2
0
mirror of https://github.com/iconify/iconify.git synced 2024-12-13 22:18:24 +00:00

Update Svelte component to new structure, redo tests with TypeScript and demos with API

This commit is contained in:
Vjacheslav Trushkin 2021-09-27 16:29:45 +03:00
parent b415911f04
commit 1f203e2914
35 changed files with 6476 additions and 8343 deletions

View File

@ -22,7 +22,6 @@
"@babel/plugin-transform-runtime": "^7.12.1", "@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.7", "@babel/preset-env": "^7.12.7",
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"@iconify-icons/bi": "^1.0.0",
"@iconify-icons/openmoji": "^1.0.9", "@iconify-icons/openmoji": "^1.0.9",
"@iconify/svelte": "^2.1.0-beta.1", "@iconify/svelte": "^2.1.0-beta.1",
"@rollup/plugin-babel": "^5.2.1", "@rollup/plugin-babel": "^5.2.1",

View File

@ -1,9 +1,5 @@
<script> <script>
import Icon from '@iconify/svelte'; import Icon from '@iconify/svelte';
import homeIcon from '@iconify-icons/bi/house-door';
import blogIcon from '@iconify-icons/bi/file-text';
import aboutIcon from '@iconify-icons/bi/question-octagon';
export let segment; export let segment;
</script> </script>
@ -67,13 +63,13 @@
<ul> <ul>
<li> <li>
<a aria-current={segment === undefined ? 'page' : undefined} href="."> <a aria-current={segment === undefined ? 'page' : undefined} href=".">
<Icon icon={homeIcon} /> <Icon icon="bi:house-door" />
Home Home
</a> </a>
</li> </li>
<li> <li>
<a aria-current={segment === 'about' ? 'page' : undefined} href="about"> <a aria-current={segment === 'about' ? 'page' : undefined} href="about">
<Icon icon={aboutIcon} /> <Icon icon="bi:question-octagon" />
About About
</a> </a>
</li> </li>
@ -85,7 +81,7 @@
rel="prefetch" rel="prefetch"
aria-current={segment === 'blog' ? 'page' : undefined} aria-current={segment === 'blog' ? 'page' : undefined}
href="blog"> href="blog">
<Icon icon={blogIcon} /> <Icon icon="bi:file-text" />
Blog Blog
</a> </a>
</li> </li>

View File

@ -13,16 +13,13 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
let Icon; let Icon;
let postIcon;
onMount(async () => { onMount(async () => {
const promises = [ const promises = [
import('@iconify/svelte'), import('@iconify/svelte'),
import('@iconify-icons/bi/link-45deg'),
]; ];
const results = await Promise.all(promises); const results = await Promise.all(promises);
Icon = results[0].default; Icon = results[0].default;
postIcon = results[1].default;
}); });
export let posts; export let posts;
@ -70,7 +67,7 @@
the user hovers over the link or taps it, instead of the user hovers over the link or taps it, instead of
waiting for the 'click' event --> waiting for the 'click' event -->
<li> <li>
<svelte:component this={Icon} icon={postIcon} /> <svelte:component this={Icon} icon=bi:link-45deg />
<a rel="prefetch" href="blog/{post.slug}">{post.title}</a> <a rel="prefetch" href="blog/{post.slug}">{post.title}</a>
</li> </li>
{/each} {/each}

View File

@ -4,7 +4,8 @@
"@iconify/types", "@iconify/types",
"@iconify/core", "@iconify/core",
"@iconify/utils", "@iconify/utils",
"@cyberalien/redundancy" "@cyberalien/redundancy",
"@iconify/api-redundancy"
], ],
"compiler": { "compiler": {
"skipLibCheck": true "skipLibCheck": true

View File

@ -0,0 +1,15 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
verbose: true,
transform: {
'^.+\\.svelte$': 'svelte-jester',
},
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/tests/**/*.test.ts'],
globals: {
'ts-jest': {
tsconfig: 'tests/tsconfig.json',
},
},
};

View File

@ -0,0 +1,16 @@
{
"name": "@iconify/svelte/offline",
"svelte": "../dist/OfflineIcon.svelte",
"module": "../dist/offline.mjs",
"main": "../dist/offline.js",
"types": "../dist/offline.d.ts",
"exports": {
"./*": "./*",
".": {
"import": "../dist/offline.mjs",
"types": "../dist/offline.d.ts",
"svelte": "../dist/OfflineIcon.svelte",
"default": "../dist/offline.js"
}
}
}

View File

@ -0,0 +1,5 @@
# @iconify/react/offline
This sub-directory contains `package.json` with entry points for importing `@iconify/react/offline`.
There is a duplicate entry in `exports` section of `package.json` in the parent directory, but at moment of coding this, TypeScript does not support conditional exports properly, so this directory is used as a duplicate to make everything work with TypeScript.

File diff suppressed because it is too large Load Diff

View File

@ -16,47 +16,46 @@
"module": "dist/index.mjs", "module": "dist/index.mjs",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"exports": {
"./*": "./*",
".": {
"import": "./dist/index.mjs",
"svelte": "./dist/Icon.svelte",
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./offline": {
"import": "./dist/offline.mjs",
"svelte": "./dist/OfflineIcon.svelte",
"types": "./dist/offline.d.ts",
"default": "./dist/offline.js"
}
},
"scripts": { "scripts": {
"build": "node build", "build": "node build",
"build:tsc": "tsc -b", "build:tsc": "tsc -b",
"build:bundles": "rollup -c rollup.config.js", "build:bundles": "rollup -c rollup.config.js",
"build:api": "node build --only-api", "build:api": "node build --only-api",
"pretest": "npm run build",
"test": "jest" "test": "jest"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-env": "^7.14.2", "@iconify/core": "^1.2.0-beta.3",
"@iconify/core": "^1.2.0-beta.2", "@iconify/utils": "^1.0.9",
"@iconify/types": "^1.0.6",
"@iconify/utils": "^1.0.7",
"@microsoft/api-extractor": "^7.15.0", "@microsoft/api-extractor": "^7.15.0",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0", "@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-typescript": "^8.2.1", "@rollup/plugin-typescript": "^8.2.1",
"@testing-library/jest-dom": "^5.12.0", "@testing-library/jest-dom": "^5.14.1",
"@testing-library/svelte": "^3.0.3", "@testing-library/svelte": "^3.0.3",
"@tsconfig/svelte": "^1.0.10", "@tsconfig/svelte": "^1.0.10",
"babel-jest": "^26.6.3", "@types/jest": "^27.0.2",
"rollup": "^2.33.3", "rollup": "^2.33.3",
"rollup-plugin-svelte": "^6.1.1", "rollup-plugin-svelte": "^6.1.1",
"svelte": "^3.38.2", "svelte": "^3.43.0",
"svelte-jester": "^1.5.0", "svelte-jester": "^2.1.5",
"svelte-preprocess": "^4.7.2", "svelte-preprocess": "^4.9.5",
"ts-jest": "^26.5.5" "ts-jest": "^27.0.5"
}, },
"dependencies": { "dependencies": {
"cross-fetch": "^3.1.4" "cross-fetch": "^3.1.4"
},
"jest": {
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.ts$": "ts-jest",
"^.+\\.svelte$": "svelte-jester"
},
"moduleFileExtensions": [
"js",
"ts",
"svelte"
]
} }
} }

View File

@ -1,6 +1,5 @@
import svelte from 'rollup-plugin-svelte'; import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve'; import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript'; import typescript from '@rollup/plugin-typescript';
import sveltePreprocess from 'svelte-preprocess'; import sveltePreprocess from 'svelte-preprocess';
@ -22,10 +21,11 @@ export default [
preprocess: sveltePreprocess(), preprocess: sveltePreprocess(),
}), }),
resolve({ resolve({
extensions: ['.ts', '.js', '.svelte'], browser: true,
extensions: ['.ts', '.mjs', '.js', '.svelte'],
dedupe: ['svelte'],
}), }),
typescript(), typescript(),
commonjs(),
], ],
}, },
{ {
@ -39,10 +39,11 @@ export default [
preprocess: sveltePreprocess(), preprocess: sveltePreprocess(),
}), }),
resolve({ resolve({
extensions: ['.ts', '.js', '.svelte'], browser: true,
extensions: ['.ts', '.mjs', '.js', '.svelte'],
dedupe: ['svelte'],
}), }),
typescript(), typescript(),
commonjs(),
], ],
}, },
@ -57,10 +58,10 @@ export default [
], ],
plugins: [ plugins: [
resolve({ resolve({
extensions: ['.ts', '.js', '.svelte'], extensions: ['.ts', '.mjs', '.js', '.svelte'],
dedupe: ['svelte'],
}), }),
typescript(), typescript(),
commonjs(),
], ],
}, },
// Files included in OfflineIcon.svelte as bundle // Files included in OfflineIcon.svelte as bundle
@ -74,10 +75,10 @@ export default [
], ],
plugins: [ plugins: [
resolve({ resolve({
extensions: ['.ts', '.js', '.svelte'], extensions: ['.ts', '.mjs', '.js', '.svelte'],
dedupe: ['svelte'],
}), }),
typescript(), typescript(),
commonjs(),
], ],
}, },
]; ];

View File

@ -1,4 +1,4 @@
import type { IconifyJSON } from '@iconify/types'; import type { IconifyJSON, IconifyIcon } from '@iconify/types';
// Core // Core
import { IconifyIconName, stringToIcon } from '@iconify/utils/lib/icon/name'; import { IconifyIconName, stringToIcon } from '@iconify/utils/lib/icon/name';
@ -7,51 +7,55 @@ import type {
IconifyHorizontalIconAlignment, IconifyHorizontalIconAlignment,
IconifyVerticalIconAlignment, IconifyVerticalIconAlignment,
} from '@iconify/utils/lib/customisations'; } from '@iconify/utils/lib/customisations';
import type { IconifyStorageFunctions } from '@iconify/core/lib/storage/functions';
import { import {
IconifyStorageFunctions, iconExists,
storageFunctions, getIcon,
addIcon,
addCollection,
getIconData, getIconData,
allowSimpleNames, allowSimpleNames,
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { import { listIcons } from '@iconify/core/lib/storage/storage';
IconifyBuilderFunctions, import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
builderFunctions, import { buildIcon } from '@iconify/core/lib/builder/functions';
} from '@iconify/core/lib/builder/functions'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
import { fullIcon, IconifyIcon } from '@iconify/utils/lib/icon'; import { fullIcon } from '@iconify/utils/lib/icon';
// API // API
import { import type {
IconifyAPIFunctions, IconifyAPIFunctions,
IconifyAPIInternalFunctions, IconifyAPIInternalFunctions,
APIFunctions,
APIInternalFunctions,
IconifyAPIQueryParams, IconifyAPIQueryParams,
IconifyAPICustomQueryParams, IconifyAPICustomQueryParams,
IconifyAPIMergeQueryParams, IconifyAPIMergeQueryParams,
} from '@iconify/core/lib/api/functions'; } from '@iconify/core/lib/api/functions';
import { import type {
setAPIModule,
IconifyAPIModule, IconifyAPIModule,
IconifyAPISendQuery, IconifyAPISendQuery,
IconifyAPIPrepareIconsQuery, IconifyAPIPrepareIconsQuery,
} from '@iconify/core/lib/api/modules'; } from '@iconify/core/lib/api/modules';
import { jsonpAPIModule } from '@iconify/core/lib/api/modules/jsonp'; import { setAPIModule } from '@iconify/core/lib/api/modules';
import { import type {
fetchAPIModule,
getFetch,
setFetch,
} from '@iconify/core/lib/api/modules/fetch';
import {
setAPIConfig,
PartialIconifyAPIConfig, PartialIconifyAPIConfig,
IconifyAPIConfig, IconifyAPIConfig,
GetAPIConfig, GetAPIConfig,
} from '@iconify/core/lib/api/config'; } from '@iconify/core/lib/api/config';
import {
addAPIProvider,
getAPIConfig,
listAPIProviders,
} from '@iconify/core/lib/api/config';
import { fetchAPIModule, setFetch } from '@iconify/core/lib/api/modules/fetch';
import type { import type {
IconifyIconLoaderCallback, IconifyIconLoaderCallback,
IconifyIconLoaderAbort, IconifyIconLoaderAbort,
} from '@iconify/core/lib/api/icons'; } from '@iconify/core/lib/api/icons';
import { loadIcons } from '@iconify/core/lib/api/icons';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
import { mergeParams } from '@iconify/core/lib/api/params';
// Cache // Cache
import { cache } from '@iconify/core/lib/cache'; import { cache } from '@iconify/core/lib/cache';
@ -119,73 +123,19 @@ export { RawIconCustomisations, IconifyIconBuildResult };
/* Browser cache */ /* Browser cache */
export { IconifyBrowserCacheType }; export { IconifyBrowserCacheType };
/** /**
* Enable and disable browser cache * Enable cache
*/ */
export const enableCache = (storage: IconifyBrowserCacheType) => function enableCache(storage: IconifyBrowserCacheType): void {
toggleBrowserCache(storage, true); toggleBrowserCache(storage, true);
}
export const disableCache = (storage: IconifyBrowserCacheType) => /**
* Disable cache
*/
function disableCache(storage: IconifyBrowserCacheType): void {
toggleBrowserCache(storage, false); toggleBrowserCache(storage, false);
}
/* Storage functions */
/**
* Check if icon exists
*/
export const iconExists = storageFunctions.iconExists;
/**
* Get icon data
*/
export const getIcon = storageFunctions.getIcon;
/**
* List available icons
*/
export const listIcons = storageFunctions.listIcons;
/**
* Add one icon
*/
export const addIcon = storageFunctions.addIcon;
/**
* Add icon set
*/
export const addCollection = storageFunctions.addCollection;
/* Builder functions */
/**
* Calculate icon size
*/
export const calculateSize = builderFunctions.calculateSize;
/**
* Replace unique ids in content
*/
export const replaceIDs = builderFunctions.replaceIDs;
/**
* Build SVG
*/
export const buildIcon = builderFunctions.buildIcon;
/* API functions */
/**
* Load icons
*/
export const loadIcons = APIFunctions.loadIcons;
/**
* Add API provider
*/
export const addAPIProvider = APIFunctions.addAPIProvider;
/**
* Export internal functions that can be used by third party implementations
*/
export const _api = APIInternalFunctions;
/** /**
* Initialise stuff * Initialise stuff
@ -194,15 +144,7 @@ export const _api = APIInternalFunctions;
allowSimpleNames(true); allowSimpleNames(true);
// Set API module // Set API module
setAPIModule('', getFetch() ? fetchAPIModule : jsonpAPIModule);
/**
* Function to enable node-fetch for getting icons on server side
*/
_api.setFetch = (nodeFetch: typeof fetch) => {
setFetch(nodeFetch);
setAPIModule('', fetchAPIModule); setAPIModule('', fetchAPIModule);
};
/** /**
* Browser stuff * Browser stuff
@ -260,7 +202,7 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
) { ) {
continue; continue;
} }
if (!setAPIConfig(key, value)) { if (!addAPIProvider(key, value)) {
console.error(err); console.error(err);
} }
} catch (e) { } catch (e) {
@ -394,3 +336,33 @@ export function generateIcon(
): RenderResult | null { ): RenderResult | null {
return icon ? render(icon, props) : null; return icon ? render(icon, props) : null;
} }
/**
* Internal API
*/
const _api: IconifyAPIInternalFunctions = {
getAPIConfig,
setAPIModule,
sendAPIQuery,
setFetch,
listAPIProviders,
mergeParams,
};
/**
* Export functions
*/
// IconifyAPIInternalFunctions
export { _api };
// IconifyAPIFunctions
export { addAPIProvider, loadIcons };
// IconifyStorageFunctions
export { iconExists, getIcon, listIcons, addIcon, addCollection };
// IconifyBuilderFunctions
export { replaceIDs, calculateSize, buildIcon };
// IconifyBrowserCacheFunctions
export { enableCache, disableCache };

View File

@ -1,4 +1,7 @@
import { loadIcons, iconExists } from '../../dist/'; /**
* @jest-environment jsdom
*/
import { loadIcons, iconExists } from '../../dist';
import { mockAPIData } from '@iconify/core/lib/api/modules/mock'; import { mockAPIData } from '@iconify/core/lib/api/modules/mock';
import { provider, nextPrefix } from './load'; import { provider, nextPrefix } from './load';
@ -22,7 +25,7 @@ describe('Testing fake API', () => {
}); });
// Check if icon has been loaded // Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// Load icon // Load icon
loadIcons([iconName], (loaded, missing, pending) => { loadIcons([iconName], (loaded, missing, pending) => {

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon, { loadIcons, iconExists } from '../../dist/'; import Icon, { loadIcons, iconExists } from '../../';
import { mockAPIData } from '@iconify/core/lib/api/modules/mock'; import { mockAPIData } from '@iconify/core/lib/api/modules/mock';
import { provider, nextPrefix } from './load'; import { provider, nextPrefix } from './load';
@ -30,7 +33,7 @@ describe('Rendering icon', () => {
}); });
// Check if icon has been loaded // Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// Load icon // Load icon
loadIcons([iconName], (loaded, missing, pending) => { loadIcons([iconName], (loaded, missing, pending) => {
@ -44,29 +47,29 @@ describe('Rendering icon', () => {
]); ]);
expect(missing).toMatchObject([]); expect(missing).toMatchObject([]);
expect(pending).toMatchObject([]); expect(pending).toMatchObject([]);
expect(iconExists(iconName)).toEqual(true); expect(iconExists(iconName)).toBe(true);
// Render component // Render component
const component = render(Icon, { const component = render(Icon, {
icon: iconName, icon: iconName,
onLoad: (name) => { onLoad: (name: string) => {
expect(name).toEqual(iconName); expect(name).toBe(iconName);
expect(onLoadCalled).toEqual(false); expect(onLoadCalled).toBe(false);
onLoadCalled = true; onLoadCalled = true;
}, },
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; const html = (node.parentNode as HTMLDivElement).innerHTML;
// Check HTML // Check HTML
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" class="' + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" class="' +
className + className +
'"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>' '"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
); );
// Make sure onLoad has been called // Make sure onLoad has been called
expect(onLoadCalled).toEqual(true); expect(onLoadCalled).toBe(true);
done(); done();
}); });
@ -91,33 +94,34 @@ describe('Rendering icon', () => {
}, },
delay: (next) => { delay: (next) => {
// Icon should not have loaded yet // Icon should not have loaded yet
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// onLoad should not have been called yet // onLoad should not have been called yet
expect(onLoadCalled).toEqual(false); expect(onLoadCalled).toBe(false);
// Send icon data // Send icon data
next(); next();
// Test it again // Test it again
expect(iconExists(iconName)).toEqual(true); expect(iconExists(iconName)).toBe(true);
// Check if state was changed // Check if state was changed
// Wrapped in double setTimeout() because re-render takes 2 ticks // Wrapped in double setTimeout() because re-render takes 2 ticks
setTimeout(() => { setTimeout(() => {
setTimeout(() => { setTimeout(() => {
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; const html = (node.parentNode as HTMLDivElement)
.innerHTML;
// Check HTML // Check HTML
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="test ' + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="test ' +
className + className +
'" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>' '" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
); );
// onLoad should have been called // onLoad should have been called
expect(onLoadCalled).toEqual(true); expect(onLoadCalled).toBe(true);
done(); done();
}, 0); }, 0);
@ -126,26 +130,26 @@ describe('Rendering icon', () => {
}); });
// Check if icon has been loaded // Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// Render component // Render component
const component = render(Icon, { const component = render(Icon, {
icon: iconName, icon: iconName,
// Also testing simple class // Also testing simple class
class: 'test', class: 'test',
onLoad: (name) => { onLoad: (name: string) => {
expect(name).toEqual(iconName); expect(name).toBe(iconName);
expect(onLoadCalled).toEqual(false); expect(onLoadCalled).toBe(false);
onLoadCalled = true; onLoadCalled = true;
}, },
}); });
// Should render empty icon // Should render empty icon
const html = component.container.innerHTML; const html = component.container.innerHTML;
expect(html).toEqual('<div></div>'); expect(html).toBe('<div></div>');
// onLoad should not have been called yet // onLoad should not have been called yet
expect(onLoadCalled).toEqual(false); expect(onLoadCalled).toBe(false);
}); });
test('missing icon', (done) => { test('missing icon', (done) => {
@ -160,20 +164,20 @@ describe('Rendering icon', () => {
response: 404, response: 404,
delay: (next) => { delay: (next) => {
// Icon should not have loaded yet // Icon should not have loaded yet
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// Send icon data // Send icon data
next(); next();
// Test it again // Test it again
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// Check if state was changed // Check if state was changed
// Wrapped in double setTimeout() because re-render takes 2 ticks // Wrapped in double setTimeout() because re-render takes 2 ticks
setTimeout(() => { setTimeout(() => {
setTimeout(() => { setTimeout(() => {
const html = component.container.innerHTML; const html = component.container.innerHTML;
expect(html).toEqual('<div></div>'); expect(html).toBe('<div></div>');
done(); done();
}, 0); }, 0);
@ -182,7 +186,7 @@ describe('Rendering icon', () => {
}); });
// Check if icon has been loaded // Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false); expect(iconExists(iconName)).toBe(false);
// Render component // Render component
const component = render(Icon, { const component = render(Icon, {
@ -194,6 +198,6 @@ describe('Rendering icon', () => {
// Should render empty icon // Should render empty icon
const html = component.container.innerHTML; const html = component.container.innerHTML;
expect(html).toEqual('<div></div>'); expect(html).toBe('<div></div>');
}); });
}); });

View File

@ -1,375 +0,0 @@
import { render } from '@testing-library/svelte';
import { iconExists } from '../../dist/';
import { mockAPIData } from '@iconify/core/lib/api/modules/mock';
import { provider, nextPrefix } from './load';
import ChangeIcon from './fixtures/ChangeIcon.svelte';
import ChangeProps from './fixtures/ChangeProps.svelte';
const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
width: 24,
height: 24,
};
const iconData2 = {
body: '<path d="M19.031 4.281l-11 11l-.687.719l.687.719l11 11l1.438-1.438L10.187 16L20.47 5.719z" fill="currentColor"/>',
width: 32,
height: 32,
};
describe('Rendering icon', () => {
test('changing icon property', (done) => {
const prefix = nextPrefix();
const name = 'changing-prop';
const name2 = 'changing-prop2';
const iconName = `@${provider}:${prefix}:${name}`;
const iconName2 = `@${provider}:${prefix}:${name2}`;
const className = `iconify iconify--${prefix} iconify--${provider}`;
let onLoadCalled = ''; // Name of icon from last onLoad call
let triggerSwap;
mockAPIData({
type: 'icons',
provider,
prefix,
response: {
prefix,
icons: {
[name]: iconData,
},
},
delay: (next) => {
// Fixture callback should have been called
expect(typeof triggerSwap).toEqual('function');
// Icon should not have loaded yet
expect(iconExists(iconName)).toEqual(false);
// onLoad should not have been called yet
expect(onLoadCalled).toEqual('');
// Send icon data
next();
// Test it again
expect(iconExists(iconName)).toEqual(true);
// Check if state was changed
// Wrapped in double setTimeout() because re-render takes 2 ticks
setTimeout(() => {
setTimeout(() => {
const node = component.container.querySelector('svg');
const html = node.parentNode.innerHTML;
// Check HTML
expect(html).toEqual(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" class="' +
className +
'"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
);
// onLoad should have been called
expect(onLoadCalled).toEqual(iconName);
// Change property
triggerSwap();
}, 0);
}, 0);
},
});
mockAPIData({
type: 'icons',
provider,
prefix,
response: {
prefix,
icons: {
[name2]: iconData2,
},
},
delay: (next) => {
// Icon should not have loaded yet
expect(iconExists(iconName2)).toEqual(false);
// onLoad should have been called only once for previous icon
expect(onLoadCalled).toEqual(iconName);
// Send icon data
next();
// Test it again
expect(iconExists(iconName2)).toEqual(true);
// Check if state was changed
// Wrapped in double setTimeout() because re-render takes 2 ticks
setTimeout(() => {
setTimeout(() => {
const node = component.container.querySelector('svg');
const html = node.parentNode.innerHTML;
// Check HTML
expect(html).toEqual(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" class="' +
className +
'"><path d="M19.031 4.281l-11 11l-.687.719l.687.719l11 11l1.438-1.438L10.187 16L20.47 5.719z" fill="currentColor"></path></svg>'
);
// onLoad should have been called for second icon
expect(onLoadCalled).toEqual(iconName2);
done();
}, 0);
}, 0);
},
});
// Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false);
// Render component
const component = render(ChangeIcon, {
icon1: iconName,
icon2: iconName2,
expose: (swap) => {
triggerSwap = swap;
},
onLoad: (name) => {
// onLoad should be called only once per icon
switch (name) {
// First onLoad call
case iconName:
expect(onLoadCalled).toEqual('');
break;
// Second onLoad call
case iconName2:
expect(onLoadCalled).toEqual(iconName);
break;
default:
throw new Error(`Unexpected onLoad('${name}') call`);
}
onLoadCalled = name;
},
});
// Should render empty icon
const html = component.container.innerHTML;
expect(html).toEqual('<div></div>');
// onLoad should not have been called yet
expect(onLoadCalled).toEqual('');
});
test('changing icon property while loading', (done) => {
const prefix = nextPrefix();
const name = 'changing-prop';
const name2 = 'changing-prop2';
const iconName = `@${provider}:${prefix}:${name}`;
const iconName2 = `@${provider}:${prefix}:${name2}`;
const className = `iconify iconify--${prefix} iconify--${provider}`;
let onLoadCalled = ''; // Name of icon from last onLoad call
let isSync = true;
let triggerSwap;
mockAPIData({
type: 'icons',
provider,
prefix,
response: {
prefix,
icons: {
[name]: iconData,
},
},
delay: (next) => {
// Should have been called asynchronously
expect(isSync).toEqual(false);
// Icon should not have loaded yet
expect(iconExists(iconName)).toEqual(false);
// Send icon data
next();
},
});
mockAPIData({
type: 'icons',
provider,
prefix,
response: {
prefix,
icons: {
[name2]: iconData2,
},
},
delay: (next) => {
// Should have been called asynchronously
expect(isSync).toEqual(false);
// Icon should not have loaded yet
expect(iconExists(iconName2)).toEqual(false);
// Send icon data
next();
// Test it again
expect(iconExists(iconName2)).toEqual(true);
// Check if state was changed
// Wrapped in double setTimeout() because re-render takes 2 ticks
setTimeout(() => {
setTimeout(() => {
const node = component.container.querySelector('svg');
const html = node.parentNode.innerHTML;
// Check HTML
expect(html).toEqual(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" class="' +
className +
'"><path d="M19.031 4.281l-11 11l-.687.719l.687.719l11 11l1.438-1.438L10.187 16L20.47 5.719z" fill="currentColor"></path></svg>'
);
// onLoad should have been called for second icon
expect(onLoadCalled).toEqual(iconName2);
done();
}, 0);
}, 0);
},
});
// Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false);
// Render component
const component = render(ChangeIcon, {
icon1: iconName,
icon2: iconName2,
expose: (swap) => {
triggerSwap = swap;
},
onLoad: (name) => {
// onLoad should be called only for second icon
expect(name).toEqual(iconName2);
onLoadCalled = name;
},
});
// Should render empty icon
const html = component.container.innerHTML;
expect(html).toEqual('<div></div>');
// Fixture callback should have been called
expect(typeof triggerSwap).toEqual('function');
// Change property
triggerSwap();
// Async
isSync = false;
// onLoad should not have been called yet
expect(onLoadCalled).toEqual('');
});
test('changing multiple properties', (done) => {
const prefix = nextPrefix();
const name = 'multiple-props';
const iconName = `@${provider}:${prefix}:${name}`;
const className = `iconify iconify--${prefix} iconify--${provider}`;
let onLoadCalled = false;
let triggerSwap;
mockAPIData({
type: 'icons',
provider,
prefix,
response: {
prefix,
icons: {
[name]: iconData,
},
},
delay: (next) => {
// Fixture callback should have been called
expect(typeof triggerSwap).toEqual('function');
// Icon should not have loaded yet
expect(iconExists(iconName)).toEqual(false);
// Send icon data
next();
// Test it again
expect(iconExists(iconName)).toEqual(true);
// Check if state was changed
// Wrapped in double setTimeout() because re-render takes 2 ticks
setTimeout(() => {
setTimeout(() => {
const node = component.container.querySelector('svg');
const html = node.parentNode.innerHTML;
// Check HTML
expect(html).toEqual(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" class="' +
className +
'"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
);
// onLoad should have been called
expect(onLoadCalled).toEqual(true);
// Add horizontal flip and style
triggerSwap();
// Wait for component to re-render
setTimeout(() => {
setTimeout(() => {
// Check HTML again
const node =
component.container.querySelector('svg');
const html = node.parentNode.innerHTML;
expect(html).toEqual(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" class="' +
className +
'"><g transform="translate(24 0) scale(-1 1)"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></g></svg>'
);
done();
}, 0);
}, 0);
}, 0);
}, 0);
},
});
// Check if icon has been loaded
expect(iconExists(iconName)).toEqual(false);
// Render component
const component = render(ChangeProps, {
icon: iconName,
expose: (swap) => {
triggerSwap = swap;
},
onLoad: (name) => {
expect(name).toEqual(iconName);
// Should be called only once
expect(onLoadCalled).toEqual(false);
onLoadCalled = true;
},
});
// Should render empty icon
const html = component.container.innerHTML;
expect(html).toEqual('<div></div>');
// onLoad should not have been called yet
expect(onLoadCalled).toEqual(false);
});
});

View File

@ -1,19 +0,0 @@
<script>
import Icon from '../../../dist/';
export let icon1;
export let icon2;
export let expose;
export let onLoad;
let icon = icon1;
$: {
expose(swap);
}
function swap() {
icon = icon2;
}
</script>
<Icon icon={icon} onLoad={onLoad} />

View File

@ -1,24 +0,0 @@
<script>
import Icon from '../../../dist/';
export let icon;
export let expose;
export let onLoad;
const props = {
icon,
onLoad
};
$: {
expose(swap);
}
function swap() {
props.hFlip = true;
props.style = {
color: 'red'
}
}
</script>
<Icon {...props} />

View File

@ -1,4 +1,4 @@
import { _api, addAPIProvider } from '../../dist/'; import { _api, addAPIProvider } from '../../dist';
import { mockAPIModule } from '@iconify/core/lib/api/modules/mock'; import { mockAPIModule } from '@iconify/core/lib/api/modules/mock';
// API provider for tests // API provider for tests

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -16,22 +19,22 @@ describe('Creating component', () => {
throw new Error('onLoad called for object!'); throw new Error('onLoad called for object!');
}, },
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; expect(node).not.toBeNull();
expect(node.parentNode).not.toBeNull();
const html = (node.parentNode as HTMLDivElement).innerHTML;
// Check HTML // Check HTML
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>' '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
); );
// Make sure getAttribute() works, used in other tests // Make sure getAttribute() works, used in other tests
expect(node.getAttribute('xmlns')).toEqual( expect(node.getAttribute('xmlns')).toBe('http://www.w3.org/2000/svg');
'http://www.w3.org/2000/svg' expect(node.getAttribute('aria-hidden')).toBe('true');
);
expect(node.getAttribute('aria-hidden')).toEqual('true');
// Make sure style exists // Make sure style exists
const style = node.style; const style = node.style;
expect(typeof style).toEqual('object'); expect(typeof style).toBe('object');
}); });
}); });

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
describe('Empty icon', () => { describe('Empty icon', () => {
test('basic test', () => { test('basic test', () => {
@ -7,6 +10,6 @@ describe('Empty icon', () => {
const html = component.container.innerHTML; const html = component.container.innerHTML;
// Empty container div // Empty container div
expect(html).toEqual('<div></div>'); expect(html).toBe('<div></div>');
}); });
}); });

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -10,8 +13,8 @@ const iconData = {
describe('Padding attributes', () => { describe('Padding attributes', () => {
test('title', () => { test('title', () => {
const component = render(Icon, { icon: iconData, title: 'Icon!' }); const component = render(Icon, { icon: iconData, title: 'Icon!' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('title')).toEqual('Icon!'); expect(node.getAttribute('title')).toBe('Icon!');
}); });
test('aria-hidden', () => { test('aria-hidden', () => {
@ -20,7 +23,7 @@ describe('Padding attributes', () => {
'icon': iconData, 'icon': iconData,
'aria-hidden': 'false', 'aria-hidden': 'false',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('aria-hidden')).toEqual(null); expect(node.getAttribute('aria-hidden')).toEqual(null);
}); });
@ -30,8 +33,8 @@ describe('Padding attributes', () => {
icon: iconData, icon: iconData,
ariaHidden: false, ariaHidden: false,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('aria-hidden')).toEqual(null); expect(node.getAttribute('aria-hidden')).toBe(null);
}); });
test('style', () => { test('style', () => {
@ -39,9 +42,9 @@ describe('Padding attributes', () => {
icon: iconData, icon: iconData,
style: 'vertical-align: 0; color: red;', style: 'vertical-align: 0; color: red;',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.style.verticalAlign).toEqual('0'); expect(node.style.verticalAlign).toBe('0');
expect(node.style.color).toEqual('red'); expect(node.style.color).toBe('red');
}); });
test('color', () => { test('color', () => {
@ -49,8 +52,8 @@ describe('Padding attributes', () => {
icon: iconData, icon: iconData,
color: 'red', color: 'red',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.style.color).toEqual('red'); expect(node.style.color).toBe('red');
}); });
test('color with style', () => { test('color with style', () => {
@ -59,8 +62,8 @@ describe('Padding attributes', () => {
color: 'red', color: 'red',
style: 'color: green;', style: 'color: green;',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.style.color).toEqual('red'); expect(node.style.color).toBe('red');
}); });
test('attributes that cannot change', () => { test('attributes that cannot change', () => {
@ -69,10 +72,8 @@ describe('Padding attributes', () => {
viewBox: '0 0 0 0', viewBox: '0 0 0 0',
preserveAspectRatio: 'none', preserveAspectRatio: 'none',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('viewBox')).toEqual('0 0 24 24'); expect(node.getAttribute('viewBox')).toBe('0 0 24 24');
expect(node.getAttribute('preserveAspectRatio')).toEqual( expect(node.getAttribute('preserveAspectRatio')).toBe('xMidYMid meet');
'xMidYMid meet'
);
}); });
}); });

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -10,9 +13,9 @@ const iconData = {
describe('Dimensions', () => { describe('Dimensions', () => {
test('height', () => { test('height', () => {
const component = render(Icon, { icon: iconData, height: '48' }); const component = render(Icon, { icon: iconData, height: '48' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('48'); expect(node.getAttribute('height')).toBe('48');
expect(node.getAttribute('width')).toEqual('48'); expect(node.getAttribute('width')).toBe('48');
}); });
test('width and height', () => { test('width and height', () => {
@ -22,9 +25,9 @@ describe('Dimensions', () => {
width: 32, width: 32,
height: '48', height: '48',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('48'); expect(node.getAttribute('height')).toBe('48');
expect(node.getAttribute('width')).toEqual('32'); expect(node.getAttribute('width')).toBe('32');
}); });
test('auto', () => { test('auto', () => {
@ -32,9 +35,9 @@ describe('Dimensions', () => {
icon: iconData, icon: iconData,
height: 'auto', height: 'auto',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('24'); expect(node.getAttribute('height')).toBe('24');
expect(node.getAttribute('width')).toEqual('24'); expect(node.getAttribute('width')).toBe('24');
}); });
test('invalid values', () => { test('invalid values', () => {
@ -43,8 +46,8 @@ describe('Dimensions', () => {
height: null, height: null,
width: void 0, width: void 0,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('1em'); expect(node.getAttribute('height')).toBe('1em');
expect(node.getAttribute('width')).toEqual('1em'); expect(node.getAttribute('width')).toBe('1em');
}); });
}); });

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
const iconDataWithID = { const iconDataWithID = {
body: '<defs><path id="ssvg-id-1st-place-medala" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medald" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalf" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalh" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalj" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalm" d="M.93.01h120.55v58.36H.93z"/><path d="M52.849 78.373v-3.908c3.681-.359 6.25-.958 7.703-1.798c1.454-.84 2.54-2.828 3.257-5.962h4.021v40.385h-5.437V78.373h-9.544z" id="ssvg-id-1st-place-medalp"/><linearGradient x1="49.998%" y1="-13.249%" x2="49.998%" y2="90.002%" id="ssvg-id-1st-place-medalb"><stop stop-color="#1E88E5" offset="13.55%"/><stop stop-color="#1565C0" offset="93.8%"/></linearGradient><linearGradient x1="26.648%" y1="2.735%" x2="77.654%" y2="105.978%" id="ssvg-id-1st-place-medalk"><stop stop-color="#64B5F6" offset="13.55%"/><stop stop-color="#2196F3" offset="94.62%"/></linearGradient><radialGradient cx="22.368%" cy="12.5%" fx="22.368%" fy="12.5%" r="95.496%" id="ssvg-id-1st-place-medalo"><stop stop-color="#FFEB3B" offset="29.72%"/><stop stop-color="#FBC02D" offset="95.44%"/></radialGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medalc" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medala"/></mask><path fill="url(#ssvg-id-1st-place-medalb)" fill-rule="nonzero" mask="url(#ssvg-id-1st-place-medalc)" d="M45.44 42.18h31.43l30-48.43H75.44z"/></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medale" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medald"/></mask><g opacity=".2" mask="url(#ssvg-id-1st-place-medale)" fill="#424242" fill-rule="nonzero"><path d="M101.23-3L75.2 39H50.85L77.11-3h24.12zm5.64-3H75.44l-30 48h31.42l30.01-48z"/></g></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medalg" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalf"/></mask><path d="M79 30H43c-4.42 0-8 3.58-8 8v16.04c0 2.17 1.8 3.95 4.02 3.96h.01c2.23-.01 4.97-1.75 4.97-3.96V44c0-1.1.9-2 2-2h30c1.1 0 2 .9 2 2v9.93c0 1.98 2.35 3.68 4.22 4.04c.26.05.52.08.78.08c2.21 0 4-1.79 4-4V38c0-4.42-3.58-8-8-8z" fill="#FDD835" fill-rule="nonzero" mask="url(#ssvg-id-1st-place-medalg)"/></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medali" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalh"/></mask><g opacity=".2" mask="url(#ssvg-id-1st-place-medali)" fill="#424242" fill-rule="nonzero"><path d="M79 32c3.31 0 6 2.69 6 6v16.04A2.006 2.006 0 0 1 82.59 56c-1.18-.23-2.59-1.35-2.59-2.07V44c0-2.21-1.79-4-4-4H46c-2.21 0-4 1.79-4 4v10.04c0 .88-1.64 1.96-2.97 1.96c-1.12-.01-2.03-.89-2.03-1.96V38c0-3.31 2.69-6 6-6h36zm0-2H43c-4.42 0-8 3.58-8 8v16.04c0 2.17 1.8 3.95 4.02 3.96h.01c2.23-.01 4.97-1.75 4.97-3.96V44c0-1.1.9-2 2-2h30c1.1 0 2 .9 2 2v9.93c0 1.98 2.35 3.68 4.22 4.04c.26.05.52.08.78.08c2.21 0 4-1.79 4-4V38c0-4.42-3.58-8-8-8z"/></g></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medall" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalj"/></mask><path fill="url(#ssvg-id-1st-place-medalk)" fill-rule="nonzero" mask="url(#ssvg-id-1st-place-medall)" d="M76.87 42.18H45.44l-30-48.43h31.43z"/></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medaln" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalm"/></mask><g opacity=".2" mask="url(#ssvg-id-1st-place-medaln)" fill="#424242" fill-rule="nonzero"><path d="M45.1-3l26.35 42H47.1L20.86-3H45.1zm1.77-3H15.44l30 48h31.42L46.87-6z"/></g></g><circle fill="url(#ssvg-id-1st-place-medalo)" fill-rule="nonzero" cx="64" cy="86" r="38"/><path d="M64 51c19.3 0 35 15.7 35 35s-15.7 35-35 35s-35-15.7-35-35s15.7-35 35-35zm0-3c-20.99 0-38 17.01-38 38s17.01 38 38 38s38-17.01 38-38s-17.01-38-38-38z" opacity=".2" fill="#424242" fill-rule="nonzero"/><path d="M47.3 63.59h33.4v44.4H47.3z"/><use fill="#000" xlink:href="#ssvg-id-1st-place-medalp"/><use fill="#FFA000" xlink:href="#ssvg-id-1st-place-medalp"/></g>', body: '<defs><path id="ssvg-id-1st-place-medala" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medald" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalf" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalh" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalj" d="M.93.01h120.55v58.36H.93z"/><path id="ssvg-id-1st-place-medalm" d="M.93.01h120.55v58.36H.93z"/><path d="M52.849 78.373v-3.908c3.681-.359 6.25-.958 7.703-1.798c1.454-.84 2.54-2.828 3.257-5.962h4.021v40.385h-5.437V78.373h-9.544z" id="ssvg-id-1st-place-medalp"/><linearGradient x1="49.998%" y1="-13.249%" x2="49.998%" y2="90.002%" id="ssvg-id-1st-place-medalb"><stop stop-color="#1E88E5" offset="13.55%"/><stop stop-color="#1565C0" offset="93.8%"/></linearGradient><linearGradient x1="26.648%" y1="2.735%" x2="77.654%" y2="105.978%" id="ssvg-id-1st-place-medalk"><stop stop-color="#64B5F6" offset="13.55%"/><stop stop-color="#2196F3" offset="94.62%"/></linearGradient><radialGradient cx="22.368%" cy="12.5%" fx="22.368%" fy="12.5%" r="95.496%" id="ssvg-id-1st-place-medalo"><stop stop-color="#FFEB3B" offset="29.72%"/><stop stop-color="#FBC02D" offset="95.44%"/></radialGradient></defs><g fill="none" fill-rule="evenodd"><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medalc" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medala"/></mask><path fill="url(#ssvg-id-1st-place-medalb)" fill-rule="nonzero" mask="url(#ssvg-id-1st-place-medalc)" d="M45.44 42.18h31.43l30-48.43H75.44z"/></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medale" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medald"/></mask><g opacity=".2" mask="url(#ssvg-id-1st-place-medale)" fill="#424242" fill-rule="nonzero"><path d="M101.23-3L75.2 39H50.85L77.11-3h24.12zm5.64-3H75.44l-30 48h31.42l30.01-48z"/></g></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medalg" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalf"/></mask><path d="M79 30H43c-4.42 0-8 3.58-8 8v16.04c0 2.17 1.8 3.95 4.02 3.96h.01c2.23-.01 4.97-1.75 4.97-3.96V44c0-1.1.9-2 2-2h30c1.1 0 2 .9 2 2v9.93c0 1.98 2.35 3.68 4.22 4.04c.26.05.52.08.78.08c2.21 0 4-1.79 4-4V38c0-4.42-3.58-8-8-8z" fill="#FDD835" fill-rule="nonzero" mask="url(#ssvg-id-1st-place-medalg)"/></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medali" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalh"/></mask><g opacity=".2" mask="url(#ssvg-id-1st-place-medali)" fill="#424242" fill-rule="nonzero"><path d="M79 32c3.31 0 6 2.69 6 6v16.04A2.006 2.006 0 0 1 82.59 56c-1.18-.23-2.59-1.35-2.59-2.07V44c0-2.21-1.79-4-4-4H46c-2.21 0-4 1.79-4 4v10.04c0 .88-1.64 1.96-2.97 1.96c-1.12-.01-2.03-.89-2.03-1.96V38c0-3.31 2.69-6 6-6h36zm0-2H43c-4.42 0-8 3.58-8 8v16.04c0 2.17 1.8 3.95 4.02 3.96h.01c2.23-.01 4.97-1.75 4.97-3.96V44c0-1.1.9-2 2-2h30c1.1 0 2 .9 2 2v9.93c0 1.98 2.35 3.68 4.22 4.04c.26.05.52.08.78.08c2.21 0 4-1.79 4-4V38c0-4.42-3.58-8-8-8z"/></g></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medall" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalj"/></mask><path fill="url(#ssvg-id-1st-place-medalk)" fill-rule="nonzero" mask="url(#ssvg-id-1st-place-medall)" d="M76.87 42.18H45.44l-30-48.43h31.43z"/></g><g transform="translate(3 4)"><mask id="ssvg-id-1st-place-medaln" fill="#fff"><use xlink:href="#ssvg-id-1st-place-medalm"/></mask><g opacity=".2" mask="url(#ssvg-id-1st-place-medaln)" fill="#424242" fill-rule="nonzero"><path d="M45.1-3l26.35 42H47.1L20.86-3H45.1zm1.77-3H15.44l30 48h31.42L46.87-6z"/></g></g><circle fill="url(#ssvg-id-1st-place-medalo)" fill-rule="nonzero" cx="64" cy="86" r="38"/><path d="M64 51c19.3 0 35 15.7 35 35s-15.7 35-35 35s-35-15.7-35-35s15.7-35 35-35zm0-3c-20.99 0-38 17.01-38 38s17.01 38 38 38s38-17.01 38-38s-17.01-38-38-38z" opacity=".2" fill="#424242" fill-rule="nonzero"/><path d="M47.3 63.59h33.4v44.4H47.3z"/><use fill="#000" xlink:href="#ssvg-id-1st-place-medalp"/><use fill="#FFA000" xlink:href="#ssvg-id-1st-place-medalp"/></g>',
@ -10,7 +13,7 @@ const iconDataWithID = {
describe('Replacing IDs', () => { describe('Replacing IDs', () => {
test('default behavior', () => { test('default behavior', () => {
const component = render(Icon, { icon: iconDataWithID }); const component = render(Icon, { icon: iconDataWithID });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Check that default id doesn't exist // Check that default id doesn't exist
const path = node.getElementById('ssvg-id-1st-place-medala'); const path = node.getElementById('ssvg-id-1st-place-medala');
@ -19,7 +22,7 @@ describe('Replacing IDs', () => {
test('custom generator', () => { test('custom generator', () => {
const component = render(Icon, { icon: iconDataWithID, id: 'test' }); const component = render(Icon, { icon: iconDataWithID, id: 'test' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Check that ID 'testa' exists // Check that ID 'testa' exists
const path = node.getElementById('test-0'); const path = node.getElementById('test-0');

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -10,34 +13,34 @@ const iconData = {
describe('Inline attribute', () => { describe('Inline attribute', () => {
test('boolean true', () => { test('boolean true', () => {
const component = render(Icon, { icon: iconData, inline: true }); const component = render(Icon, { icon: iconData, inline: true });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual('-0.125em'); expect(style.verticalAlign).toBe('-0.125em');
}); });
test('string true', () => { test('string true', () => {
const component = render(Icon, { icon: iconData, inline: 'true' }); const component = render(Icon, { icon: iconData, inline: 'true' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual('-0.125em'); expect(style.verticalAlign).toBe('-0.125em');
}); });
test('false', () => { test('false', () => {
const component = render(Icon, { icon: iconData, inline: false }); const component = render(Icon, { icon: iconData, inline: false });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual(''); expect(style.verticalAlign).toBe('');
}); });
test('false string', () => { test('false string', () => {
// "false" should be ignored // "false" should be ignored
const component = render(Icon, { icon: iconData, inline: 'false' }); const component = render(Icon, { icon: iconData, inline: 'false' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual(''); expect(style.verticalAlign).toBe('');
}); });
}); });

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/'; import Icon from '../../';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -10,46 +13,46 @@ const iconData = {
describe('Rotation', () => { describe('Rotation', () => {
test('number', () => { test('number', () => {
const component = render(Icon, { icon: iconData, rotate: 1 }); const component = render(Icon, { icon: iconData, rotate: 1 });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual('rotate(90 16 16)'); expect(child.getAttribute('transform')).toBe('rotate(90 16 16)');
}); });
test('string', () => { test('string', () => {
const component = render(Icon, { icon: iconData, rotate: '180deg' }); const component = render(Icon, { icon: iconData, rotate: '180deg' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); expect(child.getAttribute('transform')).toBe('rotate(180 12 16)');
}); });
}); });
describe('Flip', () => { describe('Flip', () => {
test('boolean', () => { test('boolean', () => {
const component = render(Icon, { icon: iconData, hFlip: true }); const component = render(Icon, { icon: iconData, hFlip: true });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(24 0) scale(-1 1)' 'translate(24 0) scale(-1 1)'
); );
}); });
test('string', () => { test('string', () => {
const component = render(Icon, { icon: iconData, flip: 'vertical' }); const component = render(Icon, { icon: iconData, flip: 'vertical' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(0 32) scale(1 -1)' 'translate(0 32) scale(1 -1)'
); );
}); });
@ -60,13 +63,13 @@ describe('Flip', () => {
flip: 'horizontal', flip: 'horizontal',
vFlip: true, vFlip: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
// horizontal + vertical = 180deg rotation // horizontal + vertical = 180deg rotation
expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); expect(child.getAttribute('transform')).toBe('rotate(180 12 16)');
}); });
test('string for boolean attribute', () => { test('string for boolean attribute', () => {
@ -74,12 +77,12 @@ describe('Flip', () => {
icon: iconData, icon: iconData,
hFlip: 'true', hFlip: 'true',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(24 0) scale(-1 1)' 'translate(24 0) scale(-1 1)'
); );
}); });
@ -91,12 +94,12 @@ describe('Flip', () => {
hFlip: false, hFlip: false,
flip: 'horizontal', flip: 'horizontal',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(24 0) scale(-1 1)' 'translate(24 0) scale(-1 1)'
); );
}); });
@ -107,12 +110,12 @@ describe('Flip', () => {
flip: 'vertical', flip: 'vertical',
hFlip: true, hFlip: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); expect(child.getAttribute('transform')).toBe('rotate(180 12 16)');
}); });
test('wrong case', () => { test('wrong case', () => {
@ -120,11 +123,11 @@ describe('Flip', () => {
icon: iconData, icon: iconData,
vflip: true, vflip: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('path'); expect(child.tagName).toBe('path');
}); });
}); });
@ -135,11 +138,9 @@ describe('Alignment and slice', () => {
vAlign: 'top', vAlign: 'top',
slice: true, slice: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('preserveAspectRatio')).toEqual( expect(node.getAttribute('preserveAspectRatio')).toBe('xMidYMin slice');
'xMidYMin slice'
);
}); });
test('string', () => { test('string', () => {
@ -147,10 +148,8 @@ describe('Alignment and slice', () => {
icon: iconData, icon: iconData,
align: 'left bottom', align: 'left bottom',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('preserveAspectRatio')).toEqual( expect(node.getAttribute('preserveAspectRatio')).toBe('xMinYMax meet');
'xMinYMax meet'
);
}); });
}); });

View File

@ -1,5 +1,10 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/offline';
// Test importing from exports
import Icon from '../../offline';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -10,22 +15,20 @@ const iconData = {
describe('Creating component', () => { describe('Creating component', () => {
test('basic icon', () => { test('basic icon', () => {
const component = render(Icon, { icon: iconData }); const component = render(Icon, { icon: iconData });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; const html = (node.parentNode as HTMLDivElement).innerHTML;
// Check HTML // Check HTML
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>' '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
); );
// Make sure getAttribute() works, used in other tests // Make sure getAttribute() works, used in other tests
expect(node.getAttribute('xmlns')).toEqual( expect(node.getAttribute('xmlns')).toBe('http://www.w3.org/2000/svg');
'http://www.w3.org/2000/svg' expect(node.getAttribute('aria-hidden')).toBe('true');
);
expect(node.getAttribute('aria-hidden')).toEqual('true');
// Make sure style exists // Make sure style exists
const style = node.style; const style = node.style;
expect(typeof style).toEqual('object'); expect(typeof style).toBe('object');
}); });
}); });

View File

@ -1,4 +1,9 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
// Test importing from offline.mjs
import Icon from '../../dist/offline'; import Icon from '../../dist/offline';
describe('Empty icon', () => { describe('Empty icon', () => {
@ -7,6 +12,6 @@ describe('Empty icon', () => {
const html = component.container.innerHTML; const html = component.container.innerHTML;
// Empty container div // Empty container div
expect(html).toEqual('<div></div>'); expect(html).toBe('<div></div>');
}); });
}); });

View File

@ -1,3 +1,6 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/offline'; import Icon from '../../dist/offline';
@ -10,8 +13,8 @@ const iconData = {
describe('Padding attributes', () => { describe('Padding attributes', () => {
test('title', () => { test('title', () => {
const component = render(Icon, { icon: iconData, title: 'Icon!' }); const component = render(Icon, { icon: iconData, title: 'Icon!' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('title')).toEqual('Icon!'); expect(node.getAttribute('title')).toBe('Icon!');
}); });
test('aria-hidden', () => { test('aria-hidden', () => {
@ -20,8 +23,8 @@ describe('Padding attributes', () => {
'icon': iconData, 'icon': iconData,
'aria-hidden': 'false', 'aria-hidden': 'false',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('aria-hidden')).toEqual(null); expect(node.getAttribute('aria-hidden')).toBeNull();
}); });
test('ariaHidden', () => { test('ariaHidden', () => {
@ -30,8 +33,8 @@ describe('Padding attributes', () => {
icon: iconData, icon: iconData,
ariaHidden: false, ariaHidden: false,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('aria-hidden')).toEqual(null); expect(node.getAttribute('aria-hidden')).toBeNull();
}); });
test('style', () => { test('style', () => {
@ -39,9 +42,9 @@ describe('Padding attributes', () => {
icon: iconData, icon: iconData,
style: 'vertical-align: 0; color: red;', style: 'vertical-align: 0; color: red;',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.style.verticalAlign).toEqual('0'); expect(node.style.verticalAlign).toBe('0');
expect(node.style.color).toEqual('red'); expect(node.style.color).toBe('red');
}); });
test('color', () => { test('color', () => {
@ -49,8 +52,8 @@ describe('Padding attributes', () => {
icon: iconData, icon: iconData,
color: 'red', color: 'red',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.style.color).toEqual('red'); expect(node.style.color).toBe('red');
}); });
test('color with style', () => { test('color with style', () => {
@ -59,8 +62,8 @@ describe('Padding attributes', () => {
color: 'red', color: 'red',
style: 'color: green;', style: 'color: green;',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.style.color).toEqual('red'); expect(node.style.color).toBe('red');
}); });
test('attributes that cannot change', () => { test('attributes that cannot change', () => {
@ -69,10 +72,8 @@ describe('Padding attributes', () => {
viewBox: '0 0 0 0', viewBox: '0 0 0 0',
preserveAspectRatio: 'none', preserveAspectRatio: 'none',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('viewBox')).toEqual('0 0 24 24'); expect(node.getAttribute('viewBox')).toBe('0 0 24 24');
expect(node.getAttribute('preserveAspectRatio')).toEqual( expect(node.getAttribute('preserveAspectRatio')).toBe('xMidYMid meet');
'xMidYMid meet'
);
}); });
}); });

View File

@ -1,3 +1,6 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/offline'; import Icon from '../../dist/offline';
@ -10,9 +13,9 @@ const iconData = {
describe('Dimensions', () => { describe('Dimensions', () => {
test('height', () => { test('height', () => {
const component = render(Icon, { icon: iconData, height: '48' }); const component = render(Icon, { icon: iconData, height: '48' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('48'); expect(node.getAttribute('height')).toBe('48');
expect(node.getAttribute('width')).toEqual('48'); expect(node.getAttribute('width')).toBe('48');
}); });
test('width and height', () => { test('width and height', () => {
@ -22,9 +25,9 @@ describe('Dimensions', () => {
width: 32, width: 32,
height: '48', height: '48',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('48'); expect(node.getAttribute('height')).toBe('48');
expect(node.getAttribute('width')).toEqual('32'); expect(node.getAttribute('width')).toBe('32');
}); });
test('auto', () => { test('auto', () => {
@ -32,8 +35,8 @@ describe('Dimensions', () => {
icon: iconData, icon: iconData,
height: 'auto', height: 'auto',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('height')).toEqual('24'); expect(node.getAttribute('height')).toBe('24');
expect(node.getAttribute('width')).toEqual('24'); expect(node.getAttribute('width')).toBe('24');
}); });
}); });

View File

@ -1,3 +1,6 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/offline'; import Icon from '../../dist/offline';
@ -10,7 +13,7 @@ const iconDataWithID = {
describe('Replacing IDs', () => { describe('Replacing IDs', () => {
test('default behavior', () => { test('default behavior', () => {
const component = render(Icon, { icon: iconDataWithID }); const component = render(Icon, { icon: iconDataWithID });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Check that default id doesn't exist // Check that default id doesn't exist
const path = node.getElementById('ssvg-id-1st-place-medala'); const path = node.getElementById('ssvg-id-1st-place-medala');
@ -19,7 +22,7 @@ describe('Replacing IDs', () => {
test('custom generator', () => { test('custom generator', () => {
const component = render(Icon, { icon: iconDataWithID, id: 'test' }); const component = render(Icon, { icon: iconDataWithID, id: 'test' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Check that ID 'testa' exists // Check that ID 'testa' exists
const path = node.getElementById('test-0'); const path = node.getElementById('test-0');

View File

@ -1,5 +1,8 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/offline'; import Icon from '../../offline';
const iconData = { const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>', body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -10,34 +13,34 @@ const iconData = {
describe('Inline attribute', () => { describe('Inline attribute', () => {
test('boolean true', () => { test('boolean true', () => {
const component = render(Icon, { icon: iconData, inline: true }); const component = render(Icon, { icon: iconData, inline: true });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual('-0.125em'); expect(style.verticalAlign).toBe('-0.125em');
}); });
test('string true', () => { test('string true', () => {
const component = render(Icon, { icon: iconData, inline: 'true' }); const component = render(Icon, { icon: iconData, inline: 'true' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual('-0.125em'); expect(style.verticalAlign).toBe('-0.125em');
}); });
test('false', () => { test('false', () => {
const component = render(Icon, { icon: iconData, inline: false }); const component = render(Icon, { icon: iconData, inline: false });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual(''); expect(style.verticalAlign).toBe('');
}); });
test('false string', () => { test('false string', () => {
// "false" should be ignored // "false" should be ignored
const component = render(Icon, { icon: iconData, inline: 'false' }); const component = render(Icon, { icon: iconData, inline: 'false' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const style = node.style; const style = node.style;
expect(style.verticalAlign).toEqual(''); expect(style.verticalAlign).toBe('');
}); });
}); });

View File

@ -1,3 +1,6 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon, { addIcon, addCollection } from '../../dist/offline'; import Icon, { addIcon, addCollection } from '../../dist/offline';
@ -12,10 +15,10 @@ describe('Using storage', () => {
addIcon('test-icon', iconData); addIcon('test-icon', iconData);
const component = render(Icon, { icon: 'test-icon' }); const component = render(Icon, { icon: 'test-icon' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; const html = (node.parentNode as HTMLDivElement).innerHTML;
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>' '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>'
); );
}); });
@ -38,10 +41,10 @@ describe('Using storage', () => {
addCollection(iconSet); addCollection(iconSet);
const component = render(Icon, { icon: 'mdi-light:account' }); const component = render(Icon, { icon: 'mdi-light:account' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; const html = (node.parentNode as HTMLDivElement).innerHTML;
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M11.5 14c4.142 0 7.5 1.567 7.5 3.5V20H4v-2.5c0-1.933 3.358-3.5 7.5-3.5zm6.5 3.5c0-1.38-2.91-2.5-6.5-2.5S5 16.12 5 17.5V19h13v-1.5zM11.5 5a3.5 3.5 0 1 1 0 7a3.5 3.5 0 0 1 0-7zm0 1a2.5 2.5 0 1 0 0 5a2.5 2.5 0 0 0 0-5z" fill="currentColor"></path></svg>' '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M11.5 14c4.142 0 7.5 1.567 7.5 3.5V20H4v-2.5c0-1.933 3.358-3.5 7.5-3.5zm6.5 3.5c0-1.38-2.91-2.5-6.5-2.5S5 16.12 5 17.5V19h13v-1.5zM11.5 5a3.5 3.5 0 1 1 0 7a3.5 3.5 0 0 1 0-7zm0 1a2.5 2.5 0 1 0 0 5a2.5 2.5 0 0 0 0-5z" fill="currentColor"></path></svg>'
); );
}); });
@ -64,10 +67,10 @@ describe('Using storage', () => {
addCollection(iconSet, 'custom-'); addCollection(iconSet, 'custom-');
const component = render(Icon, { icon: 'custom-link' }); const component = render(Icon, { icon: 'custom-link' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
const html = node.parentNode.innerHTML; const html = (node.parentNode as HTMLDivElement).innerHTML;
expect(html).toEqual( expect(html).toBe(
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M8 13v-1h7v1H8zm7.5-6a5.5 5.5 0 1 1 0 11H13v-1h2.5a4.5 4.5 0 1 0 0-9H13V7h2.5zm-8 11a5.5 5.5 0 1 1 0-11H10v1H7.5a4.5 4.5 0 1 0 0 9H10v1H7.5z" fill="currentColor"></path></svg>' '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M8 13v-1h7v1H8zm7.5-6a5.5 5.5 0 1 1 0 11H13v-1h2.5a4.5 4.5 0 1 0 0-9H13V7h2.5zm-8 11a5.5 5.5 0 1 1 0-11H10v1H7.5a4.5 4.5 0 1 0 0 9H10v1H7.5z" fill="currentColor"></path></svg>'
); );
}); });
@ -79,6 +82,6 @@ describe('Using storage', () => {
const html = component.container.innerHTML; const html = component.container.innerHTML;
// Empty container div // Empty container div
expect(html).toEqual('<div></div>'); expect(html).toBe('<div></div>');
}); });
}); });

View File

@ -1,3 +1,6 @@
/**
* @jest-environment jsdom
*/
import { render } from '@testing-library/svelte'; import { render } from '@testing-library/svelte';
import Icon from '../../dist/offline'; import Icon from '../../dist/offline';
@ -10,46 +13,46 @@ const iconData = {
describe('Rotation', () => { describe('Rotation', () => {
test('number', () => { test('number', () => {
const component = render(Icon, { icon: iconData, rotate: 1 }); const component = render(Icon, { icon: iconData, rotate: 1 });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual('rotate(90 16 16)'); expect(child.getAttribute('transform')).toBe('rotate(90 16 16)');
}); });
test('string', () => { test('string', () => {
const component = render(Icon, { icon: iconData, rotate: '180deg' }); const component = render(Icon, { icon: iconData, rotate: '180deg' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); expect(child.getAttribute('transform')).toBe('rotate(180 12 16)');
}); });
}); });
describe('Flip', () => { describe('Flip', () => {
test('boolean', () => { test('boolean', () => {
const component = render(Icon, { icon: iconData, hFlip: true }); const component = render(Icon, { icon: iconData, hFlip: true });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(24 0) scale(-1 1)' 'translate(24 0) scale(-1 1)'
); );
}); });
test('string', () => { test('string', () => {
const component = render(Icon, { icon: iconData, flip: 'vertical' }); const component = render(Icon, { icon: iconData, flip: 'vertical' });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(0 32) scale(1 -1)' 'translate(0 32) scale(1 -1)'
); );
}); });
@ -60,13 +63,13 @@ describe('Flip', () => {
flip: 'horizontal', flip: 'horizontal',
vFlip: true, vFlip: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
// horizontal + vertical = 180deg rotation // horizontal + vertical = 180deg rotation
expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); expect(child.getAttribute('transform')).toBe('rotate(180 12 16)');
}); });
test('string for boolean attribute', () => { test('string for boolean attribute', () => {
@ -74,12 +77,12 @@ describe('Flip', () => {
icon: iconData, icon: iconData,
hFlip: 'true', hFlip: 'true',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(24 0) scale(-1 1)' 'translate(24 0) scale(-1 1)'
); );
}); });
@ -91,12 +94,12 @@ describe('Flip', () => {
hFlip: false, hFlip: false,
flip: 'horizontal', flip: 'horizontal',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual( expect(child.getAttribute('transform')).toBe(
'translate(24 0) scale(-1 1)' 'translate(24 0) scale(-1 1)'
); );
}); });
@ -107,12 +110,12 @@ describe('Flip', () => {
flip: 'vertical', flip: 'vertical',
hFlip: true, hFlip: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('g'); expect(child.tagName).toBe('g');
expect(child.getAttribute('transform')).toEqual('rotate(180 12 16)'); expect(child.getAttribute('transform')).toBe('rotate(180 12 16)');
}); });
test('wrong case', () => { test('wrong case', () => {
@ -120,11 +123,11 @@ describe('Flip', () => {
icon: iconData, icon: iconData,
vflip: true, vflip: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
// Find first child node // Find first child node
const child = node.childNodes[0]; const child = node.childNodes[0] as SVGGElement;
expect(child.tagName).toEqual('path'); expect(child.tagName).toBe('path');
}); });
}); });
@ -135,11 +138,9 @@ describe('Alignment and slice', () => {
vAlign: 'top', vAlign: 'top',
slice: true, slice: true,
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('preserveAspectRatio')).toEqual( expect(node.getAttribute('preserveAspectRatio')).toBe('xMidYMin slice');
'xMidYMin slice'
);
}); });
test('string', () => { test('string', () => {
@ -147,10 +148,8 @@ describe('Alignment and slice', () => {
icon: iconData, icon: iconData,
align: 'left bottom', align: 'left bottom',
}); });
const node = component.container.querySelector('svg'); const node = component.container.querySelector('svg')!;
expect(node.getAttribute('preserveAspectRatio')).toEqual( expect(node.getAttribute('preserveAspectRatio')).toBe('xMinYMax meet');
'xMinYMax meet'
);
}); });
}); });

View File

@ -0,0 +1,9 @@
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"types": ["node", "jest"],
"rootDir": ".",
"outDir": "../lib",
"module": "CommonJS"
}
}

View File

@ -0,0 +1,17 @@
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
"target": "esnext",
"module": "esnext",
"declaration": true,
"sourceMap": false,
"strict": true,
"types": ["node", "svelte"],
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"importsNotUsedAsValues": "error"
}
}

View File

@ -1,17 +1,8 @@
{ {
"extends": "./tsconfig-base.json",
"include": ["src/**/*.ts", ".eslintrc.js"],
"compilerOptions": { "compilerOptions": {
"rootDir": "src", "rootDir": "./src",
"outDir": "lib", "outDir": "./lib"
"target": "es2017",
"module": "esnext",
"declaration": true,
"sourceMap": false,
"strict": true,
"types": ["node", "svelte"],
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"importsNotUsedAsValues": "error"
} }
} }