Skip to content

Commit

Permalink
lift test coverage, remove dead code
Browse files Browse the repository at this point in the history
  • Loading branch information
sjhorn committed Mar 30, 2024
1 parent 6caa567 commit 72c61d7
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 34 deletions.
37 changes: 11 additions & 26 deletions lib/src/formula/grammar/validate_expression.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ class ValidateExpression extends Expression {

@override
Parser<A1Cursor> expression() {
return super.expression().map((value) {
//print('Expression -> $value');
return value;
});
return super.expression().map((value) => value);
}

@override
Expand Down Expand Up @@ -91,42 +88,30 @@ class ValidateExpression extends Expression {
(ref0(expression) & (char(',') & ref0(expression)).star() & char(','))
.end()
.map((value) => A1Cursor.end()),
super.list().map((value) {
final (_, rest) = value;
final last = (rest as Iterable).flattened.last.$2;

return switch (last) {
A1Cursor() => last,
null => A1Cursor.none(),
_ => A1Cursor.end(),
};
}),
super.list().map((value) => (value.$2 as Iterable).flattened.last.$2),
].toChoiceParser();

@override
Parser<A1Cursor> additive() => seq2(
super.additive().map((value) {
final last = (value.elements as Iterable).flattened.last;
return last ?? A1Cursor.none();
}),
super
.additive()
.map((value) => (value.elements as Iterable).flattened.last),
anyOf('+-').end().optional(),
).map2((value, String? op) => op == null ? value : A1Cursor.end());

@override
Parser<A1Cursor> multiplicative() => seq2(
super.multiplicative().map((value) {
final last = (value.elements as Iterable).flattened.last;
return last ?? A1Cursor.none();
}),
super
.multiplicative()
.map((value) => (value.elements as Iterable).flattened.last),
anyOf('*/').end().optional(),
).map2((value, String? op) => op == null ? value : A1Cursor.end());

@override
Parser<A1Cursor> power() => seq2(
super.power().map((value) {
final last = (value.elements as Iterable).flattened.last;
return last ?? A1Cursor.none();
}),
super
.power()
.map((value) => (value.elements as Iterable).flattened.last),
anyOf('^').end().optional(),
).map2((value, String? op) => op == null ? value : A1Cursor.end());

Expand Down
16 changes: 16 additions & 0 deletions lib/src/formula/results/list_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,20 @@ class ListResult extends ResultType {

@override
String toString() => 'List: ${list.map((e) => e.toString())}';
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

if (other is ListResult) {
for (final (index, item) in other.list.indexed) {
if (list[index] != item) return false;
}
return true;
}
return false;
}

@override
int get hashCode => list.fold(
0, (previousValue, element) => previousValue ^ element.hashCode);
}
3 changes: 2 additions & 1 deletion lib/src/formula/results/number_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class NumberResult extends ResultType implements Comparable {

@override
String toString() => switch (value.abs()) {
num(isNaN: var nan) when nan == true => 'ERROR',
num(isNaN: var nan, isInfinite: var infinite) when nan || infinite =>
'ERROR',
0 => '0',
(>= minExponent && < maxExponent) => numFormat.format(value),
_ => value.toStringAsExponential().length > 11
Expand Down
18 changes: 17 additions & 1 deletion lib/src/formula/types/list_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ListType extends FormulaType {
}

@override
String toString() => 'ListResult($list)';
String toString() => 'ListType($list)';

@override
String get asFormula => list.map((e) => e.asFormula).join(",");
Expand All @@ -39,4 +39,20 @@ class ListType extends FormulaType {
e.visit(callback);
}
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other is ListType) {
for (final (index, item) in other.list.indexed) {
if (list[index] != item) return false;
}
return true;
}
return false;
}

@override
int get hashCode => list.fold(
0, (previousValue, element) => previousValue ^ element.hashCode);
}
4 changes: 0 additions & 4 deletions lib/src/formula/types/lookup_function.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:a1/a1.dart';
import '../results/error_result.dart';
import '../types/error_type.dart';
import '../result_cache_map.dart';
import '../types/list_range_type.dart';
import '../types/reference_type.dart';
Expand All @@ -25,9 +24,6 @@ class LookupFunction extends FormulaType {
if (lookupNumber is ErrorResult) return ErrorResult();
final range = paramList[1];
if (lookupNumber is NumberResult && range is ListRangeType) {
if (range.list.whereType<ErrorType>().isNotEmpty) {
return ErrorResult();
}
if (range.isColumnLine || range.isRowLine) {
A1? lastCell;
for (A1 cell in range.from.rangeTo(range.to)) {
Expand Down
12 changes: 11 additions & 1 deletion lib/src/formula/types/num_type.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '../result_cache_map.dart';
import '../results/number_result.dart';
import 'formula_type.dart';
import '../results/result_type.dart';
import 'formula_type.dart';

class NumType extends FormulaType {
NumType(this.value);
Expand All @@ -23,4 +23,14 @@ class NumType extends FormulaType {
void visit(FormulaTypeVisitor callback) {
callback(this);
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is NumType && other.value == value;
}

@override
int get hashCode => value.hashCode;
}
5 changes: 5 additions & 0 deletions lib/visicalc_engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ library;
export 'src/formula/grammar/validate_expression.dart';
export 'src/formula/result_cache_map.dart';
export 'src/formula/results/error_result.dart';
export 'src/formula/results/list_result.dart';
export 'src/formula/results/not_available_result.dart';
export 'src/formula/results/empty_result.dart';
export 'src/formula/types/average_function.dart';
export 'src/formula/types/brackets_type.dart';
export 'src/formula/types/error_type.dart';
Expand All @@ -19,6 +22,7 @@ export 'src/formula/types/maths_function.dart';
export 'src/formula/types/max_function.dart';
export 'src/formula/types/min_function.dart';
export 'src/formula/types/npv_function.dart';
export 'src/formula/types/not_available_type.dart';
export 'src/formula/grammar/evaluator.dart';
export 'src/formula/results/number_result.dart';
export 'src/formula/results/result_type.dart';
Expand All @@ -30,4 +34,5 @@ export 'src/formula/types/pi_type.dart';
export 'src/formula/types/positive_op.dart';
export 'src/formula/types/reference_type.dart';
export 'src/formula/types/sum_function.dart';
export 'src/formula/types/list_type.dart';
export 'src/formula/grammar/file_format.dart';
3 changes: 3 additions & 0 deletions test/evaluator_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:test/test.dart';
import 'package:petitparser/petitparser.dart';
import 'package:a1/a1.dart';
import 'package:visicalc_engine/src/formula/types/count_function.dart';
import 'package:visicalc_engine/visicalc_engine.dart';

void main() {
Expand Down Expand Up @@ -136,6 +137,8 @@ void main() {
group('wrappers', () {
test('functions', () async {
final p = evaluator.buildFrom(evaluator.left()).end();
expectEval(p, '@count()', isA<CountFunction>(), isA<NumberResult>(), 0);
expectEval(p, '@su(12)', isA<ErrorType>(), isA<ErrorResult>(), null);
expectEval(p, '@sum(12)', isA<SumFunction>(), isA<NumberResult>(), 12);
expectEval(p, '@sum(12+2)', isA<SumFunction>(), isA<NumberResult>(), 14);
expectEval(
Expand Down
21 changes: 20 additions & 1 deletion test/file_format_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ void main() {
final parser = fileFormat.buildFrom(fileFormat.cellExpression());
expect(parser.parse('>A9:/FR"TRUE').value,
equals(('A9'.a1, 'R', LabelFormat('TRUE'))));

expect(parser.parse('>G9:/-=').value,
equals(('G9'.a1, null, RepeatingFormat('='))));
expect(parser.parse('>G8:+F8*10').value,
equals(('G8'.a1, null, ExpressionFormat('+F8*10'))));
expect(parser.parse('>F8:+F7+1').value,
Expand All @@ -45,11 +46,29 @@ void main() {

test('global directive', () async {
final parser = fileFormat.buildFrom(fileFormat.start());

expect(parser.parse('/W1').value, equals(GlobalDirectiveFormat('W1')));
expect(parser.parse('/GOC').value, equals(GlobalDirectiveFormat('GOC')));
expect(parser.parse('/GRA').value, equals(GlobalDirectiveFormat('GRA')));
expect(parser.parse('/X>A1:>C14:').value,
equals(GlobalDirectiveFormat('X>A1:>C14:')));
});

test('hashCodes', () async {
expect(LabelFormat('test').hashCode, LabelFormat('test').hashCode);
expect(
ExpressionFormat('+A1').hashCode,
ExpressionFormat('+A1').hashCode,
);
expect(
GlobalDirectiveFormat('/GC10').hashCode,
GlobalDirectiveFormat('/GC10').hashCode,
);
expect(
RepeatingFormat('/-=').hashCode,
RepeatingFormat('/-=').hashCode,
);
expect(RepeatingFormat('=').toString(), equals('='));
});
});
}
46 changes: 46 additions & 0 deletions test/results_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:test/test.dart';
import 'package:visicalc_engine/visicalc_engine.dart';

void main() {
test('result types', () async {
expect(EmptyResult().toString(), equals(''));
expect(ErrorResult().toString(), equals('ERROR'));
expect(ListResult([ErrorResult(), ErrorResult()]).toString(),
equals('List: (ERROR, ERROR)'));
expect(NotAvailableResult('test').toString(), equals('NA - test'));
expect(NotAvailableResult().toString(), equals('NA'));
});

test('number result type', () async {
var result = NumberResult(12);
expect(result.toString(), equals('12'));

expect(result.compareTo('test'), equals(-1));
expect(result.compareTo(NumberResult(13)), equals(-1));
expect(result.compareTo(NumberResult(12)), equals(0));
expect(result.compareTo(NumberResult(11)), equals(1));
expect(result < NumberResult(11), isFalse);
expect(result > NumberResult(11), isTrue);
expect(result == NumberResult(12), isTrue);
expect(result.hashCode, equals(NumberResult(12).hashCode));
});

test('number result type formatting', () async {
expect(NumberResult(double.nan).toString(), equals('ERROR'));
expect(NumberResult(double.infinity).toString(), equals('ERROR'));
expect(NumberResult(double.negativeInfinity).toString(), equals('ERROR'));
expect(NumberResult(0).toString(), equals('0'));
expect(NumberResult(-0).toString(), equals('0'));
expect(NumberResult(1.01234e-7).toString(), equals('1.01234e-7'));
expect(NumberResult(1.01234e-5).toString(), equals('0.0000101234'));
expect(NumberResult(1.01234e22).toString(), equals('1.01234e+22'));
expect(NumberResult(123456789012e22).toString(), equals('1.23457e+33'));
expect(NumberResult(123456789e22).toString(), equals('1.23457e+30'));
});
test('list result type', () async {
expect(
ListResult([NumberResult(1)]).hashCode,
equals(ListResult([NumberResult(1)]).hashCode),
);
});
}
Loading

0 comments on commit 72c61d7

Please sign in to comment.