123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- /* global sinon */
- import {
- bootstrapDiagram,
- inject
- } from 'test/TestHelper';
- import searchPadModule from 'lib/features/search-pad';
- import SearchPad from 'lib/features/search-pad/SearchPad';
- import {
- query as domQuery,
- queryAll as domQueryAll,
- classes as domClasses
- } from 'min-dom';
- var EVENTS = {
- closed: 'searchPad.closed',
- opened: 'searchPad.opened',
- preselected: 'searchPad.preselected',
- selected: 'searchPad.selected'
- };
- describe('features/searchPad', function() {
- beforeEach(bootstrapDiagram({ modules: [ searchPadModule ] }));
- var capturedEvents;
- var searchProvider;
- var elements;
- var input_node;
- beforeEach(inject(function(searchPad, eventBus, canvas) {
- canvas.setRootElement({ id: 'FOO' });
- elements = {
- one: {
- a: canvas.addShape({ id: 'one-a', x: 0, y: 0, width: 100, height: 80 })
- },
- two: {
- a: canvas.addShape({ id: 'two-a', x: 0, y: 0, width: 100, height: 80 }),
- b: canvas.addShape({ id: 'two-b', x: 0, y: 0, width: 100, height: 80 })
- }
- };
- function SearchProvider() {
- this.setup = function(pattern, results) {
- this._pattern = pattern;
- this._results = results;
- };
- this.find = function(pattern) {
- if (pattern === this._pattern) {
- return this._results;
- }
- if (pattern === 'one') {
- return [{
- primaryTokens: [
- { normal: 'one' }
- ],
- secondaryTokens: [
- { normal: 'some_' },
- { matched: 'DataStore' },
- { normal: '_123456_id' }
- ],
- element: elements.one.a
- }];
- }
- if (pattern === 'two') {
- return [{
- primaryTokens: [
- { normal: 'one' }
- ],
- secondaryTokens: [
- { normal: 'some_' },
- { matched: 'DataStore' },
- { normal: '_123456_id' }
- ],
- element: elements.two.a
- },{
- primaryTokens: [
- { normal: 'two' }
- ],
- secondaryTokens: [
- { normal: 'some_' },
- { matched: 'DataStore' },
- { normal: '_123456_id' }
- ],
- element: elements.two.b
- }];
- }
- if (pattern === 'html') {
- return [{
- primaryTokens: [
- { normal: '<html/>' }
- ],
- secondaryTokens: [
- { normal: 'some_' },
- { matched: '<html/>' },
- { normal: '_123456_id' }
- ],
- element: elements.one.a
- }];
- }
- return [];
- };
- }
- searchProvider = new SearchProvider();
- searchPad.registerProvider(searchProvider);
- capturedEvents = [];
- Object.keys(EVENTS).forEach(function(k) {
- var e = EVENTS[k];
- eventBus.on(e, function() {
- capturedEvents.push(e);
- });
- });
- input_node = domQuery(SearchPad.INPUT_SELECTOR, canvas.getContainer());
- }));
- it('should be closed by default', inject(function(canvas, eventBus, searchPad) {
- // then
- expect(searchPad.isOpen()).to.equal(false);
- }));
- it('should open', inject(function(canvas, eventBus, searchPad) {
- // when
- searchPad.open();
- // then
- expect(searchPad.isOpen()).to.equal(true);
- expect(capturedEvents).to.eql([ EVENTS.opened ]);
- }));
- it('should error on open when provider not registered', inject(function(canvas, eventBus, searchPad) {
- // given
- searchPad.registerProvider(undefined);
- // when
- expect(function() {
- searchPad.open();
- }).to.throw('no search provider registered');
- // then
- expect(searchPad.isOpen()).to.equal(false);
- expect(capturedEvents).to.eql([]);
- }));
- it('should close', inject(function(canvas, eventBus, searchPad) {
- // given
- searchPad.open();
- // when
- searchPad.close();
- // then
- expect(searchPad.isOpen()).to.equal(false);
- expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]);
- }));
- it('should toggle open/close', inject(function(canvas, eventBus, searchPad) {
- // when
- searchPad.toggle();
- searchPad.toggle();
- // then
- expect(searchPad.isOpen()).to.equal(false);
- expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]);
- // when
- searchPad.toggle();
- // then
- expect(searchPad.isOpen()).to.equal(true);
- expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed, EVENTS.opened ]);
- }));
- describe('searching/selection', function() {
- var element;
- beforeEach(inject(function(searchPad, eventBus) {
- // given
- element = searchProvider.find('one')[0].element;
- searchPad.open();
- }));
- it('should not search on empty string', inject(function(canvas, eventBus, searchPad) {
- // given
- var find = sinon.spy(searchProvider, 'find');
- // when
- typeText(input_node, '');
- // then
- expect(find).callCount(0);
- }));
- it('should display results', inject(function(canvas, eventBus, searchPad) {
- // given
- var find = sinon.spy(searchProvider, 'find');
- // when
- typeText(input_node, 'two');
- // then
- expect(find).callCount(3);
- var result_nodes = domQueryAll(SearchPad.RESULT_SELECTOR, canvas.getContainer());
- expect(result_nodes).length(2);
- }));
- it('should escape displayed results', inject(function(canvas, eventBus, searchPad) {
- // when
- typeText(input_node, 'html');
- // then
- var result_nodes = domQueryAll(SearchPad.RESULT_SELECTOR, canvas.getContainer());
- expect(result_nodes).to.have.length(1);
- expect(result_nodes[0].innerHTML).not.to.contain('<html/>');
- }));
- it('should preselect first result', inject(function(canvas, eventBus, searchPad) {
- // when
- typeText(input_node, 'two');
- // then
- var result_nodes = domQueryAll(SearchPad.RESULT_SELECTOR, canvas.getContainer());
- expect(domClasses(result_nodes[0]).has(SearchPad.RESULT_SELECTED_CLASS)).to.be.true;
- expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.preselected ]);
- }));
- it('should select result on enter', inject(function(canvas, eventBus, searchPad) {
- // given
- typeText(input_node, 'two');
- // when
- triggerKeyEvent(input_node, 'keyup', 13);
- // then
- expect(capturedEvents).to.eql([
- EVENTS.opened,
- EVENTS.preselected,
- EVENTS.closed,
- EVENTS.selected
- ]);
- }));
- it('should set overlay on an highlighted element', inject(function(searchPad, overlays) {
- // when
- typeText(input_node, 'one');
- // then
- var overlay = overlays.get({ element: element });
- expect(overlay).length(1);
- }));
- it('should remove overlay from an element on enter', inject(function(searchPad, overlays) {
- // given
- typeText(input_node, 'one');
- // when
- triggerKeyEvent(input_node, 'keyup', 13);
- // then
- var overlay = overlays.get({ element: element });
- expect(overlay).length(0);
- }));
- it('select should center viewbox on an element', inject(function(searchPad, canvas) {
- // given
- typeText(input_node, 'one');
- var container = canvas.getContainer();
- container.style.width = '1000px';
- container.style.height = '1000px';
- canvas.viewbox({
- x: 0,
- y: 0,
- width: 1000,
- height: 1000
- });
- // when
- triggerKeyEvent(input_node, 'keyup', 13);
- // then
- var newViewbox = canvas.viewbox();
- expect(newViewbox).to.have.property('x', -450);
- expect(newViewbox).to.have.property('y', -460);
- }));
- it('select should keep zoom level', inject(function(searchPad, canvas) {
- // given
- canvas.zoom(0.4);
- typeText(input_node, 'one');
- // when
- triggerKeyEvent(input_node, 'keyup', 13);
- // then
- var newViewbox = canvas.viewbox();
- expect(newViewbox).to.have.property('scale', 0.4);
- }));
- it('select should apply selection on an element', inject(function(searchPad, selection) {
- // given
- typeText(input_node, 'one');
- // when
- triggerKeyEvent(input_node, 'keyup', 13);
- // then
- expect(selection.isSelected(element)).to.be.true;
- }));
- it('should close on escape', inject(function(canvas, eventBus, searchPad) {
- // when
- triggerKeyEvent(input_node, 'keyup', 27);
- // then
- expect(searchPad.isOpen()).to.equal(false);
- expect(capturedEvents).to.eql([ EVENTS.opened, EVENTS.closed ]);
- }));
- it('should preselect next/previus results on arrow down/up', inject(function(canvas, eventBus, searchPad) {
- // given
- typeText(input_node, 'two');
- var result_nodes = domQueryAll(SearchPad.RESULT_SELECTOR, canvas.getContainer());
- // when press 'down'
- triggerKeyEvent(input_node, 'keyup', 40);
- // then
- expect(domClasses(result_nodes[0]).has(SearchPad.RESULT_SELECTED_CLASS)).to.be.false;
- expect(domClasses(result_nodes[1]).has(SearchPad.RESULT_SELECTED_CLASS)).to.be.true;
- // when press 'up'
- triggerKeyEvent(input_node, 'keyup', 38);
- // then
- expect(domClasses(result_nodes[0]).has(SearchPad.RESULT_SELECTED_CLASS)).to.be.true;
- expect(domClasses(result_nodes[1]).has(SearchPad.RESULT_SELECTED_CLASS)).to.be.false;
- expect(capturedEvents).to.eql([
- EVENTS.opened,
- EVENTS.preselected,
- EVENTS.preselected,
- EVENTS.preselected
- ]);
- }));
- it('should not move input cursor on arrow down', inject(function(canvas, eventBus, searchPad) {
- // given
- typeText(input_node, 'two');
- // when press 'down'
- var e = triggerKeyEvent(input_node, 'keydown', 40);
- expect(e.defaultPrevented).to.be.true;
- }));
- it('should not move input cursor on arrow up', inject(function(canvas, eventBus, searchPad) {
- // given
- typeText(input_node, 'two');
- // when press 'up'
- var e = triggerKeyEvent(input_node, 'keydown', 38);
- expect(e.defaultPrevented).to.be.true;
- }));
- it('should not search while navigating text in input box left', inject(function(canvas, eventBus, searchPad) {
- // given
- var find = sinon.spy(searchProvider, 'find');
- typeText(input_node, 'two');
- // when press 'left'
- triggerKeyEvent(input_node, 'keyup', 37);
- // then
- expect(find).callCount('two'.length);
- }));
- it('should not search while navigating text in input box right', inject(function(canvas, eventBus, searchPad) {
- // given
- var find = sinon.spy(searchProvider, 'find');
- typeText(input_node, 'two');
- // when press 'right'
- triggerKeyEvent(input_node, 'keyup', 39);
- // then
- expect(find).callCount('two'.length);
- }));
- });
- });
- function triggerKeyEvent(element, event, code) {
- var e = document.createEvent('Events');
- if (e.initEvent) {
- e.initEvent(event, true, true);
- }
- e.keyCode = code;
- e.which = code;
- element.dispatchEvent(e);
- return e;
- }
- function typeText(element, text) {
- var input = text.split('');
- element.value = '';
- input.forEach(function(c) {
- element.value += c;
- triggerKeyEvent(element, 'keyup', c.charCodeAt(0));
- });
- }
|