| OLD | NEW |
| 1 function writeString(s, a, offset) { | 1 function writeString(s, a, offset) { |
| 2 for (var i = 0; i < s.length; ++i) { | 2 for (var i = 0; i < s.length; ++i) { |
| 3 a[offset + i] = s.charCodeAt(i); | 3 a[offset + i] = s.charCodeAt(i); |
| 4 } | 4 } |
| 5 } | 5 } |
| 6 | 6 |
| 7 function writeInt16(n, a, offset) { | 7 function writeInt16(n, a, offset) { |
| 8 n = Math.floor(n); | 8 n = Math.floor(n); |
| 9 | 9 |
| 10 var b1 = n & 255; | 10 var b1 = n & 255; |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 this._success = false; | 410 this._success = false; |
| 411 | 411 |
| 412 // If the number of errors is greater than this, the rest of error | 412 // If the number of errors is greater than this, the rest of error |
| 413 // messages are suppressed. the value is fairly arbitrary, but shouldn't | 413 // messages are suppressed. the value is fairly arbitrary, but shouldn't |
| 414 // be too small or too large. | 414 // be too small or too large. |
| 415 this.NUM_ERRORS_LOG = opts.numberOfErrorLog; | 415 this.NUM_ERRORS_LOG = opts.numberOfErrorLog; |
| 416 | 416 |
| 417 // If the number of array elements is greater than this, the rest of | 417 // If the number of array elements is greater than this, the rest of |
| 418 // elements will be omitted. | 418 // elements will be omitted. |
| 419 this.NUM_ARRAY_LOG = opts.numberOfArrayLog; | 419 this.NUM_ARRAY_LOG = opts.numberOfArrayLog; |
| 420 |
| 421 // If true, verbose output for the failure case is printed, for methods
where this makes |
| 422 // sense. |
| 423 this.verbose = opts.verbose; |
| 424 |
| 425 // If set, this is the precision with which numbers will be printed. |
| 426 this.PRINT_PRECISION = opts.precision; |
| 420 } | 427 } |
| 421 | 428 |
| 422 // Internal methods starting with a underscore. | 429 // Internal methods starting with a underscore. |
| 423 ShouldModel.prototype._testPassed = function (msg) { | 430 ShouldModel.prototype._testPassed = function (msg) { |
| 424 testPassed(this.desc + ' ' + msg + '.'); | 431 testPassed(this.desc + ' ' + msg + '.'); |
| 425 this._success = true; | 432 this._success = true; |
| 426 }; | 433 }; |
| 427 | 434 |
| 428 ShouldModel.prototype._testFailed = function (msg) { | 435 ShouldModel.prototype._testFailed = function (msg) { |
| 429 testFailed(this.desc + ' ' + msg + '.'); | 436 testFailed(this.desc + ' ' + msg + '.'); |
| 430 this._success = false; | 437 this._success = false; |
| 431 }; | 438 }; |
| 432 | 439 |
| 433 ShouldModel.prototype._isArray = function (arg) { | 440 ShouldModel.prototype._isArray = function (arg) { |
| 434 return arg instanceof Array || arg instanceof Float32Array; | 441 return arg instanceof Array || arg instanceof Float32Array; |
| 435 }; | 442 }; |
| 436 | 443 |
| 437 ShouldModel.prototype._assert = function (expression, reason) { | 444 ShouldModel.prototype._assert = function (expression, reason, value) { |
| 438 if (expression) | 445 if (expression) |
| 439 return; | 446 return; |
| 440 | 447 |
| 441 var failureMessage = 'Assertion failed: ' + reason + ' ' + this.desc +'.
'; | 448 var failureMessage = 'Assertion failed: ' + reason + ' ' + this.desc +'.
'; |
| 449 if (arguments.length >= 3) |
| 450 failureMessage += ": " + value; |
| 442 testFailed(failureMessage); | 451 testFailed(failureMessage); |
| 443 throw failureMessage; | 452 throw failureMessage; |
| 444 }; | 453 }; |
| 445 | 454 |
| 446 // Check the expected value if it is a NaN (Number) or has NaN(s) in | 455 // Check the expected value if it is a NaN (Number) or has NaN(s) in |
| 447 // its content (Array or Float32Array). Returns a string depends on the | 456 // its content (Array or Float32Array). Returns a string depends on the |
| 448 // result of check. | 457 // result of check. |
| 449 ShouldModel.prototype._checkNaN = function (value, label) { | 458 ShouldModel.prototype._checkNaN = function (value, label) { |
| 450 var failureMessage = 'NaN found in ' + label + ' while testing "' + | 459 var failureMessage = 'NaN found in ' + label + ' while testing "' + |
| 451 this.desc + '"'; | 460 this.desc + '"'; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 | 495 |
| 487 // Check if |target| is equal to |value|. | 496 // Check if |target| is equal to |value|. |
| 488 // | 497 // |
| 489 // Example: | 498 // Example: |
| 490 // Should('Zero', 0).beEqualTo(0); | 499 // Should('Zero', 0).beEqualTo(0); |
| 491 // Result: | 500 // Result: |
| 492 // "PASS Zero is equal to 0." | 501 // "PASS Zero is equal to 0." |
| 493 ShouldModel.prototype.beEqualTo = function (value) { | 502 ShouldModel.prototype.beEqualTo = function (value) { |
| 494 var type = typeof value; | 503 var type = typeof value; |
| 495 this._assert(type === 'number' || type === 'string', | 504 this._assert(type === 'number' || type === 'string', |
| 496 'value should be number or string for'); | 505 'value should be number or string for', value); |
| 497 | 506 |
| 498 this._checkNaN(value, 'EXPECTED'); | 507 this._checkNaN(value, 'EXPECTED'); |
| 499 | 508 |
| 500 if (this.target === value) | 509 if (this.target === value) |
| 501 this._testPassed('is equal to ' + value); | 510 this._testPassed('is equal to ' + value); |
| 502 else | 511 else |
| 503 this._testFailed('was ' + this.target + ' instead of ' + value); | 512 this._testFailed('was ' + this.target + ' instead of ' + value); |
| 504 return this._success; | 513 return this._success; |
| 505 }; | 514 }; |
| 506 | 515 |
| 507 // Check if |target| is not equal to |value|. | 516 // Check if |target| is not equal to |value|. |
| 508 // | 517 // |
| 509 // Example: | 518 // Example: |
| 510 // Should('One', one).notBeEqualTo(0); | 519 // Should('One', one).notBeEqualTo(0); |
| 511 // Result: | 520 // Result: |
| 512 // "PASS One is not equal to 0." | 521 // "PASS One is not equal to 0." |
| 513 ShouldModel.prototype.notBeEqualTo = function (value) { | 522 ShouldModel.prototype.notBeEqualTo = function (value) { |
| 514 var type = typeof value; | 523 var type = typeof value; |
| 515 this._assert(type === 'number' || type === 'string', | 524 this._assert(type === 'number' || type === 'string', |
| 516 'value should be number or string for'); | 525 'value should be number or string for', value); |
| 517 | 526 |
| 518 this._checkNaN(value, 'EXPECTED'); | 527 this._checkNaN(value, 'EXPECTED'); |
| 519 | 528 |
| 520 if (this.target === value) | 529 if (this.target === value) |
| 521 this._testFailed('should not be equal to ' + value); | 530 this._testFailed('should not be equal to ' + value); |
| 522 else | 531 else |
| 523 this._testPassed('is not equal to ' + value); | 532 this._testPassed('is not equal to ' + value); |
| 524 return this._success; | 533 return this._success; |
| 525 }; | 534 }; |
| 526 | 535 |
| 527 // Check if |target| is greater than or equal to |value|. | 536 // Check if |target| is greater than or equal to |value|. |
| 528 // | 537 // |
| 529 // Example: | 538 // Example: |
| 530 // Should("SNR", snr).beGreaterThanOrEqualTo(100); | 539 // Should("SNR", snr).beGreaterThanOrEqualTo(100); |
| 531 // Result: | 540 // Result: |
| 532 // "PASS SNR exceeds 100" | 541 // "PASS SNR exceeds 100" |
| 533 // "FAIL SNR (n) is not greater than or equal to 100" | 542 // "FAIL SNR (n) is not greater than or equal to 100" |
| 534 ShouldModel.prototype.beGreaterThanOrEqualTo = function (value) { | 543 ShouldModel.prototype.beGreaterThanOrEqualTo = function (value) { |
| 535 var type = typeof value; | 544 var type = typeof value; |
| 536 this._assert(type === 'number' || type === 'string', | 545 this._assert(type === 'number' || type === 'string', |
| 537 'value should be number or string for'); | 546 'value should be number or string for', value); |
| 538 | 547 |
| 539 this._checkNaN(value, 'EXPECTED'); | 548 this._checkNaN(value, 'EXPECTED'); |
| 540 | 549 |
| 541 if (this.target >= value) | 550 if (this.target >= value) |
| 542 this._testPassed("is greater than or equal to " + value); | 551 this._testPassed("is greater than or equal to " + value); |
| 543 else | 552 else |
| 544 this._testFailed("(" + this.target + ") is not greater than or equal
to " + value); | 553 this._testFailed("(" + this.target + ") is not greater than or equal
to " + value); |
| 545 return this._success; | 554 return this._success; |
| 546 } | 555 } |
| 547 | 556 |
| 548 // Check if |target| is lest than or equal to |value|. | 557 // Check if |target| is lest than or equal to |value|. |
| 549 // | 558 // |
| 550 // Example: | 559 // Example: |
| 551 // maxError = 1e-6; | 560 // maxError = 1e-6; |
| 552 // Should("max error", maxError).beLessThanOrEqualTo(1e-5); | 561 // Should("max error", maxError).beLessThanOrEqualTo(1e-5); |
| 553 // Should("max error", maxError).beLessThanOrEqualTo(-1); | 562 // Should("max error", maxError).beLessThanOrEqualTo(-1); |
| 554 // Result: | 563 // Result: |
| 555 // "PASS max error is less than or equal to 1e-5" | 564 // "PASS max error is less than or equal to 1e-5" |
| 556 // "FAIL max error (1e-6) is not less than or equal to -1" | 565 // "FAIL max error (1e-6) is not less than or equal to -1" |
| 557 ShouldModel.prototype.beLessThanOrEqualTo = function (value) { | 566 ShouldModel.prototype.beLessThanOrEqualTo = function (value) { |
| 558 var type = typeof value; | 567 var type = typeof value; |
| 559 this._assert(type === 'number', 'value should be number or string for'); | 568 this._assert(type === 'number', 'value should be number or string for',
value); |
| 560 | 569 |
| 561 this._checkNaN(value, 'EXPECTED'); | 570 this._checkNaN(value, 'EXPECTED'); |
| 562 | 571 |
| 563 if (this.target <= value) | 572 if (this.target <= value) |
| 564 this._testPassed("is less than or equal to " + value); | 573 this._testPassed("is less than or equal to " + value); |
| 565 else | 574 else |
| 566 this._testFailed("(" + this.target + ") is not less than or equal to
" + value); | 575 this._testFailed("(" + this.target + ") is not less than or equal to
" + value); |
| 567 return this._success; | 576 return this._success; |
| 568 } | 577 } |
| 569 | 578 |
| 570 // Check if |target| is close to |value| using the given relative error |thr
eshold|. |value| | 579 // Check if |target| is close to |value| using the given relative error |thr
eshold|. |value| |
| 571 // should not be zero, but no check is made for that. The |target| value is
printed to | 580 // should not be zero, but no check is made for that. The |target| value is
printed to |
| 572 // precision |precision|, with |precision| defaulting to 7. | 581 // precision |precision|, with |precision| defaulting to 7. |
| 573 // | 582 // |
| 574 // If |value| is 0, however, |threshold| is treated as an absolute threshold
. | 583 // If |value| is 0, however, |threshold| is treated as an absolute threshold
. |
| 575 // | 584 // |
| 576 // Example: | 585 // Example: |
| 577 // Should("One", 1.001).beCloseTo(1, .1); | 586 // Should("One", 1.001).beCloseTo(1, .1); |
| 578 // Should("One", 2).beCloseTo(1, .1); | 587 // Should("One", 2).beCloseTo(1, .1); |
| 579 // Result: | 588 // Result: |
| 580 // "PASS One is 1 within a relative error of 0.1." | 589 // "PASS One is 1 within a relative error of 0.1." |
| 581 // "FAIL One is not 1 within a relative error of 0.1: 2" | 590 // "FAIL One is not 1 within a relative error of 0.1: 2" |
| 582 ShouldModel.prototype.beCloseTo = function (value, errorThreshold, precision
) { | 591 ShouldModel.prototype.beCloseTo = function (value, errorThreshold, precision
) { |
| 583 var type = typeof value; | 592 var type = typeof value; |
| 584 this._assert(type === 'number', 'value should be number for'); | 593 this._assert(type === 'number', 'value should be number for', value); |
| 585 | 594 |
| 586 this._checkNaN(value, 'EXPECTED'); | 595 this._checkNaN(value, 'EXPECTED'); |
| 587 | 596 |
| 588 if (value) { | 597 if (value) { |
| 589 var relativeError = Math.abs(this.target - value) / Math.abs(value); | 598 var relativeError = Math.abs(this.target - value) / Math.abs(value); |
| 590 if (relativeError <= errorThreshold) { | 599 if (relativeError <= errorThreshold) { |
| 591 this._testPassed("is " + value.toPrecision(precision) + | 600 this._testPassed("is " + value.toPrecision(precision) + |
| 592 " within a relative error of " + errorThreshold); | 601 " within a relative error of " + errorThreshold); |
| 593 } else { | 602 } else { |
| 594 // Include actual relative error so the failed test case can be
updated with the actual | 603 // Include actual relative error so the failed test case can be
updated with the actual |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 this.target(); | 644 this.target(); |
| 636 this._testFailed('did not throw an exception'); | 645 this._testFailed('did not throw an exception'); |
| 637 } catch (error) { | 646 } catch (error) { |
| 638 if (errorType === undefined) | 647 if (errorType === undefined) |
| 639 this._testPassed('threw an exception of type ' + error.name); | 648 this._testPassed('threw an exception of type ' + error.name); |
| 640 else if (error.name === errorType) | 649 else if (error.name === errorType) |
| 641 this._testPassed('threw ' + errorType + ': ' + error.message); | 650 this._testPassed('threw ' + errorType + ': ' + error.message); |
| 642 else if (self.hasOwnProperty(errorType) && error instanceof self[err
orType]) | 651 else if (self.hasOwnProperty(errorType) && error instanceof self[err
orType]) |
| 643 this._testPassed('threw ' + errorType + ': ' + error.message); | 652 this._testPassed('threw ' + errorType + ': ' + error.message); |
| 644 else | 653 else |
| 645 this._testFailed('threw ' + error.name + ' instead of ' + except
ion); | 654 this._testFailed('threw ' + error.name + ' instead of ' + errorT
ype); |
| 646 } | 655 } |
| 647 return this._success; | 656 return this._success; |
| 648 }; | 657 }; |
| 649 | 658 |
| 650 // Check if |func| does not throw an exception. | 659 // Check if |func| does not throw an exception. |
| 651 // | 660 // |
| 652 // Example: | 661 // Example: |
| 653 // Should('var foo = "bar"', function () { var foo = 'bar'; }).notThrow(); | 662 // Should('var foo = "bar"', function () { var foo = 'bar'; }).notThrow(); |
| 654 // Result: | 663 // Result: |
| 655 // "PASS var foo = "bar" did not throw an exception." | 664 // "PASS var foo = "bar" did not throw an exception." |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 }; | 709 }; |
| 701 | 710 |
| 702 // Check if |target| array is identical to |expected| array element-wise. | 711 // Check if |target| array is identical to |expected| array element-wise. |
| 703 // | 712 // |
| 704 // Example: | 713 // Example: |
| 705 // Should('[1, 2, 3]', [1, 2, 3]).beEqualToArray([1, 2, 3]); | 714 // Should('[1, 2, 3]', [1, 2, 3]).beEqualToArray([1, 2, 3]); |
| 706 // Result: | 715 // Result: |
| 707 // "PASS [1, 2, 3] is identical to the array [1,2,3]." | 716 // "PASS [1, 2, 3] is identical to the array [1,2,3]." |
| 708 ShouldModel.prototype.beEqualToArray = function (array) { | 717 ShouldModel.prototype.beEqualToArray = function (array) { |
| 709 this._assert(this._isArray(array) && this.target.length === array.length
, | 718 this._assert(this._isArray(array) && this.target.length === array.length
, |
| 710 'Invalid array or the length does not match.'); | 719 'Invalid array or the length does not match.', array); |
| 711 | 720 |
| 712 this._checkNaN(array, 'EXPECTED'); | 721 this._checkNaN(array, 'EXPECTED'); |
| 713 | 722 |
| 714 var mismatches = {}; | 723 var mismatches = {}; |
| 715 for (var i = 0; i < this.target.length; i++) { | 724 for (var i = 0; i < this.target.length; i++) { |
| 716 if (this.target[i] !== array[i]) | 725 if (this.target[i] !== array[i]) |
| 717 mismatches[i] = this.target[i]; | 726 mismatches[i] = this.target[i]; |
| 718 } | 727 } |
| 719 | 728 |
| 720 var numberOfmismatches = Object.keys(mismatches).length; | 729 var numberOfmismatches = Object.keys(mismatches).length; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 734 break; | 743 break; |
| 735 } | 744 } |
| 736 } | 745 } |
| 737 | 746 |
| 738 this._testFailed(failureMessage); | 747 this._testFailed(failureMessage); |
| 739 } | 748 } |
| 740 return this._success; | 749 return this._success; |
| 741 }; | 750 }; |
| 742 | 751 |
| 743 // Check if |target| array is close to |expected| array element-wise within | 752 // Check if |target| array is close to |expected| array element-wise within |
| 744 // the range of |maxAllowedError|. | 753 // an certain error bound given by |absoluteThresholdOrOptions|. |
| 754 // |
| 755 // The error criterion is: |
| 756 // |
| 757 // Math.abs(target[k] - expected[k]) < Math.max(abserr, relerr * Math.abs(
expected)) |
| 758 // |
| 759 // If |absoluteThresholdOrOptions| is a number, t, then abserr = t and reler
r = 0. That is the |
| 760 // max difference is bounded by t. |
| 761 // |
| 762 // If |absoluteThresholdOrOptions| is a property bag, then abserr is the val
ue of the |
| 763 // absoluteThreshold property and relerr is the value of the relativeThresho
ld property. If |
| 764 // nothing is given, then abserr = relerr = 0. If abserr = 0, then the erro
r criterion is a |
| 765 // relative error. A non-zero abserr value produces a mix intended to handl
e the case where the |
| 766 // expected value is 0, allowing the target value to differ by abserr from t
he expected. |
| 745 // | 767 // |
| 746 // Example: | 768 // Example: |
| 747 // Should('My array', [0.11, 0.19]).beCloseToArray([0.1, 0.2], 0.02); | 769 // Should('My array', [0.11, 0.19]).beCloseToArray([0.1, 0.2], 0.02); |
| 748 // Result: | 770 // Result: |
| 749 // "PASS My array equals [0.1,0.2] within an element-wise tolerance of 0.02.
" | 771 // "PASS My array equals [0.1,0.2] within an element-wise tolerance of 0.02.
" |
| 750 ShouldModel.prototype.beCloseToArray = function (array, maxAllowedError) { | 772 ShouldModel.prototype.beCloseToArray = function (expected, absoluteThreshold
OrOptions) { |
| 751 // For the comparison, the target length must be bigger than the expecte
d. | 773 // For the comparison, the target length must be bigger than the expecte
d. |
| 752 this._assert(this.target.length >= array.length, | 774 this._assert(this.target.length >= expected.length, |
| 753 'The target array length must be longer than ' + array.length + | 775 'The target array length must be longer than ' + expected.length + |
| 754 ' but got ' + this.target.length + '.'); | 776 ' but got ' + this.target.length + '.'); |
| 755 | 777 |
| 756 this._checkNaN(array, 'EXPECTED'); | 778 this._checkNaN(expected, 'EXPECTED'); |
| 757 | 779 |
| 780 var absoluteErrorThreshold = 0; |
| 781 var relativeErrorThreshold = 0; |
| 782 |
| 783 // A collection of all of the values that satisfy the error criterion.
This holds the |
| 784 // absolute difference between the target element and the expected eleme
nt. |
| 758 var mismatches = {}; | 785 var mismatches = {}; |
| 759 var maxDiff = 0.0; | 786 |
| 760 var maxDiffIndex = 0; | 787 // Keep track of the max absolute error found |
| 761 for (var i = 0; i < array.length; i++) { | 788 var maxAbsError = -Infinity; |
| 762 var diff = Math.abs(this.target[i] - array[i]); | 789 var maxAbsErrorIndex = -1; |
| 763 if (diff > maxAllowedError) | 790 // Keep trac of the max relative error found, ignoring cases where the r
elative error is |
| 791 // Infinity because the expected value is 0. |
| 792 var maxRelError = -Infinity; |
| 793 var maxRelErrorIndex = -1; |
| 794 |
| 795 // A number or string for printing out the actual thresholds used for th
e error criterion. |
| 796 var maxAllowedError; |
| 797 |
| 798 // Set up the thresholds based on |absoluteThresholdOrOptions|. |
| 799 if (typeof(absoluteThresholdOrOptions) === 'number') { |
| 800 absoluteErrorThreshold = absoluteThresholdOrOptions; |
| 801 maxAllowedError = absoluteErrorThreshold; |
| 802 } else { |
| 803 var opts = absoluteThresholdOrOptions; |
| 804 if (opts.hasOwnProperty('absoluteThreshold')) |
| 805 absoluteErrorThreshold = opts.absoluteThreshold; |
| 806 if (opts.hasOwnProperty('relativeThreshold')) |
| 807 relativeErrorThreshold = opts.relativeThreshold; |
| 808 maxAllowedError = '{absoluteThreshold: ' + absoluteErrorThreshold |
| 809 + ', relativeThreshold: ' + relativeErrorThreshold |
| 810 + '}'; |
| 811 } |
| 812 |
| 813 for (var i = 0; i < expected.length; i++) { |
| 814 var diff = Math.abs(this.target[i] - expected[i]); |
| 815 if (diff > Math.max(absoluteErrorThreshold, relativeErrorThreshold *
Math.abs(expected[i]))) { |
| 764 mismatches[i] = diff; | 816 mismatches[i] = diff; |
| 765 if (diff > maxDiff) { | 817 // Keep track of the location of the absolute max difference. |
| 766 maxDiff = diff; | 818 if (diff > maxAbsError) { |
| 767 maxDiffIndex = i; | 819 maxAbsErrorIndex = i; |
| 820 maxAbsError = diff; |
| 821 } |
| 822 // Keep track of the location of the max relative error, ignorin
g cases where the |
| 823 // relative error is ininfinity (because the expected value = 0)
. |
| 824 var relError = diff / Math.abs(expected[i]); |
| 825 if (isFinite(relError) && relError > maxRelError) { |
| 826 maxRelErrorIndex = i; |
| 827 maxRelError = relError; |
| 828 } |
| 768 } | 829 } |
| 769 } | 830 } |
| 770 | 831 |
| 771 var numberOfmismatches = Object.keys(mismatches).length; | 832 var numberOfmismatches = Object.keys(mismatches).length; |
| 772 var arrStr = (array.length > this.NUM_ARRAY_LOG) ? | 833 var arrSlice = expected.slice(0, Math.min(expected.length, this.NUM_ARRA
Y_LOG)); |
| 773 array.slice(0, this.NUM_ARRAY_LOG).toString() + ',...' : array.toString(
); | 834 var arrStr; |
| 774 | 835 |
| 836 arrStr = arrSlice[0].toPrecision(this.PRINT_PRECISION); |
| 837 for (var k = 1; k < arrSlice.length; ++k) |
| 838 arrStr += ',' + arrSlice[k].toPrecision(this.PRINT_PRECISION); |
| 839 |
| 840 if (expected.length > this.NUM_ARRAY_LOG) |
| 841 arrStr += ',...'; |
| 775 if (numberOfmismatches === 0) { | 842 if (numberOfmismatches === 0) { |
| 776 this._testPassed('equals [' + arrStr + | 843 this._testPassed('equals [' + arrStr + |
| 777 '] with an element-wise tolerance of ' + maxAllowedError); | 844 '] with an element-wise tolerance of ' + maxAllowedError); |
| 778 } else { | 845 } else { |
| 779 var counter = 0; | 846 var counter = 0; |
| 780 var failureMessage = 'does not equal [' + arrStr + | 847 var failureMessage = 'does not equal [' + arrStr + |
| 781 '] with an element-wise tolerance of ' + maxAllowedError; | 848 '] with an element-wise tolerance of ' + maxAllowedError; |
| 782 failureMessage += '\nIndex\t Diff\t\t Actual\t\t Expected'; | 849 |
| 850 // Print a nice header for the table to follow. |
| 851 if (this.verbose) |
| 852 failureMessage += "\nIndex Actual Expected
Diff Relative"; |
| 853 else |
| 854 failureMessage += "\nDifference between expected and actual:"; |
| 855 |
| 783 for (var index in mismatches) { | 856 for (var index in mismatches) { |
| 784 failureMessage += '\n[' + index + '] :\t' + mismatches[index] + | 857 failureMessage += '\n[' + index + ']: '; |
| 785 '\t' + this.target[index] + '\t' + array[index]; | 858 if (this.verbose) { |
| 786 if (++counter >= this.NUM_ERRORS_LOG || counter === numberOfmism
atches) { | 859 // When verbose, print out actual, expected, absolute error,
and relative error. |
| 860 // TODO: print these out in nice columns to make it easier t
o read. |
| 861 var relError = Math.abs(this.target[index] - expected[index]
) / Math.abs(expected[index]); |
| 862 failureMessage += this.target[index].toExponential(16) + '
' |
| 863 + expected[index].toExponential(16) + ' ' |
| 864 + mismatches[index].toExponential(16) + ' ' |
| 865 + relError.toExponential(16) + ' ' |
| 866 + Math.max(absoluteErrorThreshold, |
| 867 relativeErrorThreshold * Math.abs(expecte
d[index])); |
| 868 } else { |
| 869 // Otherwise, just the print the absolute error. |
| 870 failureMessage += mismatches[index]; |
| 871 } |
| 872 if (++counter >= this.NUM_ERRORS_LOG) { |
| 787 failureMessage += '\nand ' + (numberOfmismatches - counter)
+ | 873 failureMessage += '\nand ' + (numberOfmismatches - counter)
+ |
| 788 ' more differences with the maximum error of ' + maxDiff
+ | 874 ' more differences, with max absolute error'; |
| 789 ' at index ' + maxDiffIndex; | 875 if (this.verbose) { |
| 876 // When verbose, print out the location of both the max
absolute error and |
| 877 // the max relative error so we can adjust thresholds ap
propriately in the |
| 878 // test. |
| 879 var relError = Math.abs(this.target[maxAbsErrorIndex] -
expected[maxAbsErrorIndex]) |
| 880 / Math.abs(expected[maxAbsErrorIndex]); |
| 881 failureMessage += ' at index ' + maxAbsErrorIndex + ':'; |
| 882 failureMessage += '\n[' + maxAbsErrorIndex + ']: '; |
| 883 failureMessage += this.target[maxAbsErrorIndex].toExpone
ntial(16) + ' ' |
| 884 + expected[maxAbsErrorIndex].toExponential(16) +
' ' |
| 885 + mismatches[maxAbsErrorIndex].toExponential(16)
+ ' ' |
| 886 + relError.toExponential(16) + ' ' |
| 887 + Math.max(absoluteErrorThreshold, |
| 888 relativeErrorThreshold * Math.abs(expected[m
axAbsErrorIndex])); |
| 889 failureMessage += '\nand max relative error'; |
| 890 failureMessage += ' at index ' + maxRelErrorIndex + ':'; |
| 891 failureMessage += '\n[' + maxRelErrorIndex + ']: '; |
| 892 failureMessage += this.target[maxRelErrorIndex].toExpone
ntial(16) + ' ' |
| 893 + expected[maxRelErrorIndex].toExponential(16) +
' ' |
| 894 + mismatches[maxRelErrorIndex].toExponential(16)
+ ' ' |
| 895 + maxRelError.toExponential(16) + ' ' |
| 896 + Math.max(absoluteErrorThreshold, |
| 897 relativeErrorThreshold * Math.abs(expected[m
axRelErrorIndex])); |
| 898 } else { |
| 899 // Not verbose, so just print out the max absolute error |
| 900 failureMessage += ' of ' + maxAbsError + ' at index ' +
maxAbsErrorIndex; |
| 901 } |
| 790 break; | 902 break; |
| 791 } | 903 } |
| 792 } | 904 } |
| 793 | 905 |
| 794 this._testFailed(failureMessage); | 906 this._testFailed(failureMessage); |
| 795 } | 907 } |
| 796 return this._success; | 908 return this._success; |
| 797 }; | 909 }; |
| 798 | 910 |
| 799 // Check if |target| array contains a set of values in a certain order. | 911 // Check if |target| array contains a set of values in a certain order. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 var _opts = { | 997 var _opts = { |
| 886 numberOfErrorLog: 8, | 998 numberOfErrorLog: 8, |
| 887 numberOfArrayLog: 16 | 999 numberOfArrayLog: 16 |
| 888 }; | 1000 }; |
| 889 | 1001 |
| 890 if (opts instanceof Object) { | 1002 if (opts instanceof Object) { |
| 891 if (opts.hasOwnProperty('numberOfErrorLog')) | 1003 if (opts.hasOwnProperty('numberOfErrorLog')) |
| 892 _opts.numberOfErrorLog = opts.numberOfErrorLog; | 1004 _opts.numberOfErrorLog = opts.numberOfErrorLog; |
| 893 if (opts.hasOwnProperty('numberOfArrayLog')) | 1005 if (opts.hasOwnProperty('numberOfArrayLog')) |
| 894 _opts.numberOfArrayLog = opts.numberOfArrayLog; | 1006 _opts.numberOfArrayLog = opts.numberOfArrayLog; |
| 1007 if (opts.hasOwnProperty('verbose')) |
| 1008 _opts.verbose = opts.verbose; |
| 1009 if (opts.hasOwnProperty('precision')) |
| 1010 _opts.precision = opts.precision; |
| 895 } | 1011 } |
| 896 | 1012 |
| 897 return new ShouldModel(desc, target, _opts); | 1013 return new ShouldModel(desc, target, _opts); |
| 898 }; | 1014 }; |
| 899 | 1015 |
| 900 })(); | 1016 })(); |
| OLD | NEW |