import {expect} from "chai" import * as sinon from 'sinon' import {ColumnDataSource} from "@bokehjs/models/sources/column_data_source" import {GlyphRenderer} from "@bokehjs/models/renderers/glyph_renderer" import {LegendItem} from "@bokehjs/models/annotations/legend_item" import {logger} from "@bokehjs/core/logging" describe("LegendItem", () => { describe("initialize", () => { let logger_stub: sinon.SinonStub beforeEach(() => { logger_stub = sinon.stub(logger, "error") }) afterEach(() => { logger_stub.restore() }) it("should log an error if _check_data_sources_on_renderers is false", () => { const stub = sinon.stub(LegendItem.prototype, '_check_data_sources_on_renderers').returns(false) new LegendItem() sinon.assert.calledOnce(logger_stub) stub.restore() }) it("should log an error if _check_field_label_on_data_source is false", () => { const stub = sinon.stub(LegendItem.prototype, '_check_field_label_on_data_source').returns(false) new LegendItem() sinon.assert.calledOnce(logger_stub) stub.restore() }) }) describe("_check_data_sources_on_renderers", () => { it("should return false if field label and different data sources", () => { const gr_1 = new GlyphRenderer({ data_source: new ColumnDataSource() }) const gr_2 = new GlyphRenderer({ data_source: new ColumnDataSource() }) const legend_item = new LegendItem({ label: { field: 'label' }, renderers: [ gr_1, gr_2 ], }) expect(legend_item._check_data_sources_on_renderers()).to.be.false }) it("should return false if field label and no renderers", () => { const legend_item = new LegendItem({ label: { field: 'label' }, renderers: [ ], }) expect(legend_item._check_data_sources_on_renderers()).to.be.false }) it("should return true if value label and different data sources", () => { const gr_1 = new GlyphRenderer({ data_source: new ColumnDataSource() }) const gr_2 = new GlyphRenderer({ data_source: new ColumnDataSource() }) const legend_item = new LegendItem({ label: { value: 'label' }, renderers: [ gr_1, gr_2 ], }) expect(legend_item._check_data_sources_on_renderers()).to.be.true }) }) describe("_check_field_label_on_data_source", () => { it("should return false if field label and label not in data source", () => { const gr_1 = new GlyphRenderer({ data_source: new ColumnDataSource({data: {foo: [1]}}), }) const legend_item = new LegendItem({ label: { field: 'label' }, renderers: [ gr_1 ], }) expect(legend_item._check_field_label_on_data_source()).to.be.false }) it("should return false if field label and no renderers", () => { const legend_item = new LegendItem({ label: { field: 'label' }, renderers: [ ], }) expect(legend_item._check_field_label_on_data_source()).to.be.false }) it("should return true if field label and label in data source", () => { const gr_1 = new GlyphRenderer({ data_source: new ColumnDataSource({data: {label: [1]}}), }) const legend_item = new LegendItem({ label: { field: 'label' }, renderers: [ gr_1 ], }) expect(legend_item._check_field_label_on_data_source()).to.be.true }) }) describe("get_field_from_label_prop", () => { it("should return undefined if label property is null", () => { const legend_item = new LegendItem({label: null}) const field = legend_item.get_field_from_label_prop() expect(field).to.be.null }) it("should return undefined if label property is value", () => { const legend_item = new LegendItem({label: {value: 'milk'}}) const field = legend_item.get_field_from_label_prop() expect(field).to.be.null }) it("should return field if label property is field", () => { const legend_item = new LegendItem({label: {field: 'milk'}}) const field = legend_item.get_field_from_label_prop() expect(field).to.be.equal('milk') }) }) describe("get_labels_list_from_label_prop", () => { it("should return labels if field is valid", () => { const source = new ColumnDataSource({ data: { label: ['foo', 'bar', 'foo', 'bar'], }, }) const gr = new GlyphRenderer({data_source: source}) const legend_item = new LegendItem({label: {field: 'label'}, renderers: [gr]}) const field = legend_item.get_labels_list_from_label_prop() expect(field).to.be.deep.equal(['foo', 'bar']) }) it("should return 'Invalid field' list if field is not in datasource", () => { const source = new ColumnDataSource({ data: { x: [10, 20, 30, 40], }, }) const gr = new GlyphRenderer({data_source: source}) const legend_item = new LegendItem({label: {field: 'milk'}, renderers: [gr]}) const field = legend_item.get_labels_list_from_label_prop() expect(field).to.be.deep.equal(['Invalid field']) }) it("should return 'No source found' list if no renderer and field used", () => { const legend_item = new LegendItem({label: {field: 'milk'}, renderers: []}) const field = legend_item.get_labels_list_from_label_prop() expect(field).to.be.deep.equal(['No source found']) }) it("should return 'No source found' list if no source on renderer", () => { const gr = new GlyphRenderer() const legend_item = new LegendItem({label: {field: 'milk'}, renderers: [gr]}) const field = legend_item.get_labels_list_from_label_prop() expect(field).to.be.deep.equal(['No source found']) }) it("should return value in single list if label is value", () => { const legend_item = new LegendItem({label: {value: 'milk'}}) const field = legend_item.get_labels_list_from_label_prop() expect(field).to.be.deep.equal(['milk']) }) it("should return empty list if label is null", () => { const legend_item = new LegendItem({label: null}) const field = legend_item.get_labels_list_from_label_prop() expect(field).to.be.deep.equal([]) }) }) })