mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-07 04:39:06 +02:00
73b8ceeb35
When the chart is responsive to the parent container, the calculations for padding assumes that the figure is in pixels so that 20% is taken to be 20 (pixels), which results in the chart exceeding the parent container. This appears to be an IE11 only issue.
822 lines
21 KiB
JavaScript
822 lines
21 KiB
JavaScript
describe('Core helper tests', function() {
|
|
|
|
var helpers;
|
|
|
|
beforeAll(function() {
|
|
helpers = window.Chart.helpers;
|
|
});
|
|
|
|
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',
|
|
offset: false,
|
|
scaleLabel: Chart.defaults.scale.scaleLabel,
|
|
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',
|
|
offset: false,
|
|
scaleLabel: Chart.defaults.scale.scaleLabel,
|
|
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 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);
|
|
|
|
// Check all allowed powers of 10, which should return integer values
|
|
var maxPowerOf10 = Math.floor(helpers.log10(Number.MAX_VALUE));
|
|
for (var i = 0; i < maxPowerOf10; i += 1) {
|
|
expect(helpers.log10(Math.pow(10, i))).toBe(i);
|
|
}
|
|
});
|
|
|
|
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 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 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);
|
|
});
|
|
|
|
it ('should leave styled height and width on canvas if explicitly set', function() {
|
|
var chart = window.acquireChart({}, {
|
|
canvas: {
|
|
height: 200,
|
|
width: 200,
|
|
style: 'height: 400px; width: 400px;'
|
|
}
|
|
});
|
|
|
|
helpers.retinaScale(chart, true);
|
|
|
|
var canvas = chart.canvas;
|
|
|
|
expect(canvas.style.height).toBe('400px');
|
|
expect(canvas.style.width).toBe('400px');
|
|
});
|
|
|
|
it ('Should get padding of parent as number (pixels) when defined as percent (returns incorrectly in IE11)', function() {
|
|
|
|
// Create div with fixed size as a test bed
|
|
var div = document.createElement('div');
|
|
div.style.width = '300px';
|
|
div.style.height = '300px';
|
|
document.body.appendChild(div);
|
|
|
|
// Inner DIV to have 10% padding of parent
|
|
var innerDiv = document.createElement('div');
|
|
|
|
div.appendChild(innerDiv);
|
|
|
|
var canvas = document.createElement('canvas');
|
|
innerDiv.appendChild(canvas);
|
|
|
|
// No padding
|
|
expect(helpers.getMaximumWidth(canvas)).toBe(300);
|
|
|
|
// test with percentage
|
|
innerDiv.style.padding = '10%';
|
|
expect(helpers.getMaximumWidth(canvas)).toBe(240);
|
|
|
|
// test with pixels
|
|
innerDiv.style.padding = '10px';
|
|
expect(helpers.getMaximumWidth(canvas)).toBe(280);
|
|
|
|
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);
|
|
});
|
|
});
|
|
});
|