Test for d4rt
This commit is contained in:
parent
80d6c7d0df
commit
ba6c761cee
5 changed files with 150 additions and 60 deletions
|
|
@ -5,11 +5,11 @@
|
|||
"description": '''
|
||||
Calculates vertical displacement under constant gravity
|
||||
|
||||
`h = ½gt²`
|
||||
$$h = \\frac{1}{2}gt^2$$
|
||||
|
||||
Where:
|
||||
- `g` = Gravitational acceleration (9.81 m/s² on Earth)
|
||||
- `t` = Time in free fall (seconds)
|
||||
- $g$: Gravitational acceleration ($9.81\\ \\mathrm{m/s^2}$ on Earth)
|
||||
- $t$: Time in free fall (seconds)
|
||||
|
||||
''',
|
||||
"input": [
|
||||
|
|
@ -17,7 +17,7 @@ Where:
|
|||
{"name": "g", "unit": "meters per second"} // Gravitational acceleration
|
||||
],
|
||||
"output": {"name": "h", "unit": "meter"}, // Height in meters
|
||||
"d4rtCode": "h = 0.5 * g * Math.pow(t, 2);",
|
||||
"d4rtCode": "h = 0.5 * g * pow(t, 2);",
|
||||
"tags": ["physics", "kinematics"]
|
||||
},
|
||||
|
||||
|
|
@ -27,12 +27,12 @@ Where:
|
|||
"description": '''
|
||||
Newton's law of universal gravitation
|
||||
|
||||
`F = G(m₁m₂)/r²`
|
||||
$$F = G\\frac{m_1m_2}{r^2}$$
|
||||
|
||||
Where:
|
||||
- `G` = Gravitational constant (6.674×10⁻¹¹ N·m²/kg²)
|
||||
- `m₁`, `m₂` = Masses of two objects
|
||||
- `r` = Distance between centers of masses
|
||||
- $G$: Gravitational constant ($6.674\\times 10^{-11}\\ \\mathrm{N\\cdot m^2/kg^2}$)
|
||||
- $m_1, m_2$: Masses of two objects
|
||||
- $r$: Distance between centers of masses
|
||||
|
||||
''',
|
||||
"input": [
|
||||
|
|
@ -41,7 +41,7 @@ Where:
|
|||
{"name": "r", "unit": "meter"} // Distance between masses
|
||||
],
|
||||
"output": {"name": "F", "unit": "newton"}, // Force in newtons
|
||||
"d4rtCode": "F = (6.67430e-11 * m1 * m2) / Math.pow(r, 2);",
|
||||
"d4rtCode": "F = (6.67430e-11 * m1 * m2) / pow(r, 2);",
|
||||
"tags": ["physics", "astronomy", "gravity"]
|
||||
},
|
||||
|
||||
|
|
@ -51,11 +51,11 @@ Where:
|
|||
"description": '''
|
||||
Energy possessed by a moving object
|
||||
|
||||
`KE = ½mv²`
|
||||
$$KE = \\frac{1}{2}mv^2$$
|
||||
|
||||
Where:
|
||||
- `m` = Mass of object
|
||||
- `v` = Velocity of object
|
||||
- $m$: Mass of object
|
||||
- $v$: Velocity of object
|
||||
|
||||
''',
|
||||
"input": [
|
||||
|
|
@ -63,7 +63,7 @@ Where:
|
|||
{"name": "v", "unit": "meters per second"} // Velocity
|
||||
],
|
||||
"output": {"name": "KE", "unit": "joule"}, // Energy in joules
|
||||
"d4rtCode": "KE = 0.5 * m * Math.pow(v, 2);",
|
||||
"d4rtCode": "KE = 0.5 * m * pow(v, 2);",
|
||||
"tags": ["physics", "energy", "mechanics"]
|
||||
},
|
||||
|
||||
|
|
@ -71,18 +71,21 @@ Where:
|
|||
{
|
||||
"name": "Projectile Range",
|
||||
"description": "Calculates horizontal distance of projectile motion\n\n"
|
||||
"`R = (v² sin(2θ))/g`\n\n"
|
||||
"$$R = \\frac{v^2 \\sin(2\\theta)}{g}$$\n\n"
|
||||
"Where:\n"
|
||||
"- `v` = Initial velocity\n"
|
||||
"- `θ` = Launch angle\n"
|
||||
"- `g` = Gravitational acceleration\n\n"
|
||||
"- $v$: Initial velocity\n"
|
||||
"- $\\theta$: Launch angle\n"
|
||||
"- $g$: Gravitational acceleration\n\n"
|
||||
"",
|
||||
"input": [
|
||||
{"name": "v", "unit": "meters per second"}, // Initial velocity
|
||||
{"name": "θ", "unit": "degree"} // Launch angle
|
||||
{"name": "a", "unit": "degree"} // Launch angle
|
||||
],
|
||||
"output": {"name": "R", "unit": "meter"}, // Horizontal distance
|
||||
"d4rtCode": "R = (Math.pow(v, 2) * sin(2 * radians(θ))) / 9.80665;",
|
||||
"d4rtCode": """
|
||||
var radians = a * (pi / 180);
|
||||
R = (pow(v, 2) * sin(2 * radians)) / 9.80665;
|
||||
""",
|
||||
"tags": ["physics", "kinematics", "projectile"]
|
||||
},
|
||||
|
||||
|
|
@ -91,11 +94,11 @@ Where:
|
|||
"description": '''
|
||||
Force equals mass times acceleration
|
||||
|
||||
`F = m * a`
|
||||
$$F = m \\cdot a$$
|
||||
|
||||
Where:
|
||||
- `m` = Mass of object (kg)
|
||||
- `a` = Acceleration (m/s²)
|
||||
- $m$: Mass of object ($\\mathrm{kg}$)
|
||||
- $a$: Acceleration ($\\mathrm{m/s^2}$)
|
||||
|
||||
''',
|
||||
"input": [
|
||||
|
|
|
|||
|
|
@ -46,30 +46,22 @@ class FormulaEvaluator {
|
|||
final Number exp = getNumberValueOf( positionalArgs[1].toString() );
|
||||
return MyMath.pow(base,exp);
|
||||
},
|
||||
'log': (visitor, positionalArgs, namedArgs) {
|
||||
final Number x = getNumberValueOf( positionalArgs[0].toString() );
|
||||
return MyMath.log(x);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
interpreter.registerBridgedClass(myMathDefinition, 'package:myapp/my_math.dart');
|
||||
interpreter.registerBridgedClass(myMathDefinition, "package:d4rt_formulas.dart");
|
||||
}
|
||||
|
||||
|
||||
dynamic evaluate(Formula formula, Map<String, dynamic> inputValues) {
|
||||
_validateInputValues(formula, inputValues);
|
||||
|
||||
try {
|
||||
// Build the complete d4rt source code with variable declarations
|
||||
final completeSource = _buildCompleteSource(formula, inputValues);
|
||||
|
||||
// Execute the code using d4rt (no args needed since variables are in source)
|
||||
final result = _interpreter.execute(source: completeSource);
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
throw FormulaEvaluationException(
|
||||
'Failed to execute formula "${formula.name}"',
|
||||
e,
|
||||
);
|
||||
}
|
||||
final completeSource = _buildCompleteSource(formula, inputValues);
|
||||
final result = _interpreter.execute(source: completeSource);
|
||||
return result;
|
||||
}
|
||||
|
||||
void _validateInputValues(Formula formula, Map<String, dynamic> inputValues) {
|
||||
|
|
@ -104,8 +96,17 @@ class FormulaEvaluator {
|
|||
String _buildCompleteSource(Formula formula, Map<String, dynamic> inputValues) {
|
||||
final buffer = StringBuffer();
|
||||
|
||||
buffer.writeln("import 'package:myapp/my_math.dart';");
|
||||
buffer.writeln("main(){");
|
||||
buffer.writeln("""
|
||||
import 'dart:math';
|
||||
|
||||
//log(x) => M.log(x);
|
||||
//pow(a,b) => M.pow(a,b);
|
||||
|
||||
main()
|
||||
{
|
||||
"""
|
||||
);
|
||||
|
||||
|
||||
for (final entry in inputValues.entries) {
|
||||
final varName = entry.key;
|
||||
|
|
@ -113,16 +114,22 @@ class FormulaEvaluator {
|
|||
|
||||
if (value is String) {
|
||||
final escapedValue = value.replaceAll('"', '\\"');
|
||||
buffer.writeln('var $varName = "$escapedValue";');
|
||||
buffer.writeln("""
|
||||
final $varName = "$escapedValue";
|
||||
""");
|
||||
} else {
|
||||
buffer.writeln('var $varName = $value;');
|
||||
buffer.writeln("""
|
||||
final $varName = $value;
|
||||
""");
|
||||
}
|
||||
}
|
||||
buffer.writeln("late var ${getOutputVariableName(formula)};");
|
||||
|
||||
buffer.writeln(formula.d4rtCode);
|
||||
buffer.writeln("return ${getOutputVariableName(formula)};");
|
||||
buffer.writeln("}");
|
||||
buffer.writeln("""
|
||||
late var ${getOutputVariableName(formula)};
|
||||
${formula.d4rtCode}
|
||||
return ${getOutputVariableName(formula)};
|
||||
}
|
||||
"""
|
||||
);
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
|
|
|||
56
pubspec.lock
56
pubspec.lock
|
|
@ -299,6 +299,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -323,6 +331,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_drawing
|
||||
sha256: "3bdd251dae9ffaef944450b73f168610db7e968e7b20daf0c3907f8b4aafc8a2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1+1"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_parsing
|
||||
sha256: ee5c47c1058ad66b4a41746ec3996af9593d0858872807bcd64ac118f0700337
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.0"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -331,6 +363,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: provider
|
||||
sha256: "59471e0a4595e264625d3496af567ac85bdae1148ec985aff1e0555786f53ecf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -464,6 +504,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.12"
|
||||
tuple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: tuple
|
||||
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -528,6 +576,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: "80d494c09849dc3f899d227a78c30c5b949b985ededf884cb3f3bcd39f4b447a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
37
test/d4rt_test.dart
Normal file
37
test/d4rt_test.dart
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import 'package:test/test.dart';
|
||||
import 'package:d4rt/d4rt.dart';
|
||||
import 'dart:math' as Math;
|
||||
|
||||
|
||||
main(){
|
||||
test('Access to Math', () {
|
||||
|
||||
final completeSource = """
|
||||
import 'dart:math';
|
||||
main() => sin(42);
|
||||
|
||||
""";
|
||||
final interpreter = D4rt();
|
||||
final result = interpreter.execute(source: completeSource);
|
||||
|
||||
expect(result, Math.sin(42));
|
||||
});
|
||||
|
||||
test('Access to IO', () {
|
||||
|
||||
final completeSource = """
|
||||
import 'dart:io';
|
||||
|
||||
main() {
|
||||
File file = File('/etc/passwd');
|
||||
String contents = file.readAsStringSync();
|
||||
return contents;
|
||||
}
|
||||
""";
|
||||
final interpreter = D4rt();
|
||||
final result = interpreter.execute(source: completeSource);
|
||||
|
||||
expect(result, contains("root"));
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -141,19 +141,6 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
test('throws exception for invalid d4rt code', () {
|
||||
final formula = Formula(
|
||||
name: 'Invalid code formula',
|
||||
input: [VariableSpec(name: 'x', unit: 'scalar')],
|
||||
output: VariableSpec(name: 'result', unit: 'scalar'),
|
||||
d4rtCode: 'invalid dart code here!',
|
||||
);
|
||||
|
||||
expect(
|
||||
() => evaluator.evaluate(formula, {'x': 1}),
|
||||
throwsA(isA<FormulaEvaluationException>()),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('Utility methods', () {
|
||||
|
|
|
|||
Loading…
Reference in a new issue