Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

distinguish

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

distinguish - npm Package Compare versions

Comparing version 0.1.1 to 0.1.2

.travis.yml

2

out/distinguisher.js

@@ -190,3 +190,3 @@ "use strict";

// Find all matches.
var matches = getAllMatches(new RegExp("_(" + type + ")-([a-zA-Z0-9_-]+)", 'g'), contents);
var matches = getAllMatches(new RegExp("_(" + type + ")[$-]([a-zA-Z0-9_-]+)", 'g'), contents);
for (var i = matches.length - 1; i >= 0; i--) {

@@ -193,0 +193,0 @@ // Iterate in reverse order to safely overwrite.

{
"name": "distinguish",
"version": "0.1.1",
"version": "0.1.2",
"description": "Effortless renaming, minification, and namespacing for CSS class names, IDs, and just about anything else.",
"main": "out/cli.js",
"scripts": {
"build": "tsc && chmod +x out/cli.js",
"test": "node out/tests.js"
"build": "tsc && chmod +x out/index.js",
"test": "ts-node src/tests.ts"
},

@@ -22,3 +22,3 @@ "author": "Dylan Freedman",

"bin": {
"distinguish": "./out/cli.js"
"distinguish": "./out/index.js"
},

@@ -25,0 +25,0 @@ "license": "MIT",

@@ -9,3 +9,3 @@ CSS is great, but isn't it tricky to namespace class names safely?

# Distinguish
# Distinguish [![Build Status](https://travis-ci.org/freedmand/distinguish.svg?branch=master)](https://travis-ci.org/freedmand/distinguish)

@@ -95,3 +95,3 @@ The basic idea of Distinguish is that you mark up your CSS classes slightly to be machine-parseable, and then the program will take care of all the heavy lifting to minify names and avoid naming conflicts across modules.

```bash
npx distinguish rename
npx distinguish
```

@@ -140,5 +140,5 @@

Distinguish will modify any string of the form `_{type}-{name}` that it encounters in the files it recursively crawls in the input directory, where `{type}` is the type name (e.g. `cls`). For compatibility with JavaScript naming rules, `_{type}${name}` is also transformed.
Distinguish will modify any string of the form `_{type}-{name}` that it encounters in the files it recursively crawls in the input directory, where `{type}` is the type name (e.g. `cls`). For compatibility with JavaScript variable naming rules, `_{type}${name}` is also transformed.
For example, you could add the type `fn` and then have your JavaScript functions automatically minified (e.g. `_fn$parse()` -> `a`) — though I would never recommend doing this. Just use a JS minifier like Uglify or Closure compiler instead that actually understands your code's structure.
For example, you could add the type `fn` and then have your JavaScript functions automatically minified (e.g. `_fn$parse()` → `a`) — though I would never recommend doing this. Just use a JS minifier like Uglify or Closure compiler instead that actually understands your code's structure.

@@ -200,3 +200,3 @@ ### Exclude

By default, Distinguish will collide the names. Even though the files are in a different directory, they're in the same namespace. Let's change this:
Distinguish will not do anything special by default; the names will get tangled. Even though the files are in a different directory, they're in the same namespace. Let's change this by creating a namespec file in the `src/toggle` directory:

@@ -213,5 +213,7 @@ `src/toggle/.namespec`:

You may be asking why directories don't by default have different namespaces. This is because style sheets and other resources are often managed in different directories but intended to operate in the same namespace as the HTML files that depend on them. By forcing you to namespace with intention, the results will be more controlled.
### Anatomy of a namespace
By default, all Distinguish projects have a namespace of `root`. As Distinguish recurses into subdirectories and encounters new namespaces, these are chained onto the end.
By default, all Distinguish projects have a namespace of `root`. As Distinguish recurses into sub-directories and encounters new namespaces, these are chained onto the end.

@@ -236,3 +238,3 @@ For instance,

Now, the `src/a/b` directory and its subdirectories will have the namespace `root/a/b`.
Now, the `src/a/b` directory and its sub-directories will have the namespace `root/a/b`.

@@ -289,2 +291,2 @@ ### Imports

If you import a name from another module and then never actually make use of that name, you may have made an error. To help you, Distinguisher will warn you about every unused dependency. These warnings will not stop the output generation.
If you import a name from another module and then never actually make use of that name, you may have made an error. To help you, Distinguisher will warn you about every unused dependency. These warnings will not stop the output generation.

@@ -7,5 +7,4 @@ #!/usr/bin/env node

import {Distinguisher, DistinguishConfig} from './distinguisher';
import {BaseFs} from './virtual-fs';
const version = require('../package.json').version;
const VALID_INCREMENTERS = ['simple', 'module', 'minimal'];

@@ -38,7 +37,18 @@

abstract class CLIParser {
constructor(public stream: string[], readonly parent?: CLIParser) {}
constructor(
public stream: string[],
readonly fs: BaseFs,
readonly requireFn: (module: string) => any,
readonly dirname: (path: string) => string,
readonly join: (...parts: string[]) => string,
readonly cwd: () => string,
readonly returnOptsOnly: boolean = false,
readonly parent?: CLIParser
) {}
moreArguments(): boolean {
if (this.stream.length == 0) {
logStyle(FAIL, `Expected additional arguments\n`);
if (!this.returnOptsOnly) {
logStyle(FAIL, `Expected additional arguments\n`);
}
return false;

@@ -51,3 +61,5 @@ }

if (this.stream.length != 0) {
logStyle(FAIL, `Encountered extraneous arguments: ${this.stream}\n`);
if (!this.returnOptsOnly) {
logStyle(FAIL, `Encountered extraneous arguments: ${this.stream}\n`);
}
return false;

@@ -76,3 +88,3 @@ }

interface RenameOptions {
export interface RenameOptions {
configFile?: string;

@@ -86,4 +98,12 @@ incrementer?: string;

export interface CLIResult {
opts?: RenameOptions;
initFn?: string;
showVersion?: boolean;
showUsage?: string;
showSplash?: boolean;
}
class RenameCLI extends CLIParser {
process() {
process(): CLIResult {
let expectConfig = false;

@@ -98,3 +118,3 @@ let expectIncrementer = false;

const opts: RenameOptions = {};
const opts: RenameOptions = {configFile: DEFAULT_CONFIG_FN};
while (this.stream.length > 0) {

@@ -104,4 +124,3 @@ // Go through expectations.

if (!this.moreArguments()) {
this.showUsage();
return;
return this.showUsage();
}

@@ -111,5 +130,9 @@ const incrementer = this.stream[0];

if (VALID_INCREMENTERS.indexOf(incrementer) == -1) {
logStyle(FAIL, `Expected an incrementer in the set ${VALID_INCREMENTERS}\n`);
this.showUsage();
return;
if (!this.returnOptsOnly) {
logStyle(
FAIL,
`Expected an incrementer in the set ${VALID_INCREMENTERS}\n`
);
}
return this.showUsage();
}

@@ -123,4 +146,3 @@ opts.incrementer = incrementer;

if (!this.moreArguments()) {
this.showUsage();
return;
return this.showUsage();
}

@@ -135,4 +157,3 @@ opts.types = this.stream[0].split(',');

if (!this.moreArguments()) {
this.showUsage();
return;
return this.showUsage();
}

@@ -147,4 +168,3 @@ opts.inputDir = this.stream[0];

if (!this.moreArguments()) {
this.showUsage();
return;
return this.showUsage();
}

@@ -159,4 +179,3 @@ opts.outputDir = this.stream[0];

if (!this.moreArguments()) {
this.showUsage();
return;
return this.showUsage();
}

@@ -209,4 +228,3 @@ opts.exclude = this.stream[0].split(',').map(x => new RegExp(x));

if (!this.moreArguments() || !expectConfig) {
this.showUsage();
return;
return this.showUsage();
}

@@ -230,4 +248,22 @@ opts.configFile = this.stream[0];

// Load in the config file.
opts.configFile = path.join(process.cwd(), opts.configFile);
const settings = require(opts.configFile).default;
if (!this.returnOptsOnly) {
opts.configFile = path.join(process.cwd(), opts.configFile);
}
const settings = this.requireFn(opts.configFile).default;
if (settings == undefined) {
if (!this.returnOptsOnly) {
logStyle(
FAIL,
`Unable to read in ${opts.configFile}.
Maybe you need to create a config file first by running:
distinguish init
`
);
}
return this.showUsage();
}
if (opts.incrementer == null) opts.incrementer = settings.incrementer;

@@ -241,37 +277,17 @@ if (opts.types == null) opts.types = settings.types;

// Run time.
console.log('Run settings:\n', opts);
console.log();
const distinguisher = new Distinguisher(opts as DistinguishConfig);
distinguisher.run();
if (!this.returnOptsOnly) {
console.log('Run settings:\n', opts);
console.log();
const distinguisher = new Distinguisher(
opts as DistinguishConfig,
fs,
path.dirname
);
distinguisher.run();
}
return {opts};
}
showUsage() {
console.log(`Usage: ${BINARY_NAME} rename [options]
rename and namespace files recursively in a directory
Options:
-c, --config [fn] Load all the settings from a config file.
(default if no value passed: ${DEFAULT_CONFIG_FN})
Config options / overrides:
-n, --incrementer <str> Specify the incrementer to use.
Options are 'simple', 'module', or 'minimal'
(default if no config specified: simple)
-t, --types <list> Specify a list of types to rename
(default if no config specified: cls,id)
-i, --inputDir <dir> The input directory to use
(this arg is mandatory if no config is specified)
-o, --outputDir <dir> The output directory to use
(this arg is mandatory if no config is specified)
-e, --exclude <list> Regular expression of paths to exclude renaming.
It is recommended to set this in a config file to
have more control.
(default: empty list)
`);
process.exit(1);
showUsage(): CLIResult {
return (this.parent as CLI).showUsage();
}

@@ -281,21 +297,23 @@ }

class InitCLI extends CLIParser {
process() {
process(): CLIResult {
let fn = DEFAULT_CONFIG_FN;
if (this.stream.length > 0) {
fn = this.stream[0];
if (fn.startsWith('-')) return this.showUsage();
this.advance();
if (!this.noMoreArguments()) {
this.showUsage();
return;
}
if (!this.noMoreArguments()) return this.showUsage();
}
const startTime = Date.now();
fs.writeFileSync(fn, EMPTY_CONFIG);
const deltaTime = Date.now() - startTime;
logStyle(SUCCESS, `Wrote config to ${fn} in ${deltaTime / 1000}s`);
if (!this.returnOptsOnly) {
const startTime = Date.now();
fs.writeFileSync(fn, EMPTY_CONFIG);
const deltaTime = Date.now() - startTime;
logStyle(SUCCESS, `Wrote config to ${fn} in ${deltaTime / 1000}s`);
}
return {initFn: fn};
}
showUsage() {
console.log(`Usage: ${BINARY_NAME} init <fn>
showUsage(): CLIResult {
if (!this.returnOptsOnly) {
console.log(`Usage: ${BINARY_NAME} init <fn>

@@ -308,14 +326,23 @@ create a default distinguish config file

`);
process.exit(1);
process.exit(1);
}
return {showUsage: 'init'};
}
}
class CLI extends CLIParser {
public version: string = version;
constructor() {
super(process.argv.slice(2));
export class CLI extends CLIParser {
constructor(
readonly version: string | null,
args: string[],
fs: BaseFs,
requireFn: (module: string) => any,
dirname: (path: string) => string,
join: (...parts: string[]) => string,
cwd: () => string,
returnOptsOnly: boolean = false
) {
super(args, fs, requireFn, dirname, join, cwd, returnOptsOnly);
}
process() {
process(): CLIResult {
// Try to consume options.

@@ -327,7 +354,14 @@ if (this.consumeOption(['-v', '--version'])) return this.showVersion();

// Try to consume sub-commands.
if (this.consumeOption(['rename'])) {
return new RenameCLI(this.stream.slice(1), this).process();
}
if (this.consumeOption(['init'])) {
return new InitCLI(this.stream.slice(1), this).process();
return new InitCLI(
this.stream.slice(1),
this.fs,
this.requireFn,
this.dirname,
this.join,
this.cwd,
this.returnOptsOnly,
this
).process();
}

@@ -339,18 +373,48 @@

if (this.consumeOption(['rename'])) {
return new RenameCLI(this.stream.slice(1), this).showUsage();
return new RenameCLI(
this.stream.slice(1),
this.fs,
this.requireFn,
this.dirname,
this.join,
this.cwd,
this.returnOptsOnly,
this
).showUsage();
}
if (this.consumeOption(['init'])) {
return new InitCLI(this.stream.slice(1), this).showUsage();
return new InitCLI(
this.stream.slice(1),
this.fs,
this.requireFn,
this.dirname,
this.join,
this.cwd,
this.returnOptsOnly,
this
).showUsage();
}
return this.showUsage();
}
this.showUsage();
return new RenameCLI(
this.stream,
this.fs,
this.requireFn,
this.dirname,
this.join,
this.cwd,
this.returnOptsOnly,
this
).process();
}
showVersion() {
console.log(this.version);
showVersion(): CLIResult {
if (!this.returnOptsOnly) console.log(this.version);
return {showVersion: true};
}
showUsage() {
console.log(`Usage: ${BINARY_NAME} <command> [options]
showUsage(): CLIResult {
if (!this.returnOptsOnly) {
console.log(`Usage: ${BINARY_NAME} <command> [options]

@@ -370,12 +434,15 @@ Commands:

`);
process.exit(1);
process.exit(1);
}
return {showUsage: 'base'};
}
showSplash() {
console.log(SPLASH_SCREEN);
logStyle(BOLD, 'Effortless renaming, minification, and namespacing');
logStyle(BOLD, 'for CSS class names, IDs, and just about anything else.\n');
showSplash(): CLIResult {
if (!this.returnOptsOnly) {
console.log(SPLASH_SCREEN);
logStyle(BOLD, 'Effortless renaming, minification, and namespacing');
logStyle(BOLD, 'for CSS class names, IDs, and just about anything else.\n');
}
return {showSplash: true};
}
}
new CLI().process();

@@ -1,4 +0,1 @@

import fs from 'fs';
import path from 'path';
import MagicString from 'magic-string';
import {Renamer} from './renamer';

@@ -13,2 +10,3 @@ import {NamespecParser} from './namespec';

import {logStyle, STATUS, WARN, BOLD} from './log';
import {BaseFs} from './virtual-fs';

@@ -24,6 +22,10 @@ interface WalkResult {

// Adapted from https://stackoverflow.com/a/34509653
function ensureDirectoryExistence(filePath: string) {
const dirname = path.dirname(filePath);
function ensureDirectoryExistence(
filePath: string,
dirnameFn: (path: string) => string,
fs: BaseFs
) {
const dirname = dirnameFn(filePath);
if (fs.existsSync(dirname)) return;
ensureDirectoryExistence(dirname);
ensureDirectoryExistence(dirname, dirnameFn, fs);
fs.mkdirSync(dirname);

@@ -58,3 +60,7 @@ }

constructor(readonly distinguishConfig: DistinguishConfig) {
constructor(
readonly distinguishConfig: DistinguishConfig,
readonly fs: BaseFs,
readonly dirnameFn: (path: string) => string
) {
const incrementer = incrementers[distinguishConfig.incrementer] as {

@@ -76,6 +82,6 @@ new (): Incrementer;

const namespecPath = `${dir}${NAMESPEC}`;
if (fs.existsSync(namespecPath)) {
if (this.fs.existsSync(namespecPath)) {
// Parse a namespec file to determine the renamer's new scope.
const namespec = new NamespecParser(
fs.readFileSync(namespecPath).toString()
this.fs.readFileSync(namespecPath).toString()
).parse();

@@ -103,3 +109,3 @@

const files = fs.readdirSync(dir == '' ? '.' : dir);
const files = this.fs.readdirSync(dir == '' ? '.' : dir);
files.forEach(file => {

@@ -110,4 +116,9 @@ const fn = `${dir}${file}`;

}
if (fs.statSync(fn).isDirectory()) {
filelist = this.walkSync(`${fn}/`, `${outDir}${file}`, renamer, filelist);
if (this.fs.statSync(fn).isDirectory()) {
filelist = this.walkSync(
`${fn + (fn.endsWith('/') ? '' : '/')}`,
`${outDir}${file}`,
renamer,
filelist
);
} else {

@@ -131,3 +142,3 @@ filelist.push({

)) {
let contents = fs.readFileSync(inputFile).toString();
let contents = this.fs.readFileSync(inputFile).toString();

@@ -161,4 +172,4 @@ let hadMatches = false;

ensureDirectoryExistence(outputFile);
fs.writeFileSync(outputFile, contents.toString());
ensureDirectoryExistence(outputFile, this.dirnameFn, this.fs);
this.fs.writeFileSync(outputFile, contents.toString());
}

@@ -165,0 +176,0 @@

@@ -32,4 +32,31 @@ import {logStyle, PASS, FAIL} from './log';

static getType(obj: any): 'array' | 'object' | 're' | 'primitive' {
if (Array.isArray(obj)) {
return 'array';
} else if (obj instanceof RegExp) {
return 're';
} else if (obj.constructor == Object) {
return 'object';
} else {
return 'primitive';
}
}
assertEquals(arg1: any, arg2: any) {
if (arg1 != arg2) throw new Error(`Expected ${arg1} to equal ${arg2}`);
const type1 = Tester.getType(arg1);
const type2 = Tester.getType(arg2);
if (type1 != type2) {
throw new Error(
`Types of ${arg1} and ${arg2} are not the same: ${type1} vs. ${type2}`
);
}
if (type1 == 'array') {
this.assertArrayEquals(arg1, arg2);
} else if (type1 == 'object') {
this.assertObjectEquals(arg1, arg2);
} else if (type1 == 're') {
this.assertEquals(arg1.source, arg2.source);
} else {
if (arg1 != arg2) throw new Error(`Expected ${arg1} to equal ${arg2}`);
}
}

@@ -36,0 +63,0 @@

@@ -5,2 +5,5 @@ import {Renamer} from './renamer';

import {MinimalIncrementer, SimpleIncrementer, ModuleIncrementer} from './incrementer';
import {VirtualFs} from './virtual-fs';
import {Distinguisher, DistinguishConfig} from './distinguisher';
import {CLI, CLIResult, RenameOptions} from './cli';

@@ -375,1 +378,353 @@ const t = new Tester();

});
t.test('virtualFsBasic', () => {
const fs = new VirtualFs();
fs.writeFileSync('/hello.txt', 'hello world');
t.assertEquals(fs.readFileSync('/hello.txt').toString(), 'hello world');
t.assertArrayEquals(fs.readdirSync('/'), ['hello.txt']);
});
t.test('virtualFsListDir', () => {
const fs = new VirtualFs();
fs.writeFileSync('/src/index.html', '');
fs.writeFileSync('/src/style.css', '');
fs.writeFileSync('/src/component/component.html', '');
fs.writeFileSync('/src/component/component.css', '');
fs.writeFileSync('/src/component/toggle/toggle.css', '');
fs.writeFileSync('/src/component/toggle/tests/style/test.js', '');
fs.writeFileSync('/out/module/component/test.txt', '');
t.assertArrayEquals(fs.readdirSync('/'), ['out/', 'src/']);
t.assertArrayEquals(fs.readdirSync('/src/'), [
'component/',
'index.html',
'style.css',
]);
t.assertArrayEquals(fs.readdirSync('/src/component/'), [
'component.css',
'component.html',
'toggle/',
]);
t.assertArrayEquals(fs.readdirSync('/src/component/toggle/'), [
'tests/',
'toggle.css',
]);
t.assertArrayEquals(fs.readdirSync('/src/component/toggle/tests/'), ['style/']);
t.assertArrayEquals(fs.readdirSync('/src/component/toggle/tests/style/'), [
'test.js',
]);
t.assertArrayEquals(fs.readdirSync('/out/'), ['module/']);
t.assertArrayEquals(fs.readdirSync('/out/module/'), ['component/']);
t.assertArrayEquals(fs.readdirSync('/out/module/component/'), ['test.txt']);
});
t.test('distinguisherBasic', () => {
const fs = new VirtualFs();
fs.writeFileSync('/src/style.css', '._cls-content { color: gray; }');
const config: DistinguishConfig = {
inputDir: '/src/',
outputDir: '/out/',
incrementer: 'minimal',
types: ['cls', 'id'],
exclude: [],
};
const d = new Distinguisher(config, fs, fs.dirname);
d.run();
t.assertArrayEquals(fs.readdirSync('/'), ['out/', 'src/']);
t.assertArrayEquals(fs.readdirSync('/out/'), ['style.css']);
t.assertEquals(fs.readFileSync('/out/style.css').toString(), '.a { color: gray; }');
});
t.test('distinguisherClsAndIdBasic', () => {
const fs = new VirtualFs();
fs.writeFileSync(
'/src/index.html',
'<div id="_id-content" class="_cls-content">Content here</div>'
);
fs.writeFileSync(
'/src/component/style.css',
`
._cls-content {
color: gray;
}
#_id-content {
font-weight: bold;
}`
);
const config: DistinguishConfig = {
inputDir: '/src/',
outputDir: '/out/',
incrementer: 'minimal',
types: ['cls', 'id'],
exclude: [],
};
const d = new Distinguisher(config, fs, fs.dirname);
d.run();
t.assertEquals(
fs.readFileSync('/out/index.html').toString(),
'<div id="a" class="a">Content here</div>'
);
t.assertEquals(
fs.readFileSync('/out/component/style.css').toString(),
`
.a {
color: gray;
}
#a {
font-weight: bold;
}`
);
});
function toggleSrcIndex(toggleClass: string): string {
return `
<link rel="stylesheet" href="toggle/toggle.css">
<style>
.${toggleClass} {
background: green;
}
</style>
<div class="${toggleClass}"></div>
<script src="toggle/toggle.js"></script>`;
}
function toggleToggleCss(toggleClass: string): string {
return `
.${toggleClass} {
background: blue;
}`;
}
function toggleToggleJs(toggleClass: string): string {
return `
// Create a toggle element from scratch.
const div = document.createElement('div');
div.classList.add('${toggleClass}');
// Code to render it.
...`;
}
function toggleTest(
initialClass: string,
indexClass: string,
cssClass: string,
jsClass: string,
playWithFiles?: (fs: VirtualFs) => void
) {
const fs = new VirtualFs();
fs.writeFileSync('/src/index.html', toggleSrcIndex(initialClass));
fs.writeFileSync('/src/toggle/toggle.css', toggleToggleCss(initialClass));
fs.writeFileSync('/src/toggle/toggle.js', toggleToggleJs(initialClass));
if (playWithFiles != null) playWithFiles(fs);
const config: DistinguishConfig = {
inputDir: '/src/',
outputDir: '/out/',
incrementer: 'minimal',
types: ['cls', 'id'],
exclude: [],
};
const d = new Distinguisher(config, fs, fs.dirname);
d.run();
t.assertEquals(
fs.readFileSync('/out/index.html').toString(),
toggleSrcIndex(indexClass)
);
t.assertEquals(
fs.readFileSync('/out/toggle/toggle.css').toString(),
toggleToggleCss(cssClass)
);
t.assertEquals(
fs.readFileSync('/out/toggle/toggle.js').toString(),
toggleToggleJs(jsClass)
);
}
t.test('distinguisherNamespaceClash', () => {
toggleTest('_cls-toggle', 'a', 'a', 'a');
});
t.test('distinguisherNamespaceFixComponent', () => {
toggleTest('_cls-toggle', 'a', 'b', 'b', (fs: VirtualFs) => {
fs.writeFileSync('/src/toggle/.namespec', 'namespace toggle');
});
});
t.test('distinguisherNamespaceImport', () => {
toggleTest('_cls-toggle', 'a', 'a', 'a', (fs: VirtualFs) => {
fs.writeFileSync(
'/src/toggle/.namespec',
`namespace toggle
from .. import
cls
toggle`
);
});
});
t.test('distinguisherNamespecReserve', () => {
toggleTest('_cls-toggle', 'b', 'c', 'c', (fs: VirtualFs) => {
fs.writeFileSync(
'/src/toggle/.namespec',
`namespace toggle
reserve
cls
a`
);
});
});
function cli(argsString: string, fsInit?: (fs: VirtualFs) => void): CLIResult {
const fs = new VirtualFs();
if (fsInit != null) fsInit(fs);
return new CLI(
null,
argsString.split(' ').filter(x => x.trim().length > 0),
fs,
fs.require.bind(fs),
fs.dirname,
fs.join,
() => '/',
true
).process();
}
t.test('distinguishCliShowDialogs', () => {
// Help
t.assertObjectEquals(cli('--help'), {showUsage: 'base'});
t.assertObjectEquals(cli('-h'), {showUsage: 'base'});
t.assertObjectEquals(cli('--usage'), {showUsage: 'base'});
t.assertObjectEquals(cli('help'), {showUsage: 'base'});
t.assertObjectEquals(cli('help init'), {showUsage: 'init'});
t.assertObjectEquals(cli('help rename'), {showUsage: 'base'});
t.assertObjectEquals(cli('--invalid-option'), {showUsage: 'base'});
t.assertObjectEquals(cli('rename --invalid-option'), {showUsage: 'base'});
// Version
t.assertObjectEquals(cli('-v'), {showVersion: true});
t.assertObjectEquals(cli('--version'), {showVersion: true});
// Splash
t.assertObjectEquals(cli('--splash'), {showSplash: true});
});
t.test('distinguishCliInit', () => {
t.assertObjectEquals(cli('init'), {initFn: 'distinguish.config.js'});
t.assertObjectEquals(cli('init config.js'), {initFn: 'config.js'});
t.assertObjectEquals(cli('init -o'), {showUsage: 'init'});
t.assertObjectEquals(cli('init config.js extraneous'), {showUsage: 'init'});
});
t.test('distinguishCliRenameNoConfig', () => {
const result = cli('');
// File won't exist yet.
t.assertEquals(result.showUsage, 'base');
});
function getConfig(
incrementer: string = 'simple',
types: string[] = ['cls', 'id'],
inputDir: string = 'src/',
outputDir: string = 'out/',
exclude: string[] = []
): string {
return `exports.default = {
incrementer: '${incrementer}', // the incrementer to use ([minimal, simple, module])
types: ${JSON.stringify(types)}, // the types to rename (e.g. CSS classes, IDs)
inputDir: '${inputDir}', // the input directory to use
outputDir: '${outputDir}', // the output directory to use
exclude: ${JSON.stringify(
exclude
)}, // a regular expression array describing files to exclude from renaming
};
`;
}
t.test('distinguishCliRenameWithConfig', () => {
for (const cmd of [
'',
'-c',
'-c distinguish.config.js',
'--config',
'--config distinguish.config.js',
]) {
const result = cli('', fs => {
fs.writeFileSync('distinguish.config.js', getConfig());
});
// Let's check we get a matching config.
t.assert(result.opts);
const opts = result.opts as RenameOptions;
t.assertEquals(opts, {
configFile: 'distinguish.config.js',
incrementer: 'simple',
types: ['cls', 'id'],
inputDir: 'src/',
outputDir: 'out/',
exclude: [],
});
}
});
t.test('distinguishCliRenameWithConfigDifferentFile', () => {
for (const cmd of [
'-c specification/config.js',
'--config specification/config.js',
]) {
const result = cli(cmd, fs => {
fs.writeFileSync('specification/config.js', getConfig());
});
// Let's check we get a matching config.
t.assert(result.opts);
const opts = result.opts as RenameOptions;
t.assertEquals(opts, {
configFile: 'specification/config.js',
incrementer: 'simple',
types: ['cls', 'id'],
inputDir: 'src/',
outputDir: 'out/',
exclude: [],
});
}
});
t.test('distinguishCliRenameWithOverrides', () => {
const result = cli(
'-c spec/settings/config.js -n minimal -t dog,cat,hen -i input/src/ -o dest/ -e dog,cat',
fs => {
fs.writeFileSync('spec/settings/config.js', getConfig());
}
);
// Let's check we get a matching config.
t.assert(result.opts);
const opts = result.opts as RenameOptions;
t.assertEquals(opts, {
configFile: 'spec/settings/config.js',
incrementer: 'minimal',
types: ['dog', 'cat', 'hen'],
inputDir: 'input/src/',
outputDir: 'dest/',
exclude: [/dog/, /cat/],
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc