};
}
+function toBeCloseToPoint() {
+ function rnd(v) {
+ return Math.round(v * 100) / 100;
+ }
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: rnd(actual.x) === rnd(expected.x) && rnd(actual.y) === rnd(expected.y)
+ };
+ }
+ };
+}
+
function toEqualOneOf() {
return {
compare: function(actual, expecteds) {
}
export default {
- toBeCloseToPixel: toBeCloseToPixel,
- toEqualOneOf: toEqualOneOf,
- toBeValidChart: toBeValidChart,
- toBeChartOfSize: toBeChartOfSize,
- toEqualImageData: toEqualImageData
+ toBeCloseToPixel,
+ toBeCloseToPoint,
+ toEqualOneOf,
+ toBeValidChart,
+ toBeChartOfSize,
+ toEqualImageData
};
expect(helpers.uid()).toBe(uid + 2);
expect(helpers.uid()).toBe(uid + 3);
});
-
- describe('Color helper', function() {
- function isColorInstance(obj) {
- return typeof obj === 'object' && obj.valid;
- }
-
- it('should return a color when called with a color', function() {
- expect(isColorInstance(helpers.color('rgb(1, 2, 3)'))).toBe(true);
- });
- });
-
- describe('Background hover color helper', function() {
- it('should return a CanvasPattern when called with a CanvasPattern', function(done) {
- var dots = new Image();
- dots.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAD1BMVEUAAAD///////////////+PQt5oAAAABXRSTlMAHlFhZsfk/BEAAAAqSURBVHgBY2BgZGJmYmSAAUYWEIDzmcBcJhiXGcxlRpPFrhdmMiqgvX0AcGIBEUAo6UAAAAAASUVORK5CYII=';
- dots.onload = function() {
- var chartContext = document.createElement('canvas').getContext('2d');
- var patternCanvas = document.createElement('canvas');
- var patternContext = patternCanvas.getContext('2d');
- var pattern = patternContext.createPattern(dots, 'repeat');
- patternContext.fillStyle = pattern;
-
- var backgroundColor = helpers.getHoverColor(chartContext.createPattern(patternCanvas, 'repeat'));
-
- expect(backgroundColor instanceof CanvasPattern).toBe(true);
-
- done();
- };
- });
-
- it('should return a CanvasGradient when called with a CanvasGradient', function() {
- var context = document.createElement('canvas').getContext('2d');
- var gradient = context.createLinearGradient(0, 1, 2, 3);
-
- expect(helpers.getHoverColor(gradient) instanceof CanvasGradient).toBe(true);
- });
-
- it('should return a modified version of color when called with a color', function() {
- var originalColorRGB = 'rgb(70, 191, 189)';
-
- expect(helpers.getHoverColor('#46BFBD')).not.toEqual(originalColorRGB);
- });
- });
});
--- /dev/null
+import {_lookup, _lookupByKey, _rlookupByKey} from '../../src/helpers/helpers.collection';
+
+describe('helpers.interpolation', function() {
+ it('Should do binary search', function() {
+ const data = [0, 2, 6, 9];
+ expect(_lookup(data, 0)).toEqual({lo: 0, hi: 1});
+ expect(_lookup(data, 1)).toEqual({lo: 0, hi: 1});
+ expect(_lookup(data, 3)).toEqual({lo: 1, hi: 2});
+ expect(_lookup(data, 6)).toEqual({lo: 1, hi: 2});
+ expect(_lookup(data, 9)).toEqual({lo: 2, hi: 3});
+ });
+
+ it('Should do binary search by key', function() {
+ const data = [{x: 0}, {x: 2}, {x: 6}, {x: 9}];
+ expect(_lookupByKey(data, 'x', 0)).toEqual({lo: 0, hi: 1});
+ expect(_lookupByKey(data, 'x', 1)).toEqual({lo: 0, hi: 1});
+ expect(_lookupByKey(data, 'x', 3)).toEqual({lo: 1, hi: 2});
+ expect(_lookupByKey(data, 'x', 6)).toEqual({lo: 1, hi: 2});
+ expect(_lookupByKey(data, 'x', 9)).toEqual({lo: 2, hi: 3});
+ });
+
+ it('Should do reverse binary search by key', function() {
+ const data = [{x: 10}, {x: 7}, {x: 3}, {x: 0}];
+ expect(_rlookupByKey(data, 'x', 0)).toEqual({lo: 2, hi: 3});
+ expect(_rlookupByKey(data, 'x', 3)).toEqual({lo: 2, hi: 3});
+ expect(_rlookupByKey(data, 'x', 5)).toEqual({lo: 1, hi: 2});
+ expect(_rlookupByKey(data, 'x', 8)).toEqual({lo: 0, hi: 1});
+ expect(_rlookupByKey(data, 'x', 10)).toEqual({lo: 0, hi: 1});
+ });
+});
--- /dev/null
+import {color, getHoverColor} from '../../src/helpers/helpers.color';
+
+describe('Color helper', function() {
+ function isColorInstance(obj) {
+ return typeof obj === 'object' && obj.valid;
+ }
+
+ it('should return a color when called with a color', function() {
+ expect(isColorInstance(color('rgb(1, 2, 3)'))).toBe(true);
+ });
+});
+
+describe('Background hover color helper', function() {
+ it('should return a CanvasPattern when called with a CanvasPattern', function(done) {
+ var dots = new Image();
+ dots.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAD1BMVEUAAAD///////////////+PQt5oAAAABXRSTlMAHlFhZsfk/BEAAAAqSURBVHgBY2BgZGJmYmSAAUYWEIDzmcBcJhiXGcxlRpPFrhdmMiqgvX0AcGIBEUAo6UAAAAAASUVORK5CYII=';
+ dots.onload = function() {
+ var chartContext = document.createElement('canvas').getContext('2d');
+ var patternCanvas = document.createElement('canvas');
+ var patternContext = patternCanvas.getContext('2d');
+ var pattern = patternContext.createPattern(dots, 'repeat');
+ patternContext.fillStyle = pattern;
+
+ var backgroundColor = getHoverColor(chartContext.createPattern(patternCanvas, 'repeat'));
+
+ expect(backgroundColor instanceof CanvasPattern).toBe(true);
+
+ done();
+ };
+ });
+
+ it('should return a CanvasGradient when called with a CanvasGradient', function() {
+ var context = document.createElement('canvas').getContext('2d');
+ var gradient = context.createLinearGradient(0, 1, 2, 3);
+
+ expect(getHoverColor(gradient) instanceof CanvasGradient).toBe(true);
+ });
+
+ it('should return a modified version of color when called with a color', function() {
+ var originalColorRGB = 'rgb(70, 191, 189)';
+
+ expect(getHoverColor('#46BFBD')).not.toEqual(originalColorRGB);
+ });
+});
--- /dev/null
+import {_pointInLine, _steppedInterpolation, _bezierInterpolation} from '../../src/helpers/helpers.interpolation';
+
+describe('helpers.interpolation', function() {
+ it('Should interpolate a point in line', function() {
+ expect(_pointInLine({x: 10, y: 10}, {x: 20, y: 20}, 0)).toEqual({x: 10, y: 10});
+ expect(_pointInLine({x: 10, y: 10}, {x: 20, y: 20}, 0.5)).toEqual({x: 15, y: 15});
+ expect(_pointInLine({x: 10, y: 10}, {x: 20, y: 20}, 1)).toEqual({x: 20, y: 20});
+ });
+
+ it('Should intepolate a point in stepped line', function() {
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0, 'before')).toEqual({x: 10, y: 10});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0.4, 'before')).toEqual({x: 14, y: 20});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0.5, 'before')).toEqual({x: 15, y: 20});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 1, 'before')).toEqual({x: 20, y: 20});
+
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0, 'middle')).toEqual({x: 10, y: 10});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0.4, 'middle')).toEqual({x: 14, y: 10});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0.5, 'middle')).toEqual({x: 15, y: 20});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 1, 'middle')).toEqual({x: 20, y: 20});
+
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0, 'after')).toEqual({x: 10, y: 10});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0.4, 'after')).toEqual({x: 14, y: 10});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 0.5, 'after')).toEqual({x: 15, y: 10});
+ expect(_steppedInterpolation({x: 10, y: 10}, {x: 20, y: 20}, 1, 'after')).toEqual({x: 20, y: 20});
+ });
+
+ it('Should interpolate a point in curve', function() {
+ const pt1 = {x: 10, y: 10, controlPointNextX: 12, controlPointNextY: 12};
+ const pt2 = {x: 20, y: 30, controlPointPreviousX: 18, controlPointPreviousY: 28};
+
+ expect(_bezierInterpolation(pt1, pt2, 0)).toEqual({x: 10, y: 10});
+ expect(_bezierInterpolation(pt1, pt2, 0.2)).toBeCloseToPoint({x: 11.616, y: 12.656});
+ expect(_bezierInterpolation(pt1, pt2, 1)).toEqual({x: 20, y: 30});
+ });
+});