formula element toStringLiteral
This commit is contained in:
parent
034f87945f
commit
6753fd99ea
4 changed files with 133 additions and 7 deletions
|
|
@ -14,9 +14,11 @@
|
|||
# MANDATORY WORKFLOW
|
||||
1. Only one TODO.md feature at a time
|
||||
2. Create a git branch for each new feature
|
||||
3. After making any change
|
||||
3. Implement then new feature, and create tests for the new feature
|
||||
4. After making any change
|
||||
- Allways pass all the tests and integration tests
|
||||
- Build the application for linux and web-server
|
||||
- Launch the apllication for web-server, with a timeout of 60s
|
||||
4. If any test or build or web-server launch fails, go to step 3
|
||||
5. Dont merge the feature branch into master, the work will be reviewed by a human.
|
||||
5. If any test or build or web-server launch fails, go to step 3
|
||||
6. Change TODO.md. Mark the task with [R], than means than the work will be reviewed by a human.
|
||||
7. Dont merge the feature branch into master, the work will be reviewed by a human.
|
||||
|
|
|
|||
10
TODO.md
10
TODO.md
|
|
@ -1,6 +1,10 @@
|
|||
# Conventions
|
||||
[ ] Means not done
|
||||
[x] Means done
|
||||
[R] Means done, but needs a human review
|
||||
[X] Means done
|
||||
|
||||
|
||||
# List of tasks
|
||||
- [X] Unify error reporting. Create class ErrorHandler that get notified of every catched exception. This class prints the exception in stdout.
|
||||
- [X] Make formula description collapsable in FormulaScreen. Initialy, the description is visible, but the user can hide it.
|
||||
- Refactor formula and unit loading:
|
||||
|
|
@ -11,8 +15,8 @@
|
|||
- [X] Change createDefaultCorpus to use loadFormulaElements instead of loadUnits and loadFormula. Make loadUnits and loadFormula private.
|
||||
- [X] Use a single table in database `FORMULAELEMENT` to store formulas and units. The table contains only two columns: autonumeric id and text.
|
||||
- Drift files have a lot of duplicate code. "web" version is the same as native version, only _openConnection is diferrent. Refactor to not duplicate code.
|
||||
- [ ] Create Formula.toStringLiteral. It is the reverse of Formula.fromSet( Formula.fromArrayStringLiteral(string)[0] )
|
||||
- [ ] Create UnitSpec.toStringLiteral, like Formula.toStringLiteral
|
||||
- [X] Create Formula.toStringLiteral. It is the reverse of Formula.fromSet( Formula.fromArrayStringLiteral(string)[0] )
|
||||
- [X] Create UnitSpec.toStringLiteral, like Formula.toStringLiteral
|
||||
- Database file location:
|
||||
- [ ] In linux, the sqlite database file will be located following rules at https://specifications.freedesktop.org/basedir/latest/
|
||||
- [ ] In Windows, the sqlite database file will be in %appdata%/Roaming
|
||||
|
|
|
|||
|
|
@ -134,6 +134,28 @@ class UnitSpec {
|
|||
return units.toList(growable: false);
|
||||
}
|
||||
|
||||
/// Creates a string literal representation of the UnitSpec that can be parsed
|
||||
/// by the D4RT parser to recreate the same UnitSpec object.
|
||||
String toStringLiteral() {
|
||||
final buffer = StringBuffer('{');
|
||||
buffer.write('"name": "$name", "symbol": "$symbol"');
|
||||
|
||||
if (name == baseUnit && factorFromUnitToBase == 1) {
|
||||
// This is a base unit
|
||||
buffer.write(', "isBase": true');
|
||||
} else {
|
||||
buffer.write(', "baseUnit": "$baseUnit"');
|
||||
|
||||
if (factorFromUnitToBase != null) {
|
||||
buffer.write(', "factor": $factorFromUnitToBase');
|
||||
} else if (codeFromUnitToBase != null && codeFromBaseToUnit != null) {
|
||||
buffer.write(', "toBase": "$codeFromUnitToBase", "fromBase": "$codeFromBaseToUnit"');
|
||||
}
|
||||
}
|
||||
|
||||
buffer.write('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class VariableSpec {
|
||||
|
|
@ -169,6 +191,30 @@ class VariableSpec {
|
|||
|
||||
@override
|
||||
int get hashCode => Object.hash(unit, name, values != null ? const DeepCollectionEquality().hash(values!) : 0);
|
||||
|
||||
/// Creates a string literal representation of the VariableSpec that can be parsed
|
||||
/// by the D4RT parser.
|
||||
String toStringLiteral() {
|
||||
final buffer = StringBuffer('{');
|
||||
buffer.write('"name": "$name"');
|
||||
|
||||
if (unit != null) {
|
||||
buffer.write(', "unit": "$unit"');
|
||||
}
|
||||
|
||||
if (values != null && values!.isNotEmpty) {
|
||||
buffer.write(', "values": [${values!.map((value) {
|
||||
if (value is String) {
|
||||
return '"$value"';
|
||||
} else {
|
||||
return value.toString();
|
||||
}
|
||||
}).join(", ")}]');
|
||||
}
|
||||
|
||||
buffer.write('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class Formula {
|
||||
|
|
@ -282,4 +328,28 @@ class Formula {
|
|||
d4rtCode: d4rtCode,
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a string literal representation of the Formula that can be parsed
|
||||
/// by the D4RT parser to recreate the same Formula object.
|
||||
String toStringLiteral() {
|
||||
final inputStrings = input.map((varSpec) => varSpec.toStringLiteral()).toList();
|
||||
|
||||
final buffer = StringBuffer('{');
|
||||
buffer.write('"name": "$name"');
|
||||
|
||||
if (description != null) {
|
||||
buffer.write(', "description": "$description"');
|
||||
}
|
||||
|
||||
buffer.write(', "input": [${inputStrings.join(", ")}]');
|
||||
buffer.write(', "output": ${output.toStringLiteral()}');
|
||||
buffer.write(', "d4rtCode": ${d4rtCode.contains('\n') || d4rtCode.contains('"') ? 'r"""$d4rtCode"""' : '"$d4rtCode"'}');
|
||||
|
||||
if (tags.isNotEmpty) {
|
||||
buffer.write(', "tags": [${tags.map((tag) => '"$tag"').join(", ")}]');
|
||||
}
|
||||
|
||||
buffer.write('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,56 @@ void main() {
|
|||
expect(result, 98.0); // F = m * a = 10 * 9.8 = 98 N
|
||||
});
|
||||
|
||||
test('Formula.toStringLiteral creates reversible string', () {
|
||||
final originalFormula = Formula(
|
||||
name: "Test Formula",
|
||||
description: "A test formula for toStringLiteral",
|
||||
input: [
|
||||
VariableSpec(name: 'x', unit: 'meter'),
|
||||
VariableSpec(name: 'y', unit: 'second', values: ['1', '2', '3']) // Using strings to match D4RT parsing behavior
|
||||
],
|
||||
output: VariableSpec(name: 'result', unit: 'meter_per_second'),
|
||||
d4rtCode: 'result = x / y;',
|
||||
tags: ['test', 'simple'],
|
||||
);
|
||||
|
||||
final literal = originalFormula.toStringLiteral();
|
||||
final parsedFormula = Formula.fromStringLiteral(literal);
|
||||
|
||||
expect(parsedFormula.name, originalFormula.name);
|
||||
expect(parsedFormula.description, originalFormula.description);
|
||||
expect(parsedFormula.input.length, originalFormula.input.length);
|
||||
expect(parsedFormula.output, originalFormula.output);
|
||||
expect(parsedFormula.d4rtCode, originalFormula.d4rtCode);
|
||||
expect(parsedFormula.tags, originalFormula.tags);
|
||||
|
||||
// Check inputs individually
|
||||
for (int i = 0; i < originalFormula.input.length; i++) {
|
||||
expect(parsedFormula.input[i].name, originalFormula.input[i].name);
|
||||
expect(parsedFormula.input[i].unit, originalFormula.input[i].unit);
|
||||
expect(parsedFormula.input[i].values, originalFormula.input[i].values);
|
||||
}
|
||||
});
|
||||
|
||||
test('UnitSpec.toStringLiteral creates reversible string', () {
|
||||
final originalUnit = UnitSpec(
|
||||
name: "test_unit",
|
||||
baseUnit: "base_unit",
|
||||
symbol: "tu",
|
||||
factorFromUnitToBase: 10.0,
|
||||
);
|
||||
|
||||
final literal = originalUnit.toStringLiteral();
|
||||
final parsedList = parseD4rtLiteral('[${literal}]');
|
||||
final parsedMap = parsedList[0] as Map<Object?, Object?>;
|
||||
final parsedUnit = UnitSpec.fromSet(parsedMap);
|
||||
|
||||
expect(parsedUnit.name, originalUnit.name);
|
||||
expect(parsedUnit.baseUnit, originalUnit.baseUnit);
|
||||
expect(parsedUnit.symbol, originalUnit.symbol);
|
||||
expect(parsedUnit.factorFromUnitToBase, originalUnit.factorFromUnitToBase);
|
||||
});
|
||||
|
||||
group('APGAR Score', () {
|
||||
test('evaluates APGAR score formula - Normal case', () async {
|
||||
final corpus = await testCorpus;
|
||||
|
|
|
|||
Loading…
Reference in a new issue