<commit_before>var d3 = require('d3');

var createModeBar = require('@src/components/modebar/modebar');
var manageModeBar = require('@src/components/modebar/manage');

var Plotly = require('@lib/index');
var Plots = require('@src/plots/plots');
var Registry = require('@src/registry');
var createGraphDiv = require('../assets/create_graph_div');
var destroyGraphDiv = require('../assets/destroy_graph_div');
var selectButton = require('../assets/modebar_button');


describe('ModeBar', function() {
    'use strict';

    function noop() {}

    function getMockContainerTree() {
        var root = document.createElement('div');
        root.className = 'plot-container';
        var parent = document.createElement('div');
        parent.className = 'svg-container';
        root.appendChild(parent);

        return parent;
    }

    function getMockGraphInfo(xaxes, yaxes) {
        return {
            _fullLayout: {
                dragmode: 'zoom',
                _paperdiv: d3.select(getMockContainerTree()),
                _has: Plots._hasPlotType,
                _subplots: {xaxis: xaxes || [], yaxis: yaxes || []}
            },
            _fullData: [],
            _context: {
                displaylogo: true,
                displayModeBar: true,
                modeBarButtonsToRemove: [],
                modeBarButtonsToAdd: [],
                locale: 'en',
                locales: {}
            }
        };
    }

    function countGroups(modeBar) {
        return d3.select(modeBar.element).selectAll('div.modebar-group')[0].length;
    }

    function countButtons(modeBar) {
        return d3.select(modeBar.element).selectAll('a.modebar-btn')[0].length;
    }

    function countLogo(modeBar) {
        return d3.select(modeBar.element).selectAll('a.plotlyjsicon')[0].length;
    }

    function checkBtnAttr(modeBar, index, attr) {
        var buttons = d3.select(modeBar.element).selectAll('a.modebar-btn');
        return d3.select(buttons[0][index]).attr(attr);
    }

    var buttons = [[{
        name: 'button 1',
        click: noop
    }, {
        name: 'button 2',
        click: noop
    }]];

    var modeBar = createModeBar(getMockGraphInfo(), buttons);

    describe('createModebar', function() {
        it('creates a mode bar', function() {
            expect(countGroups(modeBar)).toEqual(2);
            expect(countButtons(modeBar)).toEqual(3);
            expect(countLogo(modeBar)).toEqual(1);
        });

        it('throws when button config does not have name', function() {
            expect(function() {
                createModeBar(getMockGraphInfo(), [[
                    { click: function() { console.log('not gonna work'); } }
                ]]);
            }).toThrowError();
        });

        it('throws when button name is not unique', function() {
            expect(function() {
                createModeBar(getMockGraphInfo(), [[
                    { name: 'A', click: function() { console.log('not gonna'); } },
                    { name: 'A', click: function() { console.log('... work'); } }
                ]]);
            }).toThrowError();
        });

        it('throws when button config does not have a click handler', function() {
            expect(function() {
                createModeBar(getMockGraphInfo(), [[
                    { name: 'not gonna work' }
                ]]);
            }).toThrowError();
        });

        it('defaults title to name when missing', function() {
            var modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'the title too', click: noop }
            ]]);

            expect(checkBtnAttr(modeBar, 0, 'data-title')).toEqual('the title too');
        });

        it('hides title to when title is falsy but not 0', function() {
            var modeBar;

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: null, click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toBe(null);

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: '', click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toBe(null);

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: false, click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toBe(null);

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: 0, click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toEqual('0');
        });
    });

    describe('modeBar.removeAllButtons', function() {
        it('removes all mode bar buttons', function() {<commit_msg>added tests for mode bar icon creation<commit_after>var d3 = require('d3');

var createModeBar = require('@src/components/modebar/modebar');
var manageModeBar = require('@src/components/modebar/manage');

var Plotly = require('@lib/index');
var Plots = require('@src/plots/plots');
var Registry = require('@src/registry');
var createGraphDiv = require('../assets/create_graph_div');
var destroyGraphDiv = require('../assets/destroy_graph_div');
var selectButton = require('../assets/modebar_button');


describe('ModeBar', function() {
    'use strict';

    function noop() {}

    function getMockContainerTree() {
        var root = document.createElement('div');
        root.className = 'plot-container';
        var parent = document.createElement('div');
        parent.className = 'svg-container';
        root.appendChild(parent);

        return parent;
    }

    function getMockGraphInfo(xaxes, yaxes) {
        return {
            _fullLayout: {
                dragmode: 'zoom',
                _paperdiv: d3.select(getMockContainerTree()),
                _has: Plots._hasPlotType,
                _subplots: {xaxis: xaxes || [], yaxis: yaxes || []}
            },
            _fullData: [],
            _context: {
                displaylogo: true,
                displayModeBar: true,
                modeBarButtonsToRemove: [],
                modeBarButtonsToAdd: [],
                locale: 'en',
                locales: {}
            }
        };
    }

    function countGroups(modeBar) {
        return d3.select(modeBar.element).selectAll('div.modebar-group')[0].length;
    }

    function countButtons(modeBar) {
        return d3.select(modeBar.element).selectAll('a.modebar-btn')[0].length;
    }

    function countLogo(modeBar) {
        return d3.select(modeBar.element).selectAll('a.plotlyjsicon')[0].length;
    }

    function checkBtnAttr(modeBar, index, attr) {
        var buttons = d3.select(modeBar.element).selectAll('a.modebar-btn');
        return d3.select(buttons[0][index]).attr(attr);
    }

    var buttons = [[{
        name: 'button 1',
        click: noop
    }, {
        name: 'button 2',
        click: noop
    }]];

    var modeBar = createModeBar(getMockGraphInfo(), buttons);

    describe('createModebar', function() {
        it('creates a mode bar', function() {
            expect(countGroups(modeBar)).toEqual(2);
            expect(countButtons(modeBar)).toEqual(3);
            expect(countLogo(modeBar)).toEqual(1);
        });

        it('throws when button config does not have name', function() {
            expect(function() {
                createModeBar(getMockGraphInfo(), [[
                    { click: function() { console.log('not gonna work'); } }
                ]]);
            }).toThrowError();
        });

        it('throws when button name is not unique', function() {
            expect(function() {
                createModeBar(getMockGraphInfo(), [[
                    { name: 'A', click: function() { console.log('not gonna'); } },
                    { name: 'A', click: function() { console.log('... work'); } }
                ]]);
            }).toThrowError();
        });

        it('throws when button config does not have a click handler', function() {
            expect(function() {
                createModeBar(getMockGraphInfo(), [[
                    { name: 'not gonna work' }
                ]]);
            }).toThrowError();
        });

        it('defaults title to name when missing', function() {
            var modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'the title too', click: noop }
            ]]);

            expect(checkBtnAttr(modeBar, 0, 'data-title')).toEqual('the title too');
        });

        it('hides title to when title is falsy but not 0', function() {
            var modeBar;

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: null, click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toBe(null);

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: '', click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toBe(null);

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: false, click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toBe(null);

            modeBar = createModeBar(getMockGraphInfo(), [[
                { name: 'button', title: 0, click: noop }
            ]]);
            expect(checkBtnAttr(modeBar, 0, 'data-title')).toEqual('0');
        });

        describe('creates a custom button', function() {
            function getIconSvg(modeBar) {
                if(!modeBar || !modeBar.buttonElements || !modeBar.buttonElements.length > 0) {
                    return undefined;
                }
                var button = modeBar.buttonElements[0];
                return d3.select(button).select('svg');
            }

            it('with a Plotly icon', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: '<NAME>',
                        click: noop,
                        icon: Plotly.Icons.home
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toBeDefined();
            });

            it('with a custom icon', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: '<NAME>',
                        click: noop,
                        icon: {
                            width: 1000,
                            height: 1000,
                            path: 'M0,-150 L1000,-150 L500,850 L0,-150 Z',
                            transform: 'matrix(1 0 0 -1 0 850)',
                        }
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                expect(svg.attr('viewBox')).toBe('0 0 1000 1000');
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toEqual('matrix(1 0 0 -1 0 850)');
            });

            it('with a custom icon with no transform', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: '<NAME>',
                        click: noop,
                        icon: {
                            width: 1000,
                            height: 1000,
                            path: 'M500,0 L1000,1000 L0,1000 L500,0 Z',
                        }
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                expect(svg.attr('viewBox')).toBe('0 0 1000 1000');
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toBeNull();
            });

            it('with a custom icon created by a function', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: '<NAME>',
                        click: noop,
                        icon: function() {
                            var xmlns = 'http://www.w3.org/2000/svg';
                            var icon = document.createElementNS(xmlns, 'svg');
                            icon.setAttribute('viewBox', '0 0 1000 1000');
                            icon.setAttribute('height', '1em');
                            icon.setAttribute('width', '1em');
                            icon.setAttribute('class', 'custom-svg');
                            var path = document.createElementNS(xmlns, 'path');
                            path.setAttribute('d', 'M500,0 L1000,1000 L0,1000 L500,0 Z');
                            icon.appendChild(path);
                            return icon;
                        }
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                expect(svg.attr('viewBox')).toBe('0 0 1000 1000');
                expect(svg.attr('class')).toBe('custom-svg');
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toBeNull();
            });

            it('with a legacy icon config', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: 'some button',
                        click: noop,
                        icon: {
                            width: 1000,
                            path: 'M0,-150 L1000,-150 L500,850 L0,-150 Z',
                            ascent: 850,
                            descent: -150
                        }
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                expect(svg.attr('viewBox')).toBe('0 0 1000 1000');
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toEqual('matrix(1 0 0 -1 0 850)');
            });

            it('with the spikeline icon', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: 'some button',
                        click: noop,
                        icon: Plotly.Icons.spikeline
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                expect(svg.attr('viewBox')).toBe('0 0 1000 1000');
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toEqual('matrix(1.5 0 0 -1.5 0 850)');
            });

            it('with the legacy spikelines button config', function() {
                var modeBar = createModeBar(getMockGraphInfo(), [[
                    {
                        name: 'toggleSpikelines',
                        attr: '_cartesianSpikesEnabled',
                        val: 'on',
                        click: noop,
                        icon: {
                            width: 1000,
                            path: 'M512 409c0-57-46-104-103-104-57 0-104 47-104 104 0 57 47 103 104 103 57 0 103-46 103-103z m-327-39l92 0 0 92-92 0z m-185 0l92 0 0 92-92 0z m370-186l92 0 0 93-92 0z m0-184l92 0 0 92-92 0z',
                            ascent: 850,
                            descent: -150
                        }
                    }
                ]]);

                var svg = getIconSvg(modeBar);
                expect(svg).toBeDefined();
                expect(svg.attr('viewBox')).toBe('0 0 1000 1000');
                var path = svg.select('path');
                expect(path.attr('d')).toBeDefined();
                expect(path.attr('transform')).toEqual('matrix(1.5 0 0 -1.5 0 850)');
            });
        });
    });

    describe('modeBar.removeAllButtons', function() {
        it('removes all mode bar buttons', function() {
{'fraction_non_alphanumeric': 0.13691886964448496, 'fraction_numerical': 0.02497721057429353, 'mean_word_length': 1.5020526075718412, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 3}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5697088', 'n_tokens_mistral': 4728, 'n_tokens_neox': 4263, 'n_words': 891}