import mocha from 'mocha'; import chai from 'chai'; import { getNode, setRoot } from './node'; import { addFinder } from '@iconify/iconify/lib/modules/finder'; import { FakeData, setFakeData, prepareQuery, sendQuery } from './fake-api'; import { API } from '@iconify/core/lib/api/'; import { setAPIModule } from '@iconify/core/lib/api/modules'; import { setAPIConfig } from '@iconify/core/lib/api/config'; import { coreModules } from '@iconify/core/lib/modules'; import { finder as iconifyFinder } from '@iconify/iconify/lib/finders/iconify'; import { finder as iconifyIconFinder } from '@iconify/iconify/lib/finders/iconify-icon'; import { listRootNodes } from '@iconify/iconify/lib/modules/root'; import { scanDOM, scanElement } from '@iconify/iconify/lib/modules/scanner'; const expect = chai.expect; // Add finders addFinder(iconifyFinder); addFinder(iconifyIconFinder); // Set API setAPIModule('', { prepare: prepareQuery, send: sendQuery, }); coreModules.api = API; let prefixCounter = 0; function nextPrefix(): string { return 'scan-dom-api-' + prefixCounter++; } describe('Scanning DOM with API', () => { it('Scan DOM with API', (done) => { const provider = nextPrefix(); const prefix1 = nextPrefix(); const prefix2 = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Set icons, load them with various delay const data1: FakeData = { icons: ['home', 'account-cash'], delay: 100, data: { prefix: prefix1, icons: { 'account-cash': { body: '', }, 'home': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1); const data2: FakeData = { icons: ['account', 'account-box'], delay: 500, data: { prefix: prefix2, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix2, data2); const node = getNode('scan-dom'); node.innerHTML = '

Testing scanning DOM with API (should render SVG!)

    ' + '
  • Inline icons:' + ' ' + ' ' + '
  • ' + '
  • Block icons:' + ' ' + ' ' + '
  • ' + '
'; // Scan DOM setRoot(node); scanDOM(); // Test listRootNodes const nodes = listRootNodes(); expect(nodes.length).to.be.equal(1); expect(nodes[0].node).to.be.equal(node); expect(nodes[0].temporary).to.be.equal(false); // First API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 2, 'Expected to find 2 rendered SVG elements' ); }, 200); // Second API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 4, 'Expected to find 4 rendered SVG elements' ); done(); }, 700); }); it('Changing icon name before it loaded', (done) => { const provider = nextPrefix(); const prefix1 = nextPrefix(); const prefix2 = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Set icons, load them with various delay const data1: FakeData = { icons: ['home', 'account-cash'], delay: 100, data: { prefix: prefix1, icons: { 'account-cash': { body: '', }, 'home': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1); const data2: FakeData = { icons: ['account', 'account-box'], delay: 500, data: { prefix: prefix2, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix2, data2); const data1b: FakeData = { icons: ['account', 'account-box'], delay: 800, // +100ms for first query data: { prefix: prefix1, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1b); const node = getNode('scan-dom'); node.innerHTML = '

Testing scanning DOM with API: renamed icon (should render SVG!)

    ' + '
  • Default finder:' + ' ' + ' ' + '
  • ' + '
  • IconifyIcon finder:' + ' ' + ' ' + '
  • ' + '
'; // Scan DOM setRoot(node); scanDOM(); // Test listRootNodes const nodes = listRootNodes(); expect(nodes.length).to.be.equal(1); expect(nodes[0].node).to.be.equal(node); expect(nodes[0].temporary).to.be.equal(false); // Make sure no icons were rendered yet const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 0, 'Expected to find 0 rendered SVG elements' ); // Change icon name const icon = node.querySelector('iconify-icon[title]'); expect(icon).to.not.be.equal(null); expect(icon.getAttribute('class')).to.be.equal('third-icon'); icon.setAttribute( 'data-icon', '@' + provider + ':' + prefix1 + ':account' ); // First API response should have loaded, but only 1 icon should have been rendered setTimeout(() => { // Loaded for prefix1: account-cash, home // Loaded for prefix2: - const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(1, '200ms delay error'); }, 200); // Second API response should have loaded setTimeout(() => { // Loaded for prefix1: account-cash, home // Loaded for prefix2: account, account-box const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(3, '700ms delay error'); }, 700); // Renamed icon from first API response setTimeout(() => { // Loaded for prefix1: account-cash, home, account-box, account // Loaded for prefix2: account, account-box const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(4, '1000ms delay error'); done(); }, 1100); }); it('Changing icon name before it loaded to invalid name', (done) => { const provider = nextPrefix(); const prefix1 = nextPrefix(); const prefix2 = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Set icons, load them with various delay const data1: FakeData = { icons: ['home', 'account-cash'], delay: 100, data: { prefix: prefix1, icons: { 'account-cash': { body: '', }, 'home': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix1, data1); const data2: FakeData = { icons: ['account', 'account-box'], delay: 500, data: { prefix: prefix2, icons: { 'account-box': { body: '', }, 'account': { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix2, data2); const node = getNode('scan-dom'); node.innerHTML = '

Testing scanning DOM with API: invalid name (should render 3 SVGs!)

    ' + '
  • Inline icons (2 valid):' + ' ' + ' ' + '
  • ' + '
  • Block icons (1 valid):' + ' ' + ' ' + '
  • ' + '
'; // Scan DOM setRoot(node); scanDOM(); // Change icon name const icon = node.querySelector('iconify-icon[title]'); expect(icon).to.not.be.equal(null); icon.setAttribute('data-icon', '@' + provider + ':foo'); // First API response should have loaded, but only 1 icon setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(1); }, 200); // Second API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal(3); done(); }, 700); }); it('Unattached DOM node', (done) => { const fakeRoot = getNode('scan-dom-unattached'); const provider = nextPrefix(); const prefix = nextPrefix(); // Set fake API hosts to make test reliable setAPIConfig(provider, { resources: ['https://api1.local', 'https://api2.local'], }); // Load icons after 100ms const data: FakeData = { icons: ['home'], delay: 100, data: { prefix, icons: { home: { body: '', }, }, width: 24, height: 24, }, }; setFakeData(provider, prefix, data); const node = document.createElement('div'); node.innerHTML = 'Icon:' + ' '; // Set root node, test nodes list setRoot(fakeRoot); // Test listRootNodes let nodes = listRootNodes(); expect(nodes.length).to.be.equal(1); expect(nodes[0].node).to.be.equal(fakeRoot); expect(nodes[0].temporary).to.be.equal(false); // Scan different node scanElement(node); // Test listRootNodes nodes = listRootNodes(); expect(nodes.length).to.be.equal(2); expect(nodes[0].node).to.be.equal(fakeRoot); expect(nodes[1].node).to.be.equal(node); expect(nodes[1].temporary).to.be.equal(true); // API response should have loaded setTimeout(() => { const elements = node.querySelectorAll('svg.iconify'); expect(elements.length).to.be.equal( 1, 'Expected to find 1 rendered SVG element' ); // Test nodes list: temporary node should have been removed nodes = listRootNodes(); expect(nodes.length).to.be.equal(1); expect(nodes[0].node).to.be.equal(fakeRoot); // Done done(); }, 200); }); });