Skip to content
This repository was archived by the owner on Oct 14, 2020. It is now read-only.

Commit 48e9f2a

Browse files
DonaldKellettjhoffner
authored andcommitted
Fix Test.assert(Not)ApproxEquals (#435)
* Add relevant tests for fixing codewars/codewars.com#962 * Treat 1e-9 as absolute error margin when (un)expected value small enough
1 parent 241a65b commit 48e9f2a

File tree

2 files changed

+166
-4
lines changed

2 files changed

+166
-4
lines changed

frameworks/javascript/cw-2.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ try {
360360
// Compares two floating point values and checks whether they are approximately equal to each other
361361
options = options || {};
362362
msg = Test.display.message('Expected actual value ' + actual + ' to approximately equal expected value ' + expected + ' (accepted relative error: 1e-9)', msg);
363-
if (expected === 0) {
364-
Test.expect(Math.abs(actual) <= 1e-9, msg, options);
363+
if (Math.abs(expected) <= 1) {
364+
Test.expect(Math.abs(expected - actual) <= 1e-9, msg, options);
365365
}
366366
else {
367367
Test.expect(Math.abs((expected - actual) / expected) <= 1e-9, msg, options);
@@ -371,8 +371,8 @@ try {
371371
// Compares two floating point values and checks whether they are sufficiently different from each other
372372
options = options || {};
373373
msg = Test.display.message('Actual value ' + actual + ' should not approximately equal unexpected value ' + unexpected + ' (rejected relative error: 1e-9)', msg);
374-
if (unexpected === 0) {
375-
Test.expect(Math.abs(actual) > 1e-9, msg, options);
374+
if (Math.abs(unexpected) <= 1) {
375+
Test.expect(Math.abs(unexpected - actual) > 1e-9, msg, options);
376376
}
377377
else {
378378
Test.expect(Math.abs((unexpected - actual) / unexpected) > 1e-9, msg, options);

test/runners/javascript_spec.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,168 @@ describe("test", function(){
849849
});
850850
});
851851

852+
describe('Fix Codewars/codewars.com#962', function() {
853+
describe('Test.assertApproxEquals', function() {
854+
it('should allow for an absolute error range of 1e-9 when the actual value returned is 0', function(done) {
855+
runner.run({language: 'javascript', code: 'var a = 0', fixture: `Test.assertApproxEquals(a, 1e-15);
856+
Test.assertApproxEquals(a, 1e-14);
857+
Test.assertApproxEquals(a, 1e-13);
858+
Test.assertApproxEquals(a, 1e-12);
859+
Test.assertApproxEquals(a, 1e-11);
860+
Test.assertApproxEquals(a, 1e-10);
861+
Test.assertApproxEquals(a, 1e-9);
862+
Test.assertApproxEquals(a, -1e-9);
863+
Test.assertApproxEquals(a, -1e-10);
864+
Test.assertApproxEquals(a, -1e-11);
865+
Test.assertApproxEquals(a, -1e-12);
866+
Test.assertApproxEquals(a, -1e-13);
867+
Test.assertApproxEquals(a, -1e-14);
868+
Test.assertApproxEquals(a, -1e-15);`, testFramework: 'cw-2'}, function(buffer) {
869+
expect(buffer.stdout).to.contain('<PASSED::>');
870+
expect(buffer.stdout).to.not.contain('<FAILED::>');
871+
expect(buffer.stdout).to.not.contain('<ERROR::>');
872+
done();
873+
});
874+
});
875+
it('should allow for an absolute error range of *no more than* 1e-9 when the actual value returned is 0', function(done) {
876+
runner.run({language: 'javascript', code: 'var a = 0', fixture: `Test.assertApproxEquals(a, 1e-8);
877+
Test.assertApproxEquals(a, 1e-7);
878+
Test.assertApproxEquals(a, 1e-6);
879+
Test.assertApproxEquals(a, 1e-5);
880+
Test.assertApproxEquals(a, 1e-4);
881+
Test.assertApproxEquals(a, 1e-3);
882+
Test.assertApproxEquals(a, 1e-2);
883+
Test.assertApproxEquals(a, 1e-1);
884+
Test.assertApproxEquals(a, 1);
885+
Test.assertApproxEquals(a, -1);
886+
Test.assertApproxEquals(a, -1e-1);
887+
Test.assertApproxEquals(a, -1e-2);
888+
Test.assertApproxEquals(a, -1e-3);
889+
Test.assertApproxEquals(a, -1e-4);
890+
Test.assertApproxEquals(a, -1e-5);
891+
Test.assertApproxEquals(a, -1e-6);
892+
Test.assertApproxEquals(a, -1e-7);
893+
Test.assertApproxEquals(a, -1e-8);`, testFramework: 'cw-2'}, function(buffer) {
894+
expect(buffer.stdout).to.not.contain('<PASSED::>');
895+
expect(buffer.stdout).to.contain('<FAILED::>');
896+
expect(buffer.stdout).to.not.contain('<ERROR::>');
897+
done();
898+
});
899+
});
900+
it('should treat 1e-9 as an absolute error margin and not a relative one when Math.abs(expected) <= 1 (passing tests only)', function(done) {
901+
runner.run({language: 'javascript', code: 'var a = [1e-8 - 1e-10, 1e-8 - 1e-11, 1e-8 - 1e-12, 1e-8 - 1e-13, 1e-8 - 1e-14, 1e-8 - 1e-15, 1e-8 + 1e-15, 1e-8 + 1e-14, 1e-8 + 1e-13, 1e-8 + 1e-12, 1e-8 + 1e-11, 1e-8 + 1e-10], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertApproxEquals(a[i], 1e-8); Test.assertApproxEquals(b[i], -1e-8); }', testFramework: 'cw-2'}, function(buffer) {
902+
expect(buffer.stdout).to.contain('<PASSED::>');
903+
expect(buffer.stdout).to.not.contain('<FAILED::>');
904+
expect(buffer.stdout).to.not.contain('<ERROR::>');
905+
done();
906+
});
907+
});
908+
it('should treat 1e-9 as an absolute error margin and not a relative one when Math.abs(expected) <= 1 (failing tests only)', function(done) {
909+
runner.run({language: 'javascript', code: 'var a = [1e-8 - 1e-8, 1e-8 - 1e-7, 1e-8 - 1e-6, 1e-8 - 1e-5, 1e-8 - 1e-4, 1e-8 - 1e-3, 1e-8 - 1e-2, 1e-8 - 1e-1, 1e-8 + 1e-1, 1e-8 + 1e-2, 1e-8 + 1e-3, 1e-8 + 1e-4, 1e-8 + 1e-5, 1e-8 + 1e-6, 1e-8 + 1e-7, 1e-8 + 1e-8], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertApproxEquals(a[i], 1e-8); Test.assertApproxEquals(b[i], -1e-8); }', testFramework: 'cw-2'}, function(buffer) {
910+
expect(buffer.stdout).to.not.contain('<PASSED::>');
911+
expect(buffer.stdout).to.contain('<FAILED::>');
912+
expect(buffer.stdout).to.not.contain('<ERROR::>');
913+
done();
914+
});
915+
});
916+
it('should treat 1e-9 as a relative error margin and not an absolute one when Math.abs(expected) > 1 (passing tests only)', function(done) {
917+
runner.run({language: 'javascript', code: 'var a = [1000000 - 1e-8, 1000000 - 1e-7, 1000000 - 1e-6, 1000000 - 1e-5, 1000000 - 1e-4, 1000000 + 1e-4, 1000000 + 1e-5, 1000000 + 1e-6, 1000000 + 1e-7, 1000000 + 1e-8], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertApproxEquals(a[i], 1000000); Test.assertApproxEquals(b[i], -1000000); }', testFramework: 'cw-2'}, function(buffer) {
918+
expect(buffer.stdout).to.contain('<PASSED::>');
919+
expect(buffer.stdout).to.not.contain('<FAILED::>');
920+
expect(buffer.stdout).to.not.contain('<ERROR::>');
921+
done();
922+
});
923+
});
924+
it('should treat 1e-9 as a relative error margin and not an absolute one when Math.abs(expected) > 1 (failing tests only)', function(done) {
925+
runner.run({language: 'javascript', code: 'var a = [1000000 - 1e-2, 1000000 - 1e-1, 1000000 - 1, 1000000 - 10, 1000000 - 100, 1000000 + 100, 1000000 + 10, 1000000 + 1, 1000000 + 1e-1, 1000000 + 1e-2], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertApproxEquals(a[i], 1000000); Test.assertApproxEquals(b[i], -1000000); }', testFramework: 'cw-2'}, function(buffer) {
926+
expect(buffer.stdout).to.not.contain('<PASSED::>');
927+
expect(buffer.stdout).to.contain('<FAILED::>');
928+
expect(buffer.stdout).to.not.contain('<ERROR::>');
929+
done();
930+
});
931+
});
932+
});
933+
describe('Test.assertNotApproxEquals', function() {
934+
it('should reject an absolute difference of 1e-9 or less if the actual value is 0', function(done) {
935+
runner.run({language: 'javascript', code: 'var a = 0', fixture: `Test.assertNotApproxEquals(a, 1e-15);
936+
Test.assertNotApproxEquals(a, 1e-14);
937+
Test.assertNotApproxEquals(a, 1e-13);
938+
Test.assertNotApproxEquals(a, 1e-12);
939+
Test.assertNotApproxEquals(a, 1e-11);
940+
Test.assertNotApproxEquals(a, 1e-10);
941+
Test.assertNotApproxEquals(a, 1e-9);
942+
Test.assertNotApproxEquals(a, -1e-9);
943+
Test.assertNotApproxEquals(a, -1e-10);
944+
Test.assertNotApproxEquals(a, -1e-11);
945+
Test.assertNotApproxEquals(a, -1e-12);
946+
Test.assertNotApproxEquals(a, -1e-13);
947+
Test.assertNotApproxEquals(a, -1e-14);
948+
Test.assertNotApproxEquals(a, -1e-15);`, testFramework: 'cw-2'}, function(buffer) {
949+
expect(buffer.stdout).to.not.contain('<PASSED::>');
950+
expect(buffer.stdout).to.contain('<FAILED::>');
951+
expect(buffer.stdout).to.not.contain('<ERROR::>');
952+
done();
953+
});
954+
});
955+
it('should accept an absolute difference greater than 1e-9 if the actual value is 0', function(done) {
956+
runner.run({language: 'javascript', code: 'var a = 0', fixture: `Test.assertNotApproxEquals(a, 1e-8);
957+
Test.assertNotApproxEquals(a, 1e-7);
958+
Test.assertNotApproxEquals(a, 1e-6);
959+
Test.assertNotApproxEquals(a, 1e-5);
960+
Test.assertNotApproxEquals(a, 1e-4);
961+
Test.assertNotApproxEquals(a, 1e-3);
962+
Test.assertNotApproxEquals(a, 1e-2);
963+
Test.assertNotApproxEquals(a, 1e-1);
964+
Test.assertNotApproxEquals(a, 1);
965+
Test.assertNotApproxEquals(a, -1);
966+
Test.assertNotApproxEquals(a, -1e-1);
967+
Test.assertNotApproxEquals(a, -1e-2);
968+
Test.assertNotApproxEquals(a, -1e-3);
969+
Test.assertNotApproxEquals(a, -1e-4);
970+
Test.assertNotApproxEquals(a, -1e-5);
971+
Test.assertNotApproxEquals(a, -1e-6);
972+
Test.assertNotApproxEquals(a, -1e-7);
973+
Test.assertNotApproxEquals(a, -1e-8);`, testFramework: 'cw-2'}, function(buffer) {
974+
expect(buffer.stdout).to.contain('<PASSED::>');
975+
expect(buffer.stdout).to.not.contain('<FAILED::>');
976+
expect(buffer.stdout).to.not.contain('<ERROR::>');
977+
done();
978+
});
979+
});
980+
it('should treat 1e-9 as an absolute error margin and not a relative one when Math.abs(unexpected) <= 1 (failing tests only)', function(done) {
981+
runner.run({language: 'javascript', code: 'var a = [1e-8 - 1e-10, 1e-8 - 1e-11, 1e-8 - 1e-12, 1e-8 - 1e-13, 1e-8 - 1e-14, 1e-8 - 1e-15, 1e-8 + 1e-15, 1e-8 + 1e-14, 1e-8 + 1e-13, 1e-8 + 1e-12, 1e-8 + 1e-11, 1e-8 + 1e-10], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertNotApproxEquals(a[i], 1e-8); Test.assertNotApproxEquals(b[i], -1e-8); }', testFramework: 'cw-2'}, function(buffer) {
982+
expect(buffer.stdout).to.not.contain('<PASSED::>');
983+
expect(buffer.stdout).to.contain('<FAILED::>');
984+
expect(buffer.stdout).to.not.contain('<ERROR::>');
985+
done();
986+
});
987+
});
988+
it('should treat 1e-9 as an absolute error margin and not a relative one when Math.abs(unexpected) <= 1 (passing tests only)', function(done) {
989+
runner.run({language: 'javascript', code: 'var a = [1e-8 - 1e-8, 1e-8 - 1e-7, 1e-8 - 1e-6, 1e-8 - 1e-5, 1e-8 - 1e-4, 1e-8 - 1e-3, 1e-8 - 1e-2, 1e-8 - 1e-1, 1e-8 + 1e-1, 1e-8 + 1e-2, 1e-8 + 1e-3, 1e-8 + 1e-4, 1e-8 + 1e-5, 1e-8 + 1e-6, 1e-8 + 1e-7, 1e-8 + 1e-8], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertNotApproxEquals(a[i], 1e-8); Test.assertNotApproxEquals(b[i], -1e-8); }', testFramework: 'cw-2'}, function(buffer) {
990+
expect(buffer.stdout).to.contain('<PASSED::>');
991+
expect(buffer.stdout).to.not.contain('<FAILED::>');
992+
expect(buffer.stdout).to.not.contain('<ERROR::>');
993+
done();
994+
});
995+
});
996+
it('should treat 1e-9 as a relative error margin and not an absolute one when Math.abs(unexpected) > 1 (failing tests only)', function(done) {
997+
runner.run({language: 'javascript', code: 'var a = [1000000 - 1e-8, 1000000 - 1e-7, 1000000 - 1e-6, 1000000 - 1e-5, 1000000 - 1e-4, 1000000 + 1e-4, 1000000 + 1e-5, 1000000 + 1e-6, 1000000 + 1e-7, 1000000 + 1e-8], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertNotApproxEquals(a[i], 1000000); Test.assertNotApproxEquals(b[i], -1000000); }', testFramework: 'cw-2'}, function(buffer) {
998+
expect(buffer.stdout).to.not.contain('<PASSED::>');
999+
expect(buffer.stdout).to.contain('<FAILED::>');
1000+
expect(buffer.stdout).to.not.contain('<ERROR::>');
1001+
done();
1002+
});
1003+
});
1004+
it('should treat 1e-9 as a relative error margin and not an absolute one when Math.abs(unexpected) > 1 (passing tests only)', function(done) {
1005+
runner.run({language: 'javascript', code: 'var a = [1000000 - 1e-2, 1000000 - 1e-1, 1000000 - 1, 1000000 - 10, 1000000 - 100, 1000000 + 100, 1000000 + 10, 1000000 + 1, 1000000 + 1e-1, 1000000 + 1e-2], b = a.map(n => -n)', fixture: 'for (let i = 0; i < a.length; i++) { Test.assertNotApproxEquals(a[i], 1000000); Test.assertNotApproxEquals(b[i], -1000000); }', testFramework: 'cw-2'}, function(buffer) {
1006+
expect(buffer.stdout).to.contain('<PASSED::>');
1007+
expect(buffer.stdout).to.not.contain('<FAILED::>');
1008+
expect(buffer.stdout).to.not.contain('<ERROR::>');
1009+
done();
1010+
});
1011+
});
1012+
});
1013+
});
8521014

8531015
//----------------------------------------------------------------------------------------
8541016
// Karma BDD

0 commit comments

Comments
 (0)