convert scripts to esm (#6946)

* convert scripts to esm

* fix tests

* fix tests

* fix lints

* syncFs to fsSync

* named export for fs

Co-authored-by: LitoMore <LitoMore@users.noreply.github.com>

* fsSync to { promises as fs }

* convert update-svgs-count to esm

* rename data to icons

* fix build script

* switch svglintrc file to mjs

* use node: protocol

* pluralize getIcons

Co-authored-by: LitoMore <LitoMore@users.noreply.github.com>
This commit is contained in:
Sachin Raja 2021-12-25 06:22:56 -08:00 committed by GitHub
parent 0150cbd986
commit a930dc57ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 319 additions and 226 deletions

View File

@ -1,11 +1,28 @@
const fs = require('fs'); import fs from 'node:fs';
import path from 'node:path';
import {
getDirnameFromImportMeta,
htmlFriendlyToTitle,
} from './scripts/utils.js';
import svgpath from 'svgpath';
import svgPathBbox from 'svg-path-bbox';
import parsePath from 'svg-path-segments';
const data = require('./_data/simple-icons.json'); const __dirname = getDirnameFromImportMeta(import.meta.url);
const { htmlFriendlyToTitle } = require('./scripts/utils.js'); const dataFile = path.join(__dirname, '_data', 'simple-icons.json');
const htmlNamedEntities = require('named-html-entities-json'); const htmlNamedEntitiesFile = path.join(
const svgpath = require('svgpath'); __dirname,
const svgPathBbox = require('svg-path-bbox'); 'node_modules',
const parsePath = require('svg-path-segments'); 'named-html-entities-json',
'index.json',
);
const svglintIgnoredFile = path.join(__dirname, '.svglint-ignored.json');
const data = JSON.parse(fs.readFileSync(dataFile, 'utf8'));
const htmlNamedEntities = JSON.parse(
fs.readFileSync(htmlNamedEntitiesFile, 'utf8'),
);
const svglintIgnores = JSON.parse(fs.readFileSync(svglintIgnoredFile, 'utf8'));
const svgRegexp = const svgRegexp =
/^<svg( [^\s]*=".*"){3}><title>.*<\/title><path d=".*"\/><\/svg>\n?$/; /^<svg( [^\s]*=".*"){3}><title>.*<\/title><path d=".*"\/><\/svg>\n?$/;
@ -19,7 +36,7 @@ const iconTolerance = 0.001;
// set env SI_UPDATE_IGNORE to recreate the ignore file // set env SI_UPDATE_IGNORE to recreate the ignore file
const updateIgnoreFile = process.env.SI_UPDATE_IGNORE === 'true'; const updateIgnoreFile = process.env.SI_UPDATE_IGNORE === 'true';
const ignoreFile = './.svglint-ignored.json'; const ignoreFile = './.svglint-ignored.json';
const iconIgnored = !updateIgnoreFile ? require(ignoreFile) : {}; const iconIgnored = !updateIgnoreFile ? svglintIgnores : {};
const sortObjectByKey = (obj) => { const sortObjectByKey = (obj) => {
return Object.keys(obj) return Object.keys(obj)
@ -126,7 +143,7 @@ const ignoreIcon = (linterName, path, $) => {
iconIgnored[linterName][path] = iconName; iconIgnored[linterName][path] = iconName;
}; };
module.exports = { export default {
rules: { rules: {
elm: { elm: {
svg: 1, svg: 1,

View File

@ -56,12 +56,12 @@
"our-lint": "node scripts/lint/ourlint.js", "our-lint": "node scripts/lint/ourlint.js",
"jslint": "prettier --check .", "jslint": "prettier --check .",
"jsonlint": "node scripts/lint/jsonlint.js", "jsonlint": "node scripts/lint/jsonlint.js",
"svglint": "svglint icons/*.svg --ci", "svglint": "svglint icons/*.svg --ci --config .svglintrc.mjs",
"wslint": "editorconfig-checker", "wslint": "editorconfig-checker",
"prepare": "is-ci || husky install", "prepare": "is-ci || husky install",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
"postpublish": "npm run clean", "postpublish": "npm run clean",
"test": "node --experimental-specifier-resolution=node node_modules/uvu/bin.js", "test": "uvu",
"pretest": "npm run prepublishOnly", "pretest": "npm run prepublishOnly",
"posttest": "npm run postpublish", "posttest": "npm run postpublish",
"svgo": "svgo --config svgo.config.js", "svgo": "svgo --config svgo.config.js",

View File

@ -7,15 +7,24 @@
* tree-shakeable * tree-shakeable
*/ */
const fs = require('fs').promises; import { promises as fs } from 'node:fs';
const path = require('path'); import path from 'node:path';
const util = require('util'); import util from 'node:util';
const { transform: esbuildTransform } = require('esbuild'); import { transform as esbuildTransform } from 'esbuild';
import {
getIconSlug,
svgToPath,
titleToHtmlFriendly,
slugToVariableName,
getIconsData,
getDirnameFromImportMeta,
} from '../utils.js';
const __dirname = getDirnameFromImportMeta(import.meta.url);
const UTF8 = 'utf8'; const UTF8 = 'utf8';
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
const indexFile = path.resolve(rootDir, 'index.js'); const indexFile = path.resolve(rootDir, 'index.js');
const iconsDir = path.resolve(rootDir, 'icons'); const iconsDir = path.resolve(rootDir, 'icons');
const iconsJsFile = path.resolve(rootDir, 'icons.js'); const iconsJsFile = path.resolve(rootDir, 'icons.js');
@ -26,15 +35,8 @@ const templatesDir = path.resolve(__dirname, 'templates');
const indexTemplateFile = path.resolve(templatesDir, 'index.js'); const indexTemplateFile = path.resolve(templatesDir, 'index.js');
const iconObjectTemplateFile = path.resolve(templatesDir, 'icon-object.js'); const iconObjectTemplateFile = path.resolve(templatesDir, 'icon-object.js');
const data = require(dataFile);
const {
getIconSlug,
svgToPath,
titleToHtmlFriendly,
slugToVariableName,
} = require('../utils.js');
const build = async () => { const build = async () => {
const icons = await getIconsData();
const indexTemplate = await fs.readFile(indexTemplateFile, UTF8); const indexTemplate = await fs.readFile(indexTemplateFile, UTF8);
const iconObjectTemplate = await fs.readFile(iconObjectTemplateFile, UTF8); const iconObjectTemplate = await fs.readFile(iconObjectTemplateFile, UTF8);
@ -82,16 +84,16 @@ const build = async () => {
const iconsBarrelMjs = []; const iconsBarrelMjs = [];
const iconsBarrelJs = []; const iconsBarrelJs = [];
const iconsBarrelDts = []; const iconsBarrelDts = [];
const icons = []; const buildIcons = [];
await Promise.all( await Promise.all(
data.icons.map(async (icon) => { icons.map(async (icon) => {
const filename = getIconSlug(icon); const filename = getIconSlug(icon);
const svgFilepath = path.resolve(iconsDir, `${filename}.svg`); const svgFilepath = path.resolve(iconsDir, `${filename}.svg`);
icon.svg = (await fs.readFile(svgFilepath, UTF8)).replace(/\r?\n/, ''); icon.svg = (await fs.readFile(svgFilepath, UTF8)).replace(/\r?\n/, '');
icon.path = svgToPath(icon.svg); icon.path = svgToPath(icon.svg);
icon.slug = filename; icon.slug = filename;
icons.push(icon); buildIcons.push(icon);
const iconObject = iconToObject(icon); const iconObject = iconToObject(icon);
@ -126,7 +128,7 @@ const build = async () => {
// write our generic index.js // write our generic index.js
const rawIndexJs = util.format( const rawIndexJs = util.format(
indexTemplate, indexTemplate,
icons.map(iconToKeyValue).join(','), buildIcons.map(iconToKeyValue).join(','),
); );
await writeJs(indexFile, rawIndexJs); await writeJs(indexFile, rawIndexJs);

View File

@ -5,7 +5,7 @@
* icon SVG filename to standard output. * icon SVG filename to standard output.
*/ */
const { titleToSlug } = require('./utils.js'); import { titleToSlug } from './utils.js';
if (process.argv.length < 3) { if (process.argv.length < 3) {
console.error('Provide a brand name as argument'); console.error('Provide a brand name as argument');

View File

@ -4,23 +4,30 @@
* CLI tool to run jsonschema on the simple-icons.json data file. * CLI tool to run jsonschema on the simple-icons.json data file.
*/ */
const path = require('path'); import { promises as fs } from 'node:fs';
const { Validator } = require('jsonschema'); import path from 'node:path';
import { Validator } from 'jsonschema';
import { getDirnameFromImportMeta, getIconsData } from '../utils.js';
const __dirname = getDirnameFromImportMeta(import.meta.url);
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const schemaFile = path.resolve(rootDir, '.jsonschema.json'); const schemaFile = path.resolve(rootDir, '.jsonschema.json');
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
const schema = require(schemaFile); (async () => {
const data = require(dataFile); const icons = await getIconsData();
const schema = JSON.parse(await fs.readFile(schemaFile, 'utf8'));
const validator = new Validator(); const validator = new Validator();
const result = validator.validate(data, schema); const result = validator.validate({ icons }, schema);
if (result.errors.length > 0) { if (result.errors.length > 0) {
result.errors.forEach((error) => { result.errors.forEach((error) => {
console.error(error); console.error(error);
}); });
console.error(`Found ${result.errors.length} error(s) in simple-icons.json`); console.error(
process.exit(1); `Found ${result.errors.length} error(s) in simple-icons.json`,
} );
process.exit(1);
}
})();

View File

@ -5,16 +5,8 @@
* linters (e.g. jsonlint/svglint). * linters (e.g. jsonlint/svglint).
*/ */
const fs = require('fs'); import fakeDiff from 'fake-diff';
const path = require('path'); import { getIconsDataString } from '../utils.js';
const fakeDiff = require('fake-diff');
const UTF8 = 'utf8';
const rootDir = path.resolve(__dirname, '..', '..');
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
const data = require(dataFile);
/** /**
* Contains our tests so they can be isolated from each other. * Contains our tests so they can be isolated from each other.
@ -22,7 +14,7 @@ const data = require(dataFile);
*/ */
const TESTS = { const TESTS = {
/* Tests whether our icons are in alphabetical order */ /* Tests whether our icons are in alphabetical order */
alphabetical: () => { alphabetical: (data) => {
const collector = (invalidEntries, icon, index, array) => { const collector = (invalidEntries, icon, index, array) => {
if (index > 0) { if (index > 0) {
const prev = array[index - 1]; const prev = array[index - 1];
@ -54,22 +46,30 @@ const TESTS = {
}, },
/* Check the formatting of the data file */ /* Check the formatting of the data file */
prettified: () => { prettified: async (data, dataString) => {
const dataString = fs.readFileSync(dataFile, UTF8).replace(/\r\n/g, '\n'); const normalizedDataString = dataString.replace(/\r\n/g, '\n');
const dataPretty = `${JSON.stringify(data, null, ' ')}\n`; const dataPretty = `${JSON.stringify(data, null, ' ')}\n`;
if (dataString !== dataPretty) {
const dataDiff = fakeDiff(dataString, dataPretty); if (normalizedDataString !== dataPretty) {
const dataDiff = fakeDiff(normalizedDataString, dataPretty);
return `Data file is formatted incorrectly:\n\n${dataDiff}`; return `Data file is formatted incorrectly:\n\n${dataDiff}`;
} }
}, },
}; };
// execute all tests and log all errors // execute all tests and log all errors
const errors = Object.keys(TESTS) (async () => {
.map((k) => TESTS[k]()) const dataString = await getIconsDataString();
.filter(Boolean); const data = JSON.parse(dataString);
if (errors.length > 0) { const errors = (
errors.forEach((error) => console.error(`\u001b[31m${error}\u001b[0m`)); await Promise.all(
process.exit(1); Object.keys(TESTS).map((test) => TESTS[test](data, dataString)),
} )
).filter(Boolean);
if (errors.length > 0) {
errors.forEach((error) => console.error(`\u001b[31m${error}\u001b[0m`));
process.exit(1);
}
})();

3
scripts/package.json Normal file
View File

@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@ -4,8 +4,11 @@
* Updates the version of this package to the CLI specified version. * Updates the version of this package to the CLI specified version.
*/ */
const fs = require('fs'); import fs from 'node:fs';
const path = require('path'); import path from 'node:path';
import { getDirnameFromImportMeta } from '../utils.js';
const __dirname = getDirnameFromImportMeta(import.meta.url);
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const packageJsonFile = path.resolve(rootDir, 'package.json'); const packageJsonFile = path.resolve(rootDir, 'package.json');

View File

@ -5,8 +5,11 @@
* NPM package manifest. Does nothing if the README.md is already up-to-date. * NPM package manifest. Does nothing if the README.md is already up-to-date.
*/ */
const fs = require('fs'); import fs from 'node:fs';
const path = require('path'); import path from 'node:path';
import { getDirnameFromImportMeta } from '../utils.js';
const __dirname = getDirnameFromImportMeta(import.meta.url);
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const packageJsonFile = path.resolve(rootDir, 'package.json'); const packageJsonFile = path.resolve(rootDir, 'package.json');

View File

@ -4,16 +4,17 @@
* Generates a MarkDown file that lists every brand name and their slug. * Generates a MarkDown file that lists every brand name and their slug.
*/ */
const fs = require('fs'); import { promises as fs } from 'node:fs';
const path = require('path'); import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { getIconsData, getIconSlug } from '../utils.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
const slugsFile = path.resolve(rootDir, 'slugs.md'); const slugsFile = path.resolve(rootDir, 'slugs.md');
const data = require(dataFile);
const { getIconSlug } = require('../utils.js');
let content = `<!-- let content = `<!--
This file is automatically generated. If you want to change something, please This file is automatically generated. If you want to change something, please
update the script at '${path.relative(rootDir, __filename)}'. update the script at '${path.relative(rootDir, __filename)}'.
@ -25,10 +26,14 @@ update the script at '${path.relative(rootDir, __filename)}'.
| :--- | :--- | | :--- | :--- |
`; `;
data.icons.forEach((icon) => { (async () => {
const brandName = icon.title; const icons = await getIconsData();
const brandSlug = getIconSlug(icon);
content += `| \`${brandName}\` | \`${brandSlug}\` |\n`;
});
fs.writeFileSync(slugsFile, content); icons.forEach((icon) => {
const brandName = icon.title;
const brandSlug = getIconSlug(icon);
content += `| \`${brandName}\` | \`${brandSlug}\` |\n`;
});
await fs.writeFile(slugsFile, content);
})();

View File

@ -5,34 +5,39 @@
* at README every time the number of current icons is more than `updateRange` * at README every time the number of current icons is more than `updateRange`
* more than the previous milestone. * more than the previous milestone.
*/ */
import { promises as fs } from 'node:fs';
const fs = require('fs'); import path from 'node:path';
const path = require('path'); import { getDirnameFromImportMeta, getIconsData } from '../utils.js';
const regexMatcher = /Over\s(\d+)\s/; const regexMatcher = /Over\s(\d+)\s/;
const updateRange = 100; const updateRange = 100;
const __dirname = getDirnameFromImportMeta(import.meta.url);
const rootDir = path.resolve(__dirname, '..', '..'); const rootDir = path.resolve(__dirname, '..', '..');
const dataFile = path.resolve(rootDir, '_data', 'simple-icons.json');
const readmeFile = path.resolve(rootDir, 'README.md'); const readmeFile = path.resolve(rootDir, 'README.md');
const readmeContent = fs.readFileSync(readmeFile, 'utf-8');
let overNIconsInReadme; (async () => {
try { const readmeContent = await fs.readFile(readmeFile, 'utf-8');
overNIconsInReadme = parseInt(regexMatcher.exec(readmeContent)[1]);
} catch (err) {
console.error(
'Failed to obtain number of SVG icons of current milestone in README:',
err,
);
process.exit(1);
}
const nIcons = require(dataFile).icons.length, let overNIconsInReadme;
newNIcons = overNIconsInReadme + updateRange; try {
if (nIcons <= newNIcons) { overNIconsInReadme = parseInt(regexMatcher.exec(readmeContent)[1]);
process.exit(0); } catch (err) {
} console.error(
'Failed to obtain number of SVG icons of current milestone in README:',
err,
);
process.exit(1);
}
const newContent = readmeContent.replace(regexMatcher, `Over ${newNIcons} `); const nIcons = (await getIconsData()).length;
fs.writeFileSync(readmeFile, newContent); const newNIcons = overNIconsInReadme + updateRange;
if (nIcons <= newNIcons) {
process.exit(0);
}
const newContent = readmeContent.replace(regexMatcher, `Over ${newNIcons} `);
await fs.writeFile(readmeFile, newContent);
})();

View File

@ -3,76 +3,103 @@
* Some common utilities for scripts. * Some common utilities for scripts.
*/ */
module.exports = { import path from 'node:path';
/** import { promises as fs } from 'node:fs';
* Get the slug/filename for an icon. import { fileURLToPath } from 'node:url';
* @param {Object} icon The icon data as it appears in _data/simple-icons.json
*/
getIconSlug: (icon) => icon.slug || module.exports.titleToSlug(icon.title),
/** /**
* Extract the path from an icon SVG content. * Get the slug/filename for an icon.
* @param {Object} svg The icon SVG content * @param {Object} icon The icon data as it appears in _data/simple-icons.json
**/ */
svgToPath: (svg) => svg.match(/<path\s+d="([^"]*)/)[1], export const getIconSlug = (icon) => icon.slug || titleToSlug(icon.title);
/** /**
* Converts a brand title into a slug/filename. * Extract the path from an icon SVG content.
* @param {String} title The title to convert * @param {Object} svg The icon SVG content
*/ **/
titleToSlug: (title) => export const svgToPath = (svg) => svg.match(/<path\s+d="([^"]*)/)[1];
title
.toLowerCase()
.replace(/\+/g, 'plus')
.replace(/\./g, 'dot')
.replace(/&/g, 'and')
.replace(/đ/g, 'd')
.replace(/ħ/g, 'h')
.replace(/ı/g, 'i')
.replace(/ĸ/g, 'k')
.replace(/ŀ/g, 'l')
.replace(/ł/g, 'l')
.replace(/ß/g, 'ss')
.replace(/ŧ/g, 't')
.normalize('NFD')
.replace(/[^a-z0-9]/g, ''),
/** /**
* Converts a brand title in HTML/SVG friendly format into a brand title (as * Converts a brand title into a slug/filename.
* it is seen in simple-icons.json) * @param {String} title The title to convert
* @param {String} htmlFriendlyTitle The title to convert */
*/ export const titleToSlug = (title) =>
htmlFriendlyToTitle: (htmlFriendlyTitle) => title
htmlFriendlyTitle .toLowerCase()
.replace(/&#([0-9]+);/g, (_, num) => String.fromCharCode(parseInt(num))) .replace(/\+/g, 'plus')
.replace( .replace(/\./g, 'dot')
/&(quot|amp|lt|gt);/g, .replace(/&/g, 'and')
(_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' }[ref]), .replace(/đ/g, 'd')
), .replace(/ħ/g, 'h')
.replace(/ı/g, 'i')
.replace(/ĸ/g, 'k')
.replace(/ŀ/g, 'l')
.replace(/ł/g, 'l')
.replace(/ß/g, 'ss')
.replace(/ŧ/g, 't')
.normalize('NFD')
.replace(/[^a-z0-9]/g, '');
/** /**
* Converts a slug into a variable name that can be exported. * Converts a slug into a variable name that can be exported.
* @param {String} slug The slug to convert * @param {String} slug The slug to convert
*/ */
slugToVariableName: (slug) => { export const slugToVariableName = (slug) => {
const slugFirstLetter = slug[0].toUpperCase(); const slugFirstLetter = slug[0].toUpperCase();
const slugRest = slug.slice(1); const slugRest = slug.slice(1);
return `si${slugFirstLetter}${slugRest}`; return `si${slugFirstLetter}${slugRest}`;
},
/**
* Converts a brand title (as it is seen in simple-icons.json) into a brand
* title in HTML/SVG friendly format.
* @param {String} brandTitle The title to convert
*/
titleToHtmlFriendly: (brandTitle) =>
brandTitle
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/./g, (char) => {
const charCode = char.charCodeAt(0);
return charCode > 127 ? `&#${charCode};` : char;
}),
}; };
/**
* Converts a brand title (as it is seen in simple-icons.json) into a brand
* title in HTML/SVG friendly format.
* @param {String} brandTitle The title to convert
*/
export const titleToHtmlFriendly = (brandTitle) =>
brandTitle
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/./g, (char) => {
const charCode = char.charCodeAt(0);
return charCode > 127 ? `&#${charCode};` : char;
});
/**
* Converts a brand title in HTML/SVG friendly format into a brand title (as
* it is seen in simple-icons.json)
* @param {String} htmlFriendlyTitle The title to convert
*/
export const htmlFriendlyToTitle = (htmlFriendlyTitle) =>
htmlFriendlyTitle
.replace(/&#([0-9]+);/g, (_, num) => String.fromCharCode(parseInt(num)))
.replace(
/&(quot|amp|lt|gt);/g,
(_, ref) => ({ quot: '"', amp: '&', lt: '<', gt: '>' }[ref]),
);
/**
* Get contents of _data/simple-icons.json.
*/
export const getIconsDataString = () => {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rootDir = path.resolve(__dirname, '..');
const iconDataPath = path.resolve(rootDir, '_data', 'simple-icons.json');
return fs.readFile(iconDataPath, 'utf8');
};
/**
* Get icon data as object from _data/simple-icons.json.
*/
export const getIconsData = async () => {
const fileContents = await getIconsDataString();
return JSON.parse(fileContents).icons;
};
/**
* Get the directory name from import.meta.url.
* @param {String} importMetaUrl import.meta.url
*/
export const getDirnameFromImportMeta = (importMetaUrl) =>
path.dirname(fileURLToPath(importMetaUrl));

19
tests/icons-cjs.test.js Normal file
View File

@ -0,0 +1,19 @@
import { exec } from 'uvu';
import { testIcon } from './test-icon.js';
import { getIconSlug, getIconsData } from '../scripts/utils.js';
(async () => {
console.warn = () => {};
const icons = await getIconsData();
const tests = icons.map(async (icon) => {
const slug = getIconSlug(icon);
const { default: subject } = await import(`../icons/${slug}.js`);
testIcon(icon, subject, slug);
});
await Promise.all(tests);
exec();
})();

22
tests/icons-esm.test.js Normal file
View File

@ -0,0 +1,22 @@
import {
getIconsData,
getIconSlug,
slugToVariableName,
} from '../scripts/utils.js';
import * as simpleIcons from '../icons.mjs';
import { testIcon } from './test-icon.js';
import { exec } from 'uvu';
(async () => {
const icons = await getIconsData();
icons.map((icon) => {
const slug = getIconSlug(icon);
const variableName = slugToVariableName(slug);
const subject = simpleIcons[variableName];
testIcon(icon, subject, slug);
});
exec();
})();

View File

@ -1,12 +0,0 @@
const { icons } = require('../_data/simple-icons.json');
const { getIconSlug } = require('../scripts/utils.js');
const testIcon = require('./test-icon.js');
console.warn = () => {};
icons.forEach((icon) => {
const slug = getIconSlug(icon);
const subject = require(`../icons/${slug}.js`);
testIcon(icon, subject, slug);
});

View File

@ -1,14 +0,0 @@
import simpleIconsData from '../_data/simple-icons.json';
import utils from '../scripts/utils.js';
import * as simpleIcons from '../icons.mjs';
import testIcon from './test-icon.js';
const { getIconSlug, slugToVariableName } = utils;
simpleIconsData.icons.forEach((icon) => {
const slug = getIconSlug(icon);
const variableName = slugToVariableName(slug);
const subject = simpleIcons[variableName];
testIcon(icon, subject, slug);
});

View File

@ -1,27 +1,32 @@
const { icons } = require('../_data/simple-icons.json'); import simpleIcons from '../index.js';
const simpleIcons = require('../index.js'); import { getIconSlug, getIconsData } from '../scripts/utils.js';
const { getIconSlug } = require('../scripts/utils'); import { test, exec } from 'uvu';
const { test } = require('uvu'); import * as assert from 'uvu/assert';
const assert = require('uvu/assert');
icons.forEach((icon) => { (async () => {
const slug = getIconSlug(icon); const icons = await getIconsData();
test(`'Get' ${icon.title} by its slug`, () => { icons.forEach((icon) => {
const found = simpleIcons.Get(slug); const slug = getIconSlug(icon);
assert.ok(found);
assert.is(found.title, icon.title); test(`'Get' ${icon.title} by its slug`, () => {
assert.is(found.hex, icon.hex); const found = simpleIcons.Get(slug);
assert.is(found.source, icon.source); assert.ok(found);
assert.is(found.title, icon.title);
assert.is(found.hex, icon.hex);
assert.is(found.source, icon.source);
});
}); });
});
test(`Iterating over simpleIcons only exposes icons`, () => { test(`Iterating over simpleIcons only exposes icons`, () => {
const iconArray = Object.values(simpleIcons); const iconArray = Object.values(simpleIcons);
for (let icon of iconArray) { for (let icon of iconArray) {
assert.ok(icon); assert.ok(icon);
assert.type(icon, 'object'); assert.type(icon, 'object');
} }
}); });
test.run(); test.run();
exec();
})();

3
tests/package.json Normal file
View File

@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@ -1,9 +1,9 @@
const fs = require('fs'); import fs from 'node:fs';
const path = require('path'); import path from 'node:path';
import { suite } from 'uvu';
import * as assert from 'uvu/assert';
const iconsDir = path.resolve(process.cwd(), 'icons'); const iconsDir = path.resolve(process.cwd(), 'icons');
const { suite } = require('uvu');
const assert = require('uvu/assert');
/** /**
* Checks if icon data matches a subject icon. * Checks if icon data matches a subject icon.
@ -11,7 +11,7 @@ const assert = require('uvu/assert');
* @param {import('..').SimpleIcon} subject Icon to check against icon data * @param {import('..').SimpleIcon} subject Icon to check against icon data
* @param {String} slug Icon data slug * @param {String} slug Icon data slug
*/ */
const testIcon = (icon, subject, slug) => { export const testIcon = (icon, subject, slug) => {
const test = suite(icon.title); const test = suite(icon.title);
const svgPath = path.resolve(iconsDir, `${slug}.svg`); const svgPath = path.resolve(iconsDir, `${slug}.svg`);
@ -69,5 +69,3 @@ const testIcon = (icon, subject, slug) => {
test.run(); test.run();
}; };
module.exports = testIcon;