diff --git a/src/Services/InfoProviderSystem/DTOs/ParameterDTO.php b/src/Services/InfoProviderSystem/DTOs/ParameterDTO.php index 4c82f1db..6500164b 100644 --- a/src/Services/InfoProviderSystem/DTOs/ParameterDTO.php +++ b/src/Services/InfoProviderSystem/DTOs/ParameterDTO.php @@ -38,27 +38,59 @@ class ParameterDTO } + /** + * This function tries to decide on the value, if it is a numerical value (which is then stored in one of the value_*) fields) or a text value (which is stored in value_text). + * It is possible to give ranges like 1...2 here, which will be parsed as value_min: 1.0, value_max: 2.0. + * @param string $name + * @param string|float $value + * @param string|null $unit + * @param string|null $symbol + * @param string|null $group + * @return self + */ public static function parseValueField(string $name, string|float $value, ?string $unit = null, ?string $symbol = null, ?string $group = null): self { if (is_float($value) || is_numeric($value)) { return new self($name, value_typ: (float) $value, unit: $unit, symbol: $symbol, group: $group); } + //Try to parse as range + if (str_contains($value, '...')) { + $parts = explode('...', $value); + if (count($parts) === 2) { + + //Ensure that both parts are numerical + if (is_numeric($parts[0]) && is_numeric($parts[1])) { + return new self($name, value_min: (float) $parts[0], value_max: (float) $parts[1], unit: $unit, symbol: $symbol, group: $group); + } + } + } + return new self($name, value_text: $value, unit: $unit, symbol: $symbol, group: $group); } + /** + * This function tries to decide on the value, if it is a numerical value (which is then stored in one of the value_*) fields) or a text value (which is stored in value_text). + * It also tries to extract the unit from the value field (so 3kg will be parsed as value_typ: 3.0, unit: kg). + * Ranges like 1...2 will be parsed as value_min: 1.0, value_max: 2.0. + * @param string $name + * @param string|float $value + * @param string|null $symbol + * @param string|null $group + * @return self + */ public static function parseValueIncludingUnit(string $name, string|float $value, ?string $symbol = null, ?string $group = null): self { - if (is_float($value) || is_numeric($value)) { - return new self($name, value_typ: (float) $value, symbol: $symbol, group: $group); - } - + //Try to extract unit from value $unit = null; - if (preg_match('/^(?[0-9.]+)\s*(?[a-zA-Z]+)$/', $value, $matches)) { + if (is_string($value) && preg_match('/^(?[0-9.]+)\s*(?[°a-zA-Z_]+\s?\w{0,4})$/u', $value, $matches)) { $value = $matches['value']; $unit = $matches['unit']; + + return self::parseValueField(name: $name, value: $value, unit: $unit, symbol: $symbol, group: $group); } - return new self($name, value_text: $value, unit: $unit, symbol: $symbol, group: $group); + //Otherwise we assume that no unit is given + return self::parseValueField(name: $name, value: $value, unit: null, symbol: $symbol, group: $group); } } \ No newline at end of file diff --git a/tests/Services/InfoProviderSystem/DTOs/ParameterDTOTest.php b/tests/Services/InfoProviderSystem/DTOs/ParameterDTOTest.php new file mode 100644 index 00000000..26a4483a --- /dev/null +++ b/tests/Services/InfoProviderSystem/DTOs/ParameterDTOTest.php @@ -0,0 +1,164 @@ +. + */ + +namespace App\Tests\Services\InfoProviderSystem\DTOs; + +use App\Services\InfoProviderSystem\DTOs\ParameterDTO; +use PHPUnit\Framework\TestCase; + +class ParameterDTOTest extends TestCase +{ + + public function parseValueFieldDataProvider(): \Generator + { + //Text value + yield [ + new ParameterDTO('test', value_text: 'test', unit: 'm', symbol: 'm', group: 'test'), + 'test', + 'test', + 'm', + 'm', + 'test' + ]; + + //Numerical value + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: 'm', symbol: 'm', group: 'test'), + 'test', + 1.0, + 'm', + 'm', + 'test' + ]; + + //Numerical value with unit should be parsed as text value + yield [ + new ParameterDTO('test', value_text: '1.0 m', unit: 'm', symbol: 'm', group: 'test'), + 'test', + '1.0 m', + 'm', + 'm', + 'test' + ]; + + //Test ranges + yield [ + new ParameterDTO('test', value_min: 1.0, value_max: 2.0, unit: 'kg', symbol: 'm', group: 'test'), + 'test', + '1.0...2.0', + 'kg', + 'm', + 'test' + ]; + } + + public function parseValueIncludingUnitDataProvider(): \Generator + { + //Text value + yield [ + new ParameterDTO('test', value_text: 'test', unit: null, symbol: 'm', group: 'test'), + 'test', + 'test', + 'm', + 'test' + ]; + + //Numerical value + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: null, symbol: 'm', group: 'test'), + 'test', + 1.0, + 'm', + 'test' + ]; + + //Numerical value with unit should extract unit correctly + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: 'kg', symbol: 'm', group: 'test'), + 'test', + '1.0 kg', + 'm', + 'test' + ]; + + //Should work without space between value and unit + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: 'kg', symbol: 'm', group: 'test'), + 'test', + '1.0kg', + 'm', + 'test' + ]; + + //Allow ° as unit symbol + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: '°C', symbol: 'm', group: 'test'), + 'test', + '1.0°C', + 'm', + 'test' + ]; + + //Allow _ in units + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: 'C_m', symbol: 'm', group: 'test'), + 'test', + '1.0C_m', + 'm', + 'test' + ]; + + //Allow a single space in units + yield [ + new ParameterDTO('test', value_typ: 1.0, unit: 'C m', symbol: 'm', group: 'test'), + 'test', + '1.0C m', + 'm', + 'test' + ]; + + //Test ranges + yield [ + new ParameterDTO('test', value_min: 1.0, value_max: 2.0, unit: 'kg', symbol: 'm', group: 'test'), + 'test', + '1.0...2.0 kg', + 'm', + 'test' + ]; + } + + /** + * @dataProvider parseValueFieldDataProvider + * @return void + */ + public function testParseValueField(ParameterDTO $expected, string $name, string|float $value, ?string $unit = null, ?string $symbol = null, ?string $group = null) + { + $this->assertEquals($expected, ParameterDTO::parseValueField($name, $value, $unit, $symbol, $group)); + } + + /** + * @dataProvider parseValueIncludingUnitDataProvider + * @return void + */ + public function testParseValueIncludingUnit(ParameterDTO $expected, string $name, string|float $value, ?string $symbol = null, ?string $group = null) + { + $this->assertEquals($expected, ParameterDTO::parseValueIncludingUnit($name, $value, $symbol, $group)); + } +}