mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-06 12:19:08 +02:00
2d7c1f0d2c
Working towards creating the TimeSeries scale, this PR adds formatting for major and minor ticks on axes.
929 lines
23 KiB
JavaScript
929 lines
23 KiB
JavaScript
describe('Core helper tests', function() {
|
|
|
|
var helpers;
|
|
|
|
beforeAll(function() {
|
|
helpers = window.Chart.helpers;
|
|
});
|
|
|
|
it('should iterate over an array and pass the extra data to that function', function() {
|
|
var testData = [0, 9, 'abc'];
|
|
var scope = {}; // fake out the scope and ensure that 'this' is the correct thing
|
|
|
|
helpers.each(testData, function(item, index) {
|
|
expect(item).not.toBe(undefined);
|
|
expect(index).not.toBe(undefined);
|
|
|
|
expect(testData[index]).toBe(item);
|
|
expect(this).toBe(scope);
|
|
}, scope);
|
|
|
|
// Reverse iteration
|
|
var iterated = [];
|
|
helpers.each(testData, function(item, index) {
|
|
expect(item).not.toBe(undefined);
|
|
expect(index).not.toBe(undefined);
|
|
|
|
expect(testData[index]).toBe(item);
|
|
expect(this).toBe(scope);
|
|
|
|
iterated.push(item);
|
|
}, scope, true);
|
|
|
|
expect(iterated.slice().reverse()).toEqual(testData);
|
|
});
|
|
|
|
it('should iterate over properties in an object', function() {
|
|
var testData = {
|
|
myProp1: 'abc',
|
|
myProp2: 276,
|
|
myProp3: ['a', 'b']
|
|
};
|
|
|
|
helpers.each(testData, function(value, key) {
|
|
if (key === 'myProp1') {
|
|
expect(value).toBe('abc');
|
|
} else if (key === 'myProp2') {
|
|
expect(value).toBe(276);
|
|
} else if (key === 'myProp3') {
|
|
expect(value).toEqual(['a', 'b']);
|
|
} else {
|
|
expect(false).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should not error when iterating over a null object', function() {
|
|
expect(function() {
|
|
helpers.each(undefined);
|
|
}).not.toThrow();
|
|
});
|
|
|
|
it('should clone an object', function() {
|
|
var testData = {
|
|
myProp1: 'abc',
|
|
myProp2: ['a', 'b'],
|
|
myProp3: {
|
|
myProp4: 5,
|
|
myProp5: [1, 2]
|
|
}
|
|
};
|
|
|
|
var clone = helpers.clone(testData);
|
|
expect(clone).toEqual(testData);
|
|
expect(clone).not.toBe(testData);
|
|
|
|
expect(clone.myProp2).not.toBe(testData.myProp2);
|
|
expect(clone.myProp3).not.toBe(testData.myProp3);
|
|
expect(clone.myProp3.myProp5).not.toBe(testData.myProp3.myProp5);
|
|
});
|
|
|
|
it('should extend an object', function() {
|
|
var original = {
|
|
myProp1: 'abc',
|
|
myProp2: 56
|
|
};
|
|
|
|
var extension = {
|
|
myProp3: [2, 5, 6],
|
|
myProp2: 0
|
|
};
|
|
|
|
helpers.extend(original, extension);
|
|
|
|
expect(original).toEqual({
|
|
myProp1: 'abc',
|
|
myProp2: 0,
|
|
myProp3: [2, 5, 6],
|
|
});
|
|
});
|
|
|
|
it('should merge a normal config without scales', function() {
|
|
var baseConfig = {
|
|
valueProp: 5,
|
|
arrayProp: [1, 2, 3, 4, 5, 6],
|
|
objectProp: {
|
|
prop1: 'abc',
|
|
prop2: 56
|
|
}
|
|
};
|
|
|
|
var toMerge = {
|
|
valueProp2: null,
|
|
arrayProp: ['a', 'c'],
|
|
objectProp: {
|
|
prop1: 'c',
|
|
prop3: 'prop3'
|
|
}
|
|
};
|
|
|
|
var merged = helpers.configMerge(baseConfig, toMerge);
|
|
expect(merged).toEqual({
|
|
valueProp: 5,
|
|
valueProp2: null,
|
|
arrayProp: ['a', 'c'],
|
|
objectProp: {
|
|
prop1: 'c',
|
|
prop2: 56,
|
|
prop3: 'prop3'
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should merge scale configs', function() {
|
|
var baseConfig = {
|
|
scales: {
|
|
prop1: {
|
|
abc: 123,
|
|
def: '456'
|
|
},
|
|
prop2: 777,
|
|
yAxes: [{
|
|
type: 'linear',
|
|
}, {
|
|
type: 'log'
|
|
}]
|
|
}
|
|
};
|
|
|
|
var toMerge = {
|
|
scales: {
|
|
prop1: {
|
|
def: 'bbb',
|
|
ghi: 78
|
|
},
|
|
prop2: null,
|
|
yAxes: [{
|
|
type: 'linear',
|
|
axisProp: 456
|
|
}, {
|
|
// pulls in linear default config since axis type changes
|
|
type: 'linear',
|
|
position: 'right'
|
|
}, {
|
|
// Pulls in linear default config since axis not in base
|
|
type: 'linear'
|
|
}]
|
|
}
|
|
};
|
|
|
|
var merged = helpers.configMerge(baseConfig, toMerge);
|
|
expect(merged).toEqual({
|
|
scales: {
|
|
prop1: {
|
|
abc: 123,
|
|
def: 'bbb',
|
|
ghi: 78
|
|
},
|
|
prop2: null,
|
|
yAxes: [{
|
|
type: 'linear',
|
|
axisProp: 456
|
|
}, {
|
|
display: true,
|
|
|
|
gridLines: {
|
|
color: 'rgba(0, 0, 0, 0.1)',
|
|
drawBorder: true,
|
|
drawOnChartArea: true,
|
|
drawTicks: true, // draw ticks extending towards the label
|
|
tickMarkLength: 10,
|
|
lineWidth: 1,
|
|
offsetGridLines: false,
|
|
display: true,
|
|
zeroLineColor: 'rgba(0,0,0,0.25)',
|
|
zeroLineWidth: 1,
|
|
zeroLineBorderDash: [],
|
|
zeroLineBorderDashOffset: 0.0,
|
|
borderDash: [],
|
|
borderDashOffset: 0.0
|
|
},
|
|
position: 'right',
|
|
scaleLabel: {
|
|
labelString: '',
|
|
display: false,
|
|
},
|
|
ticks: {
|
|
beginAtZero: false,
|
|
minRotation: 0,
|
|
maxRotation: 50,
|
|
mirror: false,
|
|
padding: 0,
|
|
reverse: false,
|
|
display: true,
|
|
callback: merged.scales.yAxes[1].ticks.callback, // make it nicer, then check explicitly below
|
|
autoSkip: true,
|
|
autoSkipPadding: 0,
|
|
labelOffset: 0,
|
|
minor: {},
|
|
major: {},
|
|
},
|
|
type: 'linear'
|
|
}, {
|
|
display: true,
|
|
|
|
gridLines: {
|
|
color: 'rgba(0, 0, 0, 0.1)',
|
|
drawBorder: true,
|
|
drawOnChartArea: true,
|
|
drawTicks: true, // draw ticks extending towards the label,
|
|
tickMarkLength: 10,
|
|
lineWidth: 1,
|
|
offsetGridLines: false,
|
|
display: true,
|
|
zeroLineColor: 'rgba(0,0,0,0.25)',
|
|
zeroLineWidth: 1,
|
|
zeroLineBorderDash: [],
|
|
zeroLineBorderDashOffset: 0.0,
|
|
borderDash: [],
|
|
borderDashOffset: 0.0
|
|
},
|
|
position: 'left',
|
|
scaleLabel: {
|
|
labelString: '',
|
|
display: false,
|
|
},
|
|
ticks: {
|
|
beginAtZero: false,
|
|
minRotation: 0,
|
|
maxRotation: 50,
|
|
mirror: false,
|
|
padding: 0,
|
|
reverse: false,
|
|
display: true,
|
|
callback: merged.scales.yAxes[2].ticks.callback, // make it nicer, then check explicitly below
|
|
autoSkip: true,
|
|
autoSkipPadding: 0,
|
|
labelOffset: 0,
|
|
minor: {},
|
|
major: {},
|
|
},
|
|
type: 'linear'
|
|
}]
|
|
}
|
|
});
|
|
|
|
// Are these actually functions
|
|
expect(merged.scales.yAxes[1].ticks.callback).toEqual(jasmine.any(Function));
|
|
expect(merged.scales.yAxes[2].ticks.callback).toEqual(jasmine.any(Function));
|
|
});
|
|
|
|
it('should get value or default', function() {
|
|
expect(helpers.getValueAtIndexOrDefault(98, 0, 56)).toBe(98);
|
|
expect(helpers.getValueAtIndexOrDefault(0, 0, 56)).toBe(0);
|
|
expect(helpers.getValueAtIndexOrDefault(undefined, undefined, 56)).toBe(56);
|
|
expect(helpers.getValueAtIndexOrDefault([1, 2, 3], 1, 100)).toBe(2);
|
|
expect(helpers.getValueAtIndexOrDefault([1, 2, 3], 3, 100)).toBe(100);
|
|
});
|
|
|
|
it('should filter an array', function() {
|
|
var data = [-10, 0, 6, 0, 7];
|
|
var callback = function(item) {
|
|
return item > 2;
|
|
};
|
|
expect(helpers.where(data, callback)).toEqual([6, 7]);
|
|
expect(helpers.findNextWhere(data, callback)).toEqual(6);
|
|
expect(helpers.findNextWhere(data, callback, 2)).toBe(7);
|
|
expect(helpers.findNextWhere(data, callback, 4)).toBe(undefined);
|
|
expect(helpers.findPreviousWhere(data, callback)).toBe(7);
|
|
expect(helpers.findPreviousWhere(data, callback, 3)).toBe(6);
|
|
expect(helpers.findPreviousWhere(data, callback, 0)).toBe(undefined);
|
|
});
|
|
|
|
it('should get the correct sign', function() {
|
|
expect(helpers.sign(0)).toBe(0);
|
|
expect(helpers.sign(10)).toBe(1);
|
|
expect(helpers.sign(-5)).toBe(-1);
|
|
});
|
|
|
|
it('should do a log10 operation', function() {
|
|
expect(helpers.log10(0)).toBe(-Infinity);
|
|
expect(helpers.log10(1)).toBe(0);
|
|
expect(helpers.log10(1000)).toBeCloseTo(3, 1e-9);
|
|
});
|
|
|
|
it('should correctly determine if two numbers are essentially equal', function() {
|
|
expect(helpers.almostEquals(0, Number.EPSILON, 2 * Number.EPSILON)).toBe(true);
|
|
expect(helpers.almostEquals(1, 1.1, 0.0001)).toBe(false);
|
|
expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 0)).toBe(false);
|
|
expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 2 * Number.EPSILON)).toBe(true);
|
|
});
|
|
|
|
it('should correctly determine if a numbers are essentially whole', function() {
|
|
expect(helpers.almostWhole(0.99999, 0.0001)).toBe(true);
|
|
expect(helpers.almostWhole(0.9, 0.0001)).toBe(false);
|
|
});
|
|
|
|
it('should generate integer ids', function() {
|
|
var uid = helpers.uid();
|
|
expect(uid).toEqual(jasmine.any(Number));
|
|
expect(helpers.uid()).toBe(uid + 1);
|
|
expect(helpers.uid()).toBe(uid + 2);
|
|
expect(helpers.uid()).toBe(uid + 3);
|
|
});
|
|
|
|
it('should detect a number', function() {
|
|
expect(helpers.isNumber(123)).toBe(true);
|
|
expect(helpers.isNumber('123')).toBe(true);
|
|
expect(helpers.isNumber(null)).toBe(false);
|
|
expect(helpers.isNumber(NaN)).toBe(false);
|
|
expect(helpers.isNumber(undefined)).toBe(false);
|
|
expect(helpers.isNumber('cbc')).toBe(false);
|
|
});
|
|
|
|
it('should convert between radians and degrees', function() {
|
|
expect(helpers.toRadians(180)).toBe(Math.PI);
|
|
expect(helpers.toRadians(90)).toBe(0.5 * Math.PI);
|
|
expect(helpers.toDegrees(Math.PI)).toBe(180);
|
|
expect(helpers.toDegrees(Math.PI * 3 / 2)).toBe(270);
|
|
});
|
|
|
|
it('should get an angle from a point', function() {
|
|
var center = {
|
|
x: 0,
|
|
y: 0
|
|
};
|
|
|
|
expect(helpers.getAngleFromPoint(center, {
|
|
x: 0,
|
|
y: 10
|
|
})).toEqual({
|
|
angle: Math.PI / 2,
|
|
distance: 10,
|
|
});
|
|
|
|
expect(helpers.getAngleFromPoint(center, {
|
|
x: Math.sqrt(2),
|
|
y: Math.sqrt(2)
|
|
})).toEqual({
|
|
angle: Math.PI / 4,
|
|
distance: 2
|
|
});
|
|
|
|
expect(helpers.getAngleFromPoint(center, {
|
|
x: -1.0 * Math.sqrt(2),
|
|
y: -1.0 * Math.sqrt(2)
|
|
})).toEqual({
|
|
angle: Math.PI * 1.25,
|
|
distance: 2
|
|
});
|
|
});
|
|
|
|
it('should spline curves', function() {
|
|
expect(helpers.splineCurve({
|
|
x: 0,
|
|
y: 0
|
|
}, {
|
|
x: 1,
|
|
y: 1
|
|
}, {
|
|
x: 2,
|
|
y: 0
|
|
}, 0)).toEqual({
|
|
previous: {
|
|
x: 1,
|
|
y: 1,
|
|
},
|
|
next: {
|
|
x: 1,
|
|
y: 1,
|
|
}
|
|
});
|
|
|
|
expect(helpers.splineCurve({
|
|
x: 0,
|
|
y: 0
|
|
}, {
|
|
x: 1,
|
|
y: 1
|
|
}, {
|
|
x: 2,
|
|
y: 0
|
|
}, 1)).toEqual({
|
|
previous: {
|
|
x: 0,
|
|
y: 1,
|
|
},
|
|
next: {
|
|
x: 2,
|
|
y: 1,
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should spline curves with monotone cubic interpolation', function() {
|
|
var dataPoints = [
|
|
{_model: {x: 0, y: 0, skip: false}},
|
|
{_model: {x: 3, y: 6, skip: false}},
|
|
{_model: {x: 9, y: 6, skip: false}},
|
|
{_model: {x: 12, y: 60, skip: false}},
|
|
{_model: {x: 15, y: 60, skip: false}},
|
|
{_model: {x: 18, y: 120, skip: false}},
|
|
{_model: {x: null, y: null, skip: true}},
|
|
{_model: {x: 21, y: 180, skip: false}},
|
|
{_model: {x: 24, y: 120, skip: false}},
|
|
{_model: {x: 27, y: 125, skip: false}},
|
|
{_model: {x: 30, y: 105, skip: false}},
|
|
{_model: {x: 33, y: 110, skip: false}},
|
|
{_model: {x: 33, y: 110, skip: false}},
|
|
{_model: {x: 36, y: 170, skip: false}}
|
|
];
|
|
helpers.splineCurveMonotone(dataPoints);
|
|
expect(dataPoints).toEqual([{
|
|
_model: {
|
|
x: 0,
|
|
y: 0,
|
|
skip: false,
|
|
controlPointNextX: 1,
|
|
controlPointNextY: 2
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 3,
|
|
y: 6,
|
|
skip: false,
|
|
controlPointPreviousX: 2,
|
|
controlPointPreviousY: 6,
|
|
controlPointNextX: 5,
|
|
controlPointNextY: 6
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 9,
|
|
y: 6,
|
|
skip: false,
|
|
controlPointPreviousX: 7,
|
|
controlPointPreviousY: 6,
|
|
controlPointNextX: 10,
|
|
controlPointNextY: 6
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 12,
|
|
y: 60,
|
|
skip: false,
|
|
controlPointPreviousX: 11,
|
|
controlPointPreviousY: 60,
|
|
controlPointNextX: 13,
|
|
controlPointNextY: 60
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 15,
|
|
y: 60,
|
|
skip: false,
|
|
controlPointPreviousX: 14,
|
|
controlPointPreviousY: 60,
|
|
controlPointNextX: 16,
|
|
controlPointNextY: 60
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 18,
|
|
y: 120,
|
|
skip: false,
|
|
controlPointPreviousX: 17,
|
|
controlPointPreviousY: 100
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: null,
|
|
y: null,
|
|
skip: true
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 21,
|
|
y: 180,
|
|
skip: false,
|
|
controlPointNextX: 22,
|
|
controlPointNextY: 160
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 24,
|
|
y: 120,
|
|
skip: false,
|
|
controlPointPreviousX: 23,
|
|
controlPointPreviousY: 120,
|
|
controlPointNextX: 25,
|
|
controlPointNextY: 120
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 27,
|
|
y: 125,
|
|
skip: false,
|
|
controlPointPreviousX: 26,
|
|
controlPointPreviousY: 125,
|
|
controlPointNextX: 28,
|
|
controlPointNextY: 125
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 30,
|
|
y: 105,
|
|
skip: false,
|
|
controlPointPreviousX: 29,
|
|
controlPointPreviousY: 105,
|
|
controlPointNextX: 31,
|
|
controlPointNextY: 105
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 33,
|
|
y: 110,
|
|
skip: false,
|
|
controlPointPreviousX: 32,
|
|
controlPointPreviousY: 110,
|
|
controlPointNextX: 33,
|
|
controlPointNextY: 110
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 33,
|
|
y: 110,
|
|
skip: false,
|
|
controlPointPreviousX: 33,
|
|
controlPointPreviousY: 110,
|
|
controlPointNextX: 34,
|
|
controlPointNextY: 110
|
|
}
|
|
},
|
|
{
|
|
_model: {
|
|
x: 36,
|
|
y: 170,
|
|
skip: false,
|
|
controlPointPreviousX: 35,
|
|
controlPointPreviousY: 150
|
|
}
|
|
}]);
|
|
});
|
|
|
|
it('should get the next or previous item in an array', function() {
|
|
var testData = [0, 1, 2];
|
|
|
|
expect(helpers.nextItem(testData, 0, false)).toEqual(1);
|
|
expect(helpers.nextItem(testData, 2, false)).toEqual(2);
|
|
expect(helpers.nextItem(testData, 2, true)).toEqual(0);
|
|
expect(helpers.nextItem(testData, 1, true)).toEqual(2);
|
|
expect(helpers.nextItem(testData, -1, false)).toEqual(0);
|
|
|
|
expect(helpers.previousItem(testData, 0, false)).toEqual(0);
|
|
expect(helpers.previousItem(testData, 0, true)).toEqual(2);
|
|
expect(helpers.previousItem(testData, 2, false)).toEqual(1);
|
|
expect(helpers.previousItem(testData, 1, true)).toEqual(0);
|
|
});
|
|
|
|
it('should clear a canvas', function() {
|
|
var context = window.createMockContext();
|
|
helpers.clear({
|
|
width: 100,
|
|
height: 150,
|
|
ctx: context
|
|
});
|
|
|
|
expect(context.getCalls()).toEqual([{
|
|
name: 'clearRect',
|
|
args: [0, 0, 100, 150]
|
|
}]);
|
|
});
|
|
|
|
it('should return the width of the longest text in an Array and 2D Array', function() {
|
|
var context = window.createMockContext();
|
|
var font = "normal 12px 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif";
|
|
var arrayOfThings1D = ['FooBar', 'Bar'];
|
|
var arrayOfThings2D = [['FooBar_1', 'Bar_2'], 'Foo_1'];
|
|
|
|
|
|
// Regardless 'FooBar' is the longest label it should return (characters * 10)
|
|
expect(helpers.longestText(context, font, arrayOfThings1D, {})).toEqual(60);
|
|
expect(helpers.longestText(context, font, arrayOfThings2D, {})).toEqual(80);
|
|
// We check to make sure we made the right calls to the canvas.
|
|
expect(context.getCalls()).toEqual([{
|
|
name: 'measureText',
|
|
args: ['FooBar']
|
|
}, {
|
|
name: 'measureText',
|
|
args: ['Bar']
|
|
}, {
|
|
name: 'measureText',
|
|
args: ['FooBar_1']
|
|
}, {
|
|
name: 'measureText',
|
|
args: ['Bar_2']
|
|
}, {
|
|
name: 'measureText',
|
|
args: ['Foo_1']
|
|
}]);
|
|
});
|
|
|
|
it('compare text with current longest and update', function() {
|
|
var context = window.createMockContext();
|
|
var data = {};
|
|
var gc = [];
|
|
var longest = 70;
|
|
|
|
expect(helpers.measureText(context, data, gc, longest, 'foobar')).toEqual(70);
|
|
expect(helpers.measureText(context, data, gc, longest, 'foobar_')).toEqual(70);
|
|
expect(helpers.measureText(context, data, gc, longest, 'foobar_1')).toEqual(80);
|
|
// We check to make sure we made the right calls to the canvas.
|
|
expect(context.getCalls()).toEqual([{
|
|
name: 'measureText',
|
|
args: ['foobar']
|
|
}, {
|
|
name: 'measureText',
|
|
args: ['foobar_']
|
|
}, {
|
|
name: 'measureText',
|
|
args: ['foobar_1']
|
|
}]);
|
|
});
|
|
|
|
it('count look at all the labels and return maximum number of lines', function() {
|
|
window.createMockContext();
|
|
var arrayOfThings1 = ['Foo', 'Bar'];
|
|
var arrayOfThings2 = [['Foo', 'Bar'], 'Foo'];
|
|
var arrayOfThings3 = [['Foo', 'Bar', 'Boo'], ['Foo', 'Bar'], 'Foo'];
|
|
|
|
expect(helpers.numberOfLabelLines(arrayOfThings1)).toEqual(1);
|
|
expect(helpers.numberOfLabelLines(arrayOfThings2)).toEqual(2);
|
|
expect(helpers.numberOfLabelLines(arrayOfThings3)).toEqual(3);
|
|
});
|
|
|
|
it('should draw a rounded rectangle', function() {
|
|
var context = window.createMockContext();
|
|
helpers.drawRoundedRectangle(context, 10, 20, 30, 40, 5);
|
|
|
|
expect(context.getCalls()).toEqual([{
|
|
name: 'beginPath',
|
|
args: []
|
|
}, {
|
|
name: 'moveTo',
|
|
args: [15, 20]
|
|
}, {
|
|
name: 'lineTo',
|
|
args: [35, 20]
|
|
}, {
|
|
name: 'quadraticCurveTo',
|
|
args: [40, 20, 40, 25]
|
|
}, {
|
|
name: 'lineTo',
|
|
args: [40, 55]
|
|
}, {
|
|
name: 'quadraticCurveTo',
|
|
args: [40, 60, 35, 60]
|
|
}, {
|
|
name: 'lineTo',
|
|
args: [15, 60]
|
|
}, {
|
|
name: 'quadraticCurveTo',
|
|
args: [10, 60, 10, 55]
|
|
}, {
|
|
name: 'lineTo',
|
|
args: [10, 25]
|
|
}, {
|
|
name: 'quadraticCurveTo',
|
|
args: [10, 20, 15, 20]
|
|
}, {
|
|
name: 'closePath',
|
|
args: []
|
|
}]);
|
|
});
|
|
|
|
it ('should get the maximum width and height for a node', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create the div we want to get the max size for
|
|
var innerDiv = document.createElement('div');
|
|
div.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumWidth(innerDiv)).toBe(200);
|
|
expect(helpers.getMaximumHeight(innerDiv)).toBe(300);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum width of a node that has a max-width style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create the div we want to get the max size for and set a max-width style
|
|
var innerDiv = document.createElement('div');
|
|
innerDiv.style.maxWidth = '150px';
|
|
div.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumWidth(innerDiv)).toBe(150);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum height of a node that has a max-height style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create the div we want to get the max size for and set a max-height style
|
|
var innerDiv = document.createElement('div');
|
|
innerDiv.style.maxHeight = '150px';
|
|
div.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum width of a node when the parent has a max-width style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create an inner wrapper around our div we want to size and give that a max-width style
|
|
var parentDiv = document.createElement('div');
|
|
parentDiv.style.maxWidth = '150px';
|
|
div.appendChild(parentDiv);
|
|
|
|
// Create the div we want to get the max size for
|
|
var innerDiv = document.createElement('div');
|
|
parentDiv.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumWidth(innerDiv)).toBe(150);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum height of a node when the parent has a max-height style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create an inner wrapper around our div we want to size and give that a max-height style
|
|
var parentDiv = document.createElement('div');
|
|
parentDiv.style.maxHeight = '150px';
|
|
div.appendChild(parentDiv);
|
|
|
|
// Create the div we want to get the max size for
|
|
var innerDiv = document.createElement('div');
|
|
innerDiv.style.height = '300px'; // make it large
|
|
parentDiv.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum width of a node that has a percentage max-width style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create the div we want to get the max size for and set a max-width style
|
|
var innerDiv = document.createElement('div');
|
|
innerDiv.style.maxWidth = '50%';
|
|
div.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumWidth(innerDiv)).toBe(100);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum height of a node that has a percentage max-height style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create the div we want to get the max size for and set a max-height style
|
|
var innerDiv = document.createElement('div');
|
|
innerDiv.style.maxHeight = '50%';
|
|
div.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum width of a node when the parent has a percentage max-width style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create an inner wrapper around our div we want to size and give that a max-width style
|
|
var parentDiv = document.createElement('div');
|
|
parentDiv.style.maxWidth = '50%';
|
|
div.appendChild(parentDiv);
|
|
|
|
// Create the div we want to get the max size for
|
|
var innerDiv = document.createElement('div');
|
|
parentDiv.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumWidth(innerDiv)).toBe(100);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
it ('should get the maximum height of a node when the parent has a percentage max-height style', function() {
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.height = '300px';
|
|
|
|
document.body.appendChild(div);
|
|
|
|
// Create an inner wrapper around our div we want to size and give that a max-height style
|
|
var parentDiv = document.createElement('div');
|
|
parentDiv.style.maxHeight = '50%';
|
|
div.appendChild(parentDiv);
|
|
|
|
var innerDiv = document.createElement('div');
|
|
innerDiv.style.height = '300px'; // make it large
|
|
parentDiv.appendChild(innerDiv);
|
|
|
|
expect(helpers.getMaximumHeight(innerDiv)).toBe(150);
|
|
|
|
document.body.removeChild(div);
|
|
});
|
|
|
|
describe('Color helper', function() {
|
|
function isColorInstance(obj) {
|
|
return typeof obj === 'object' && obj.hasOwnProperty('values') && obj.values.hasOwnProperty('rgb');
|
|
}
|
|
|
|
it('should return a color when called with a color', function() {
|
|
expect(isColorInstance(helpers.color('rgb(1, 2, 3)'))).toBe(true);
|
|
});
|
|
|
|
it('should return a color when called with a CanvasGradient instance', function() {
|
|
var context = document.createElement('canvas').getContext('2d');
|
|
var gradient = context.createLinearGradient(0, 1, 2, 3);
|
|
|
|
expect(isColorInstance(helpers.color(gradient))).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 modified version of color when called with a color', function() {
|
|
var originalColorRGB = 'rgb(70, 191, 189)';
|
|
|
|
expect(helpers.getHoverColor('#46BFBD')).not.toEqual(originalColorRGB);
|
|
});
|
|
});
|
|
});
|