From ef507e11bd6936a0a60cbd66822aa6aef23df828 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Mon, 11 Feb 2019 13:31:26 -0500 Subject: [PATCH] Handle inextensible `dataset.data` array (#6060) --- src/core/core.datasetController.js | 4 +- test/specs/core.datasetController.tests.js | 80 ++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 6a7d36f196b..afd021c1db1 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -225,7 +225,9 @@ helpers.extend(DatasetController.prototype, { unlistenArrayEvents(me._data, me); } - listenArrayEvents(data, me); + if (data && Object.isExtensible(data)) { + listenArrayEvents(data, me); + } me._data = data; } diff --git a/test/specs/core.datasetController.tests.js b/test/specs/core.datasetController.tests.js index 5ab9dd5f31f..8b5d6dec2e0 100644 --- a/test/specs/core.datasetController.tests.js +++ b/test/specs/core.datasetController.tests.js @@ -38,6 +38,86 @@ describe('Chart.DatasetController', function() { }); }); + describe('inextensible data', function() { + it('should handle a frozen data object', function() { + function createChart() { + var data = Object.freeze([0, 1, 2, 3, 4, 5]); + expect(Object.isExtensible(data)).toBeFalsy(); + + var chart = acquireChart({ + type: 'line', + data: { + datasets: [{ + data: data + }] + } + }); + + var dataset = chart.data.datasets[0]; + dataset.data = Object.freeze([5, 4, 3, 2, 1, 0]); + expect(Object.isExtensible(dataset.data)).toBeFalsy(); + chart.update(); + + // Tests that the unlisten path also works for frozen objects + chart.destroy(); + } + + expect(createChart).not.toThrow(); + }); + + it('should handle a sealed data object', function() { + function createChart() { + var data = Object.seal([0, 1, 2, 3, 4, 5]); + expect(Object.isExtensible(data)).toBeFalsy(); + + var chart = acquireChart({ + type: 'line', + data: { + datasets: [{ + data: data + }] + } + }); + + var dataset = chart.data.datasets[0]; + dataset.data = Object.seal([5, 4, 3, 2, 1, 0]); + expect(Object.isExtensible(dataset.data)).toBeFalsy(); + chart.update(); + + // Tests that the unlisten path also works for frozen objects + chart.destroy(); + } + + expect(createChart).not.toThrow(); + }); + + it('should handle an unextendable data object', function() { + function createChart() { + var data = Object.preventExtensions([0, 1, 2, 3, 4, 5]); + expect(Object.isExtensible(data)).toBeFalsy(); + + var chart = acquireChart({ + type: 'line', + data: { + datasets: [{ + data: data + }] + } + }); + + var dataset = chart.data.datasets[0]; + dataset.data = Object.preventExtensions([5, 4, 3, 2, 1, 0]); + expect(Object.isExtensible(dataset.data)).toBeFalsy(); + chart.update(); + + // Tests that the unlisten path also works for frozen objects + chart.destroy(); + } + + expect(createChart).not.toThrow(); + }); + }); + it('should synchronize metadata when data are inserted or removed', function() { var data = [0, 1, 2, 3, 4, 5]; var chart = acquireChart({