@dialpad/dialtone-css 8.80.0-next.6 → 8.80.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/build/js/dialtone_migrate_border_radius/index.mjs +273 -0
- package/lib/build/js/dialtone_migrate_border_radius/test.mjs +422 -0
- package/lib/build/js/dialtone_migrate_typography/index.mjs +1628 -0
- package/lib/build/js/dialtone_migrate_typography/test.mjs +1020 -0
- package/lib/build/js/dialtone_migration_helper/configs/theme-to-mode.mjs +108 -0
- package/lib/build/js/dialtone_migration_helper/tests/theme-to-mode-test-examples.vue +24 -0
- package/lib/build/js/dialtone_migration_helper/tests/theme-to-mode.test.mjs +177 -0
- package/lib/build/less/components/button.less +2 -0
- package/lib/build/less/components/emoji-picker.less +10 -11
- package/lib/build/less/components/forms.less +22 -16
- package/lib/build/less/components/modal.less +8 -2
- package/lib/build/less/components/notice.less +4 -0
- package/lib/build/less/components/popover.less +1 -1
- package/lib/build/less/components/presence.less +23 -3
- package/lib/build/less/recipes/leftbar_row.less +1 -0
- package/lib/dist/dialtone-default-theme.css +67 -34
- package/lib/dist/dialtone-default-theme.min.css +1 -1
- package/lib/dist/dialtone-docs.json +1 -1
- package/lib/dist/dialtone.css +66 -34
- package/lib/dist/dialtone.min.css +1 -1
- package/lib/dist/js/dialtone_migrate_border_radius/index.mjs +273 -0
- package/lib/dist/js/dialtone_migrate_border_radius/test.mjs +422 -0
- package/lib/dist/js/dialtone_migrate_typography/index.mjs +1628 -0
- package/lib/dist/js/dialtone_migrate_typography/test.mjs +1020 -0
- package/lib/dist/js/dialtone_migration_helper/configs/theme-to-mode.mjs +108 -0
- package/lib/dist/js/dialtone_migration_helper/tests/theme-to-mode-test-examples.vue +24 -0
- package/lib/dist/js/dialtone_migration_helper/tests/theme-to-mode.test.mjs +177 -0
- package/lib/dist/tokens/tokens-101-dark.css +1 -0
- package/lib/dist/tokens/tokens-101-light.css +1 -0
- package/lib/dist/tokens/tokens-102-dark.css +1 -0
- package/lib/dist/tokens/tokens-102-light.css +1 -0
- package/lib/dist/tokens/tokens-103-dark.css +1 -0
- package/lib/dist/tokens/tokens-103-light.css +1 -0
- package/lib/dist/tokens/tokens-104-dark.css +1 -0
- package/lib/dist/tokens/tokens-104-light.css +1 -0
- package/lib/dist/tokens/tokens-105-dark.css +1 -0
- package/lib/dist/tokens/tokens-105-light.css +1 -0
- package/lib/dist/tokens/tokens-106-dark.css +1 -0
- package/lib/dist/tokens/tokens-106-light.css +1 -0
- package/lib/dist/tokens/tokens-107-dark.css +1 -0
- package/lib/dist/tokens/tokens-107-light.css +1 -0
- package/lib/dist/tokens/tokens-108-dark.css +1 -0
- package/lib/dist/tokens/tokens-108-light.css +1 -0
- package/lib/dist/tokens/tokens-109-dark.css +1 -0
- package/lib/dist/tokens/tokens-109-light.css +1 -0
- package/lib/dist/tokens/tokens-110-dark.css +1 -0
- package/lib/dist/tokens/tokens-110-light.css +1 -0
- package/lib/dist/tokens/tokens-111-dark.css +1 -0
- package/lib/dist/tokens/tokens-111-light.css +1 -0
- package/lib/dist/tokens/tokens-112-dark.css +1 -0
- package/lib/dist/tokens/tokens-112-light.css +1 -0
- package/lib/dist/tokens/tokens-113-dark.css +1 -0
- package/lib/dist/tokens/tokens-113-light.css +1 -0
- package/lib/dist/tokens/tokens-114-dark.css +1 -0
- package/lib/dist/tokens/tokens-114-light.css +1 -0
- package/lib/dist/tokens/tokens-115-dark.css +1 -0
- package/lib/dist/tokens/tokens-115-light.css +1 -0
- package/lib/dist/tokens/tokens-116-dark.css +1 -0
- package/lib/dist/tokens/tokens-116-light.css +1 -0
- package/lib/dist/tokens/tokens-117-dark.css +1 -0
- package/lib/dist/tokens/tokens-117-light.css +1 -0
- package/lib/dist/tokens/tokens-118-dark.css +1 -0
- package/lib/dist/tokens/tokens-118-light.css +1 -0
- package/lib/dist/tokens/tokens-119-dark.css +1 -0
- package/lib/dist/tokens/tokens-119-light.css +1 -0
- package/lib/dist/tokens/tokens-120-dark.css +1 -0
- package/lib/dist/tokens/tokens-120-light.css +1 -0
- package/lib/dist/tokens/tokens-121-dark.css +1 -0
- package/lib/dist/tokens/tokens-121-light.css +1 -0
- package/lib/dist/tokens/tokens-122-dark.css +1 -0
- package/lib/dist/tokens/tokens-122-light.css +1 -0
- package/lib/dist/tokens/tokens-123-dark.css +1 -0
- package/lib/dist/tokens/tokens-123-light.css +1 -0
- package/lib/dist/tokens/tokens-124-dark.css +1 -0
- package/lib/dist/tokens/tokens-124-light.css +1 -0
- package/lib/dist/tokens/tokens-125-dark.css +1 -0
- package/lib/dist/tokens/tokens-125-light.css +1 -0
- package/lib/dist/tokens/tokens-126-dark.css +1 -0
- package/lib/dist/tokens/tokens-126-light.css +1 -0
- package/lib/dist/tokens/tokens-127-dark.css +1 -0
- package/lib/dist/tokens/tokens-127-light.css +1 -0
- package/lib/dist/tokens/tokens-128-dark.css +1 -0
- package/lib/dist/tokens/tokens-128-light.css +1 -0
- package/lib/dist/tokens/tokens-129-dark.css +1 -0
- package/lib/dist/tokens/tokens-129-light.css +1 -0
- package/lib/dist/tokens/tokens-130-dark.css +1 -0
- package/lib/dist/tokens/tokens-130-light.css +1 -0
- package/lib/dist/tokens/tokens-131-dark.css +1 -0
- package/lib/dist/tokens/tokens-131-light.css +1 -0
- package/lib/dist/tokens/tokens-132-dark.css +1 -0
- package/lib/dist/tokens/tokens-132-light.css +1 -0
- package/lib/dist/tokens/tokens-133-dark.css +1 -0
- package/lib/dist/tokens/tokens-133-light.css +1 -0
- package/lib/dist/tokens/tokens-134-dark.css +1 -0
- package/lib/dist/tokens/tokens-134-light.css +1 -0
- package/lib/dist/tokens/tokens-135-dark.css +1 -0
- package/lib/dist/tokens/tokens-135-light.css +1 -0
- package/lib/dist/tokens/tokens-136-dark.css +1 -0
- package/lib/dist/tokens/tokens-136-light.css +1 -0
- package/lib/dist/tokens/tokens-137-dark.css +1 -0
- package/lib/dist/tokens/tokens-137-light.css +1 -0
- package/lib/dist/tokens/tokens-aegean-dark.css +1 -0
- package/lib/dist/tokens/tokens-aegean-light.css +1 -0
- package/lib/dist/tokens/tokens-botany-dark.css +1 -0
- package/lib/dist/tokens/tokens-botany-light.css +1 -0
- package/lib/dist/tokens/tokens-buttercream-dark.css +1 -0
- package/lib/dist/tokens/tokens-buttercream-light.css +1 -0
- package/lib/dist/tokens/tokens-ceruleo-dark.css +1 -0
- package/lib/dist/tokens/tokens-ceruleo-light.css +1 -0
- package/lib/dist/tokens/tokens-debug-dp.css +1 -0
- package/lib/dist/tokens/tokens-dp-dark.css +1 -0
- package/lib/dist/tokens/tokens-dp-light.css +1 -0
- package/lib/dist/tokens/tokens-expressive-dark.css +1 -0
- package/lib/dist/tokens/tokens-expressive-light.css +1 -0
- package/lib/dist/tokens/tokens-expressive-sm-dark.css +1 -0
- package/lib/dist/tokens/tokens-expressive-sm-light.css +1 -0
- package/lib/dist/tokens/tokens-high-desert-dark.css +1 -0
- package/lib/dist/tokens/tokens-high-desert-light.css +1 -0
- package/lib/dist/tokens/tokens-melon-dark.css +1 -0
- package/lib/dist/tokens/tokens-melon-light.css +1 -0
- package/lib/dist/tokens/tokens-plum-dark.css +1 -0
- package/lib/dist/tokens/tokens-plum-light.css +1 -0
- package/lib/dist/tokens/tokens-prota-deuter-dark.css +1 -0
- package/lib/dist/tokens/tokens-prota-deuter-light.css +1 -0
- package/lib/dist/tokens/tokens-sunflower-dark.css +1 -0
- package/lib/dist/tokens/tokens-sunflower-light.css +1 -0
- package/lib/dist/tokens/tokens-tmo-dark.css +1 -0
- package/lib/dist/tokens/tokens-tmo-light.css +1 -0
- package/lib/dist/tokens/tokens-trita-dark.css +1 -0
- package/lib/dist/tokens/tokens-trita-light.css +1 -0
- package/lib/dist/tokens/tokens-verdant-haze-dark.css +1 -0
- package/lib/dist/tokens/tokens-verdant-haze-light.css +1 -0
- package/lib/dist/tokens-docs.json +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Migration script for deprecated physical border-radius utility classes.
|
|
5
|
+
*
|
|
6
|
+
* DLT-3329 Physical directional border-radius utility classes have been replaced
|
|
7
|
+
* by logical equivalents. This script rewrites:
|
|
8
|
+
*
|
|
9
|
+
* All-corners numeric: d-bar6 → d-bar-350
|
|
10
|
+
* Pair numeric: d-btr8 → d-bbsr-400
|
|
11
|
+
* Pair keyword: d-btr-pill → d-bbsr-pill
|
|
12
|
+
*
|
|
13
|
+
* The full pair-prefix mapping is:
|
|
14
|
+
* btr → bbsr (top → block-start pair)
|
|
15
|
+
* bbr → bber (bottom → block-end pair)
|
|
16
|
+
* blr → bisr (left → inline-start pair)
|
|
17
|
+
* brr → bier (right → inline-end pair)
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* npx dialtone-migrate-border-radius [options]
|
|
21
|
+
*
|
|
22
|
+
* Options:
|
|
23
|
+
* --cwd <path> Working directory (default: current directory)
|
|
24
|
+
* --dry-run Show changes without applying them
|
|
25
|
+
* --yes Apply all changes without prompting
|
|
26
|
+
* --help Show help
|
|
27
|
+
*
|
|
28
|
+
* Examples:
|
|
29
|
+
* npx dialtone-migrate-border-radius
|
|
30
|
+
* npx dialtone-migrate-border-radius --dry-run
|
|
31
|
+
* npx dialtone-migrate-border-radius --cwd ./src
|
|
32
|
+
* npx dialtone-migrate-border-radius --yes
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import fs from 'fs/promises';
|
|
36
|
+
import { realpathSync } from 'node:fs';
|
|
37
|
+
import path from 'path';
|
|
38
|
+
import readline from 'readline';
|
|
39
|
+
import { fileURLToPath } from 'node:url';
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Mapping — MUST STAY IN SYNC with:
|
|
43
|
+
// - packages/eslint-plugin-dialtone/lib/rules/deprecated-radius-utility-classes.js
|
|
44
|
+
// - packages/dialtone-css/postcss/constants.cjs (RADIUS_STOPS)
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
const RADIUS_STOP_MAP = {
|
|
48
|
+
0: '0', 1: '100', 2: '200', 4: '300', 6: '350',
|
|
49
|
+
8: '400', 12: '450', 16: '500', 24: '550', 32: '600',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const PAIR_PREFIX_MAP = {
|
|
53
|
+
btr: 'bbsr', // top → block-start pair
|
|
54
|
+
bbr: 'bber', // bottom → block-end pair
|
|
55
|
+
blr: 'bisr', // left → inline-start pair
|
|
56
|
+
brr: 'bier', // right → inline-end pair
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Ordered by descending string length so regex alternation matches longest first.
|
|
60
|
+
const NUMERIC_SUFFIXES = Object.keys(RADIUS_STOP_MAP)
|
|
61
|
+
.sort((a, b) => b.length - a.length || Number(b) - Number(a))
|
|
62
|
+
.join('|');
|
|
63
|
+
const PAIR_PREFIXES = Object.keys(PAIR_PREFIX_MAP).join('|');
|
|
64
|
+
|
|
65
|
+
// Word-boundary anchored patterns to avoid matching inside unrelated class names.
|
|
66
|
+
const ALL_CORNERS_NUMERIC = new RegExp(`(?<=[\\s"'=\`])d-bar(${NUMERIC_SUFFIXES})(?=[\\s"'>;\`])`, 'g');
|
|
67
|
+
const PAIR_NUMERIC = new RegExp(`(?<=[\\s"'=\`])d-(${PAIR_PREFIXES})(${NUMERIC_SUFFIXES})(?=[\\s"'>;\`])`, 'g');
|
|
68
|
+
const PAIR_KEYWORD = new RegExp(`(?<=[\\s"'=\`])d-(${PAIR_PREFIXES})-(pill|circle)(?=[\\s"'>;\`])`, 'g');
|
|
69
|
+
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Transform
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
export function transformContent (content) {
|
|
75
|
+
let transformed = content;
|
|
76
|
+
let count = 0;
|
|
77
|
+
|
|
78
|
+
transformed = transformed
|
|
79
|
+
.replace(ALL_CORNERS_NUMERIC, (_, px) => { count++; return `d-bar-${RADIUS_STOP_MAP[px]}`; })
|
|
80
|
+
.replace(PAIR_NUMERIC, (_, legacyPrefix, px) => { count++; return `d-${PAIR_PREFIX_MAP[legacyPrefix]}-${RADIUS_STOP_MAP[px]}`; })
|
|
81
|
+
.replace(PAIR_KEYWORD, (_, legacyPrefix, keyword) => { count++; return `d-${PAIR_PREFIX_MAP[legacyPrefix]}-${keyword}`; });
|
|
82
|
+
|
|
83
|
+
return { transformed, count };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { RADIUS_STOP_MAP, PAIR_PREFIX_MAP };
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// File walker
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
function isIgnoredPath (fullPath, ignore) {
|
|
93
|
+
const segments = fullPath.split(path.sep);
|
|
94
|
+
return ignore.some(ig => {
|
|
95
|
+
if (ig.includes('/')) {
|
|
96
|
+
const parts = ig.split('/');
|
|
97
|
+
for (let i = 0; i + parts.length <= segments.length; i++) {
|
|
98
|
+
if (parts.every((p, j) => segments[i + j] === p)) return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
return segments.includes(ig);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function findFiles (dir, extensions, ignore = []) {
|
|
107
|
+
const results = [];
|
|
108
|
+
async function walk (currentDir) {
|
|
109
|
+
let entries;
|
|
110
|
+
try {
|
|
111
|
+
entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
112
|
+
} catch {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
for (const entry of entries) {
|
|
116
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
117
|
+
if (isIgnoredPath(fullPath, ignore)) continue;
|
|
118
|
+
if (entry.isDirectory()) {
|
|
119
|
+
await walk(fullPath);
|
|
120
|
+
} else if (entry.isFile() && extensions.some(ext => entry.name.endsWith(ext))) {
|
|
121
|
+
results.push(fullPath);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
await walk(dir);
|
|
126
|
+
return results;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// CLI
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
function printHelp () {
|
|
134
|
+
console.log(`
|
|
135
|
+
Usage: npx dialtone-migrate-border-radius [options]
|
|
136
|
+
|
|
137
|
+
Replaces deprecated physical border-radius utility classes with logical equivalents (DLT-3329).
|
|
138
|
+
|
|
139
|
+
d-bar6 → d-bar-350 (all-corners numeric → token stop)
|
|
140
|
+
d-btr8 → d-bbsr-400 (top pair → block-start pair)
|
|
141
|
+
d-bbr-pill → d-bber-pill (bottom pair → block-end pair)
|
|
142
|
+
d-blr12 → d-bisr-450 (left pair → inline-start pair)
|
|
143
|
+
d-brr-circle → d-bier-circle (right pair → inline-end pair)
|
|
144
|
+
|
|
145
|
+
Pair-prefix mapping:
|
|
146
|
+
btr → bbsr (top → block-start)
|
|
147
|
+
bbr → bber (bottom → block-end)
|
|
148
|
+
blr → bisr (left → inline-start)
|
|
149
|
+
brr → bier (right → inline-end)
|
|
150
|
+
|
|
151
|
+
Numeric-stop mapping:
|
|
152
|
+
0 → 0 1 → 100 2 → 200 4 → 300 6 → 350
|
|
153
|
+
8 → 400 12 → 450 16 → 500 24 → 550 32 → 600
|
|
154
|
+
|
|
155
|
+
Options:
|
|
156
|
+
--cwd <path> Working directory (default: current directory)
|
|
157
|
+
--dry-run Show changes without applying them
|
|
158
|
+
--yes Apply all changes without prompting
|
|
159
|
+
--help Show help
|
|
160
|
+
`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function parseArgs (args) {
|
|
164
|
+
const cwdIndex = args.indexOf('--cwd');
|
|
165
|
+
let cwd = process.cwd();
|
|
166
|
+
if (cwdIndex !== -1) {
|
|
167
|
+
const next = args[cwdIndex + 1];
|
|
168
|
+
if (!next || next.startsWith('--')) {
|
|
169
|
+
console.error('Error: --cwd requires a path argument.');
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
cwd = path.resolve(next);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
help: args.includes('--help'),
|
|
176
|
+
dryRun: args.includes('--dry-run'),
|
|
177
|
+
autoYes: args.includes('--yes'),
|
|
178
|
+
cwd,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function prompt (question) {
|
|
183
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
184
|
+
return new Promise(resolve => {
|
|
185
|
+
rl.question(question, answer => {
|
|
186
|
+
rl.close();
|
|
187
|
+
resolve(answer.trim().toLowerCase());
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// eslint-disable-next-line complexity
|
|
193
|
+
async function main () {
|
|
194
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
195
|
+
if (opts.help) {
|
|
196
|
+
printHelp();
|
|
197
|
+
process.exit(0);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
console.log(`\nScanning ${opts.cwd} for deprecated border-radius utility classes...\n`);
|
|
201
|
+
|
|
202
|
+
const extensions = ['.vue', '.md', '.html', '.js', '.ts', '.jsx', '.tsx'];
|
|
203
|
+
const ignore = ['node_modules', 'dist', '.git', '.vuepress/public', '.vuepress/.temp', '.vuepress/.cache', 'storybook-static'];
|
|
204
|
+
const files = await findFiles(opts.cwd, extensions, ignore);
|
|
205
|
+
|
|
206
|
+
const changes = [];
|
|
207
|
+
|
|
208
|
+
for (const file of files) {
|
|
209
|
+
try {
|
|
210
|
+
const content = await fs.readFile(file, 'utf8');
|
|
211
|
+
const { transformed, count } = transformContent(content);
|
|
212
|
+
if (count > 0) {
|
|
213
|
+
changes.push({ file, content, transformed, count });
|
|
214
|
+
}
|
|
215
|
+
} catch (err) {
|
|
216
|
+
console.warn(` ⚠ skipped (read error): ${path.relative(opts.cwd, file)} — ${err.message}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (changes.length === 0) {
|
|
221
|
+
console.log('No deprecated border-radius utility classes found. Nothing to migrate.');
|
|
222
|
+
process.exit(0);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
console.log(`Found ${changes.reduce((sum, c) => sum + c.count, 0)} deprecated border-radius class references across ${changes.length} file(s):\n`);
|
|
226
|
+
|
|
227
|
+
for (const { file, count } of changes) {
|
|
228
|
+
const rel = path.relative(opts.cwd, file);
|
|
229
|
+
console.log(` ${rel} (${count} change${count > 1 ? 's' : ''})`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (opts.dryRun) {
|
|
233
|
+
console.log('\n--dry-run: No files were modified.\n');
|
|
234
|
+
process.exit(0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (!opts.autoYes) {
|
|
238
|
+
const answer = await prompt('\nApply changes? (y/N) ');
|
|
239
|
+
if (answer !== 'y' && answer !== 'yes') {
|
|
240
|
+
console.log('Cancelled.');
|
|
241
|
+
process.exit(0);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
let written = 0;
|
|
246
|
+
let migratedRefs = 0;
|
|
247
|
+
for (const { file, transformed, count } of changes) {
|
|
248
|
+
try {
|
|
249
|
+
await fs.writeFile(file, transformed, 'utf8');
|
|
250
|
+
written++;
|
|
251
|
+
migratedRefs += count;
|
|
252
|
+
} catch (err) {
|
|
253
|
+
console.warn(` ⚠ skipped (write error): ${path.relative(opts.cwd, file)} — ${err.message}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
console.log(`\nMigrated ${migratedRefs} references across ${written} file(s).\n`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const isDirectRun = (() => {
|
|
261
|
+
try {
|
|
262
|
+
return realpathSync(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
263
|
+
} catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
})();
|
|
267
|
+
|
|
268
|
+
if (isDirectRun) {
|
|
269
|
+
main().catch(err => {
|
|
270
|
+
console.error(err);
|
|
271
|
+
process.exit(1);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Tests for dialtone-migrate-border-radius codemod.
|
|
5
|
+
* Run: node packages/dialtone-css/lib/build/js/dialtone_migrate_border_radius/test.mjs
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import assert from 'node:assert/strict';
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
import { describe, it } from 'node:test';
|
|
11
|
+
import { transformContent, RADIUS_STOP_MAP, PAIR_PREFIX_MAP } from './index.mjs';
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// All-corners numeric (d-barN → d-bar-STOP)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
describe('All-corners numeric renames', () => {
|
|
18
|
+
it('d-bar0 → d-bar-0', () => {
|
|
19
|
+
const { transformed, count } = transformContent('<div class="d-bar0" />');
|
|
20
|
+
assert.equal(transformed, '<div class="d-bar-0" />');
|
|
21
|
+
assert.equal(count, 1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('d-bar1 → d-bar-100', () => {
|
|
25
|
+
const { transformed } = transformContent('<div class="d-bar1" />');
|
|
26
|
+
assert.equal(transformed, '<div class="d-bar-100" />');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('d-bar2 → d-bar-200', () => {
|
|
30
|
+
const { transformed } = transformContent('<div class="d-bar2" />');
|
|
31
|
+
assert.equal(transformed, '<div class="d-bar-200" />');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('d-bar4 → d-bar-300', () => {
|
|
35
|
+
const { transformed } = transformContent('<div class="d-bar4" />');
|
|
36
|
+
assert.equal(transformed, '<div class="d-bar-300" />');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('d-bar6 → d-bar-350', () => {
|
|
40
|
+
const { transformed } = transformContent('<div class="d-bar6" />');
|
|
41
|
+
assert.equal(transformed, '<div class="d-bar-350" />');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('d-bar8 → d-bar-400', () => {
|
|
45
|
+
const { transformed } = transformContent('<div class="d-bar8" />');
|
|
46
|
+
assert.equal(transformed, '<div class="d-bar-400" />');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('d-bar12 → d-bar-450', () => {
|
|
50
|
+
const { transformed } = transformContent('<div class="d-bar12" />');
|
|
51
|
+
assert.equal(transformed, '<div class="d-bar-450" />');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('d-bar16 → d-bar-500', () => {
|
|
55
|
+
const { transformed } = transformContent('<div class="d-bar16" />');
|
|
56
|
+
assert.equal(transformed, '<div class="d-bar-500" />');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('d-bar24 → d-bar-550', () => {
|
|
60
|
+
const { transformed } = transformContent('<div class="d-bar24" />');
|
|
61
|
+
assert.equal(transformed, '<div class="d-bar-550" />');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('d-bar32 → d-bar-600', () => {
|
|
65
|
+
const { transformed } = transformContent('<div class="d-bar32" />');
|
|
66
|
+
assert.equal(transformed, '<div class="d-bar-600" />');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Pair numeric (d-{btr|bbr|blr|brr}N → d-{bbsr|bber|bisr|bier}-STOP)
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
describe('Pair numeric renames', () => {
|
|
75
|
+
it('d-btr6 → d-bbsr-350 (top → block-start)', () => {
|
|
76
|
+
const { transformed } = transformContent('<div class="d-btr6" />');
|
|
77
|
+
assert.equal(transformed, '<div class="d-bbsr-350" />');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('d-btr8 → d-bbsr-400', () => {
|
|
81
|
+
const { transformed } = transformContent('<div class="d-btr8" />');
|
|
82
|
+
assert.equal(transformed, '<div class="d-bbsr-400" />');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('d-bbr8 → d-bber-400 (bottom → block-end)', () => {
|
|
86
|
+
const { transformed } = transformContent('<div class="d-bbr8" />');
|
|
87
|
+
assert.equal(transformed, '<div class="d-bber-400" />');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('d-blr12 → d-bisr-450 (left → inline-start)', () => {
|
|
91
|
+
const { transformed } = transformContent('<div class="d-blr12" />');
|
|
92
|
+
assert.equal(transformed, '<div class="d-bisr-450" />');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('d-brr16 → d-bier-500 (right → inline-end)', () => {
|
|
96
|
+
const { transformed } = transformContent('<div class="d-brr16" />');
|
|
97
|
+
assert.equal(transformed, '<div class="d-bier-500" />');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// Pair keyword (d-{btr|bbr|blr|brr}-{pill|circle} → logical)
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
describe('Pair keyword renames', () => {
|
|
106
|
+
it('d-btr-pill → d-bbsr-pill', () => {
|
|
107
|
+
const { transformed } = transformContent('<div class="d-btr-pill" />');
|
|
108
|
+
assert.equal(transformed, '<div class="d-bbsr-pill" />');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('d-btr-circle → d-bbsr-circle', () => {
|
|
112
|
+
const { transformed } = transformContent('<div class="d-btr-circle" />');
|
|
113
|
+
assert.equal(transformed, '<div class="d-bbsr-circle" />');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('d-bbr-pill → d-bber-pill', () => {
|
|
117
|
+
const { transformed } = transformContent('<div class="d-bbr-pill" />');
|
|
118
|
+
assert.equal(transformed, '<div class="d-bber-pill" />');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('d-bbr-circle → d-bber-circle', () => {
|
|
122
|
+
const { transformed } = transformContent('<div class="d-bbr-circle" />');
|
|
123
|
+
assert.equal(transformed, '<div class="d-bber-circle" />');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('d-blr-pill → d-bisr-pill', () => {
|
|
127
|
+
const { transformed } = transformContent('<div class="d-blr-pill" />');
|
|
128
|
+
assert.equal(transformed, '<div class="d-bisr-pill" />');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('d-blr-circle → d-bisr-circle', () => {
|
|
132
|
+
const { transformed } = transformContent('<div class="d-blr-circle" />');
|
|
133
|
+
assert.equal(transformed, '<div class="d-bisr-circle" />');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('d-brr-pill → d-bier-pill', () => {
|
|
137
|
+
const { transformed } = transformContent('<div class="d-brr-pill" />');
|
|
138
|
+
assert.equal(transformed, '<div class="d-bier-pill" />');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('d-brr-circle → d-bier-circle', () => {
|
|
142
|
+
const { transformed } = transformContent('<div class="d-brr-circle" />');
|
|
143
|
+
assert.equal(transformed, '<div class="d-bier-circle" />');
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// Multiple classes in one attribute
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
describe('Multiple classes in one attribute', () => {
|
|
152
|
+
it('rewrites multiple legacy classes in one pass', () => {
|
|
153
|
+
const { transformed, count } = transformContent('<div class="d-bar6 d-btr8 d-blr-pill" />');
|
|
154
|
+
assert.equal(transformed, '<div class="d-bar-350 d-bbsr-400 d-bisr-pill" />');
|
|
155
|
+
assert.equal(count, 3);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('leaves non-radius classes untouched', () => {
|
|
159
|
+
const { transformed, count } = transformContent('<div class="d-p-200 d-bar6 d-fc-primary" />');
|
|
160
|
+
assert.equal(transformed, '<div class="d-p-200 d-bar-350 d-fc-primary" />');
|
|
161
|
+
assert.equal(count, 1);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Already-migrated classes — no changes
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
|
|
169
|
+
describe('Does NOT transform already-migrated classes', () => {
|
|
170
|
+
it('ignores d-bar-350 (already new format)', () => {
|
|
171
|
+
const { transformed, count } = transformContent('<div class="d-bar-350" />');
|
|
172
|
+
assert.equal(transformed, '<div class="d-bar-350" />');
|
|
173
|
+
assert.equal(count, 0);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('ignores d-bbsr-400', () => {
|
|
177
|
+
const { transformed, count } = transformContent('<div class="d-bbsr-400" />');
|
|
178
|
+
assert.equal(transformed, '<div class="d-bbsr-400" />');
|
|
179
|
+
assert.equal(count, 0);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('ignores d-bber-pill', () => {
|
|
183
|
+
const { transformed, count } = transformContent('<div class="d-bber-pill" />');
|
|
184
|
+
assert.equal(transformed, '<div class="d-bber-pill" />');
|
|
185
|
+
assert.equal(count, 0);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('ignores d-bisr-circle', () => {
|
|
189
|
+
const { transformed, count } = transformContent('<div class="d-bisr-circle" />');
|
|
190
|
+
assert.equal(transformed, '<div class="d-bisr-circle" />');
|
|
191
|
+
assert.equal(count, 0);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('ignores d-bar-pill (all-corners keyword, not deprecated)', () => {
|
|
195
|
+
const { transformed, count } = transformContent('<div class="d-bar-pill" />');
|
|
196
|
+
assert.equal(transformed, '<div class="d-bar-pill" />');
|
|
197
|
+
assert.equal(count, 0);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('ignores d-bar-circle (all-corners keyword, not deprecated)', () => {
|
|
201
|
+
const { transformed, count } = transformContent('<div class="d-bar-circle" />');
|
|
202
|
+
assert.equal(transformed, '<div class="d-bar-circle" />');
|
|
203
|
+
assert.equal(count, 0);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Does NOT match inside unrelated class names
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
describe('Does NOT match substrings inside other classes', () => {
|
|
212
|
+
it('ignores foo-d-bar6', () => {
|
|
213
|
+
const { transformed, count } = transformContent('<div class="foo-d-bar6" />');
|
|
214
|
+
assert.equal(transformed, '<div class="foo-d-bar6" />');
|
|
215
|
+
assert.equal(count, 0);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('ignores my-d-btr8', () => {
|
|
219
|
+
const { transformed, count } = transformContent('<div class="my-d-btr8" />');
|
|
220
|
+
assert.equal(transformed, '<div class="my-d-btr8" />');
|
|
221
|
+
assert.equal(count, 0);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('ignores app-d-brr-pill', () => {
|
|
225
|
+
const { transformed, count } = transformContent('<div class="app-d-brr-pill" />');
|
|
226
|
+
assert.equal(transformed, '<div class="app-d-brr-pill" />');
|
|
227
|
+
assert.equal(count, 0);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Unrelated classes — no false positives
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
describe('Does NOT touch unrelated utilities', () => {
|
|
236
|
+
it('ignores d-p-200 d-m-100 d-fc-primary', () => {
|
|
237
|
+
const input = '<div class="d-p-200 d-m-100 d-fc-primary" />';
|
|
238
|
+
const { transformed, count } = transformContent(input);
|
|
239
|
+
assert.equal(transformed, input);
|
|
240
|
+
assert.equal(count, 0);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('ignores d-ba d-baw2 d-bas-dashed', () => {
|
|
244
|
+
const input = '<div class="d-ba d-baw2 d-bas-dashed" />';
|
|
245
|
+
const { transformed, count } = transformContent(input);
|
|
246
|
+
assert.equal(transformed, input);
|
|
247
|
+
assert.equal(count, 0);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Different quote styles
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
|
|
255
|
+
describe('Different quote styles and contexts', () => {
|
|
256
|
+
it('handles single-quoted class attribute', () => {
|
|
257
|
+
const { transformed } = transformContent('<div class=\'d-btr8\' />');
|
|
258
|
+
assert.equal(transformed, '<div class=\'d-bbsr-400\' />');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('handles class in a Vue template', () => {
|
|
262
|
+
const input = '<template><div class="d-bar6 d-brr-circle" /></template>';
|
|
263
|
+
const expected = '<template><div class="d-bar-350 d-bier-circle" /></template>';
|
|
264
|
+
const { transformed } = transformContent(input);
|
|
265
|
+
assert.equal(transformed, expected);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
// Template literals (JS/TS backtick strings)
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
|
|
273
|
+
describe('Template literal delimiters', () => {
|
|
274
|
+
it('transforms d-bar6 inside a simple template literal', () => {
|
|
275
|
+
const input = 'const cls = `d-bar6`;';
|
|
276
|
+
const expected = 'const cls = `d-bar-350`;';
|
|
277
|
+
const { transformed, count } = transformContent(input);
|
|
278
|
+
assert.equal(transformed, expected);
|
|
279
|
+
assert.equal(count, 1);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('transforms pair keyword inside a template literal', () => {
|
|
283
|
+
const input = 'const cls = `d-btr-pill`;';
|
|
284
|
+
const expected = 'const cls = `d-bbsr-pill`;';
|
|
285
|
+
const { transformed } = transformContent(input);
|
|
286
|
+
assert.equal(transformed, expected);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('transforms pair numeric inside a template literal', () => {
|
|
290
|
+
const input = 'const cls = `d-brr16`;';
|
|
291
|
+
const expected = 'const cls = `d-bier-500`;';
|
|
292
|
+
const { transformed } = transformContent(input);
|
|
293
|
+
assert.equal(transformed, expected);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('transforms multiple classes inside a template literal', () => {
|
|
297
|
+
const input = 'const cls = `d-bar8 d-btr-circle`;';
|
|
298
|
+
const expected = 'const cls = `d-bar-400 d-bbsr-circle`;';
|
|
299
|
+
const { transformed, count } = transformContent(input);
|
|
300
|
+
assert.equal(transformed, expected);
|
|
301
|
+
assert.equal(count, 2);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('transforms class inside a template literal with interpolation', () => {
|
|
305
|
+
const input = 'const cls = `d-bar6 ${otherClass}`;';
|
|
306
|
+
const expected = 'const cls = `d-bar-350 ${otherClass}`;';
|
|
307
|
+
const { transformed, count } = transformContent(input);
|
|
308
|
+
assert.equal(transformed, expected);
|
|
309
|
+
assert.equal(count, 1);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('does not match inside a non-delimited context (no false positive)', () => {
|
|
313
|
+
const input = 'const cls = `foo-d-bar6`;';
|
|
314
|
+
const { transformed, count } = transformContent(input);
|
|
315
|
+
assert.equal(transformed, input);
|
|
316
|
+
assert.equal(count, 0);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// ---------------------------------------------------------------------------
|
|
321
|
+
// Edge cases
|
|
322
|
+
// ---------------------------------------------------------------------------
|
|
323
|
+
|
|
324
|
+
describe('Edge cases', () => {
|
|
325
|
+
it('returns count of 0 for content with no matches', () => {
|
|
326
|
+
const { count } = transformContent('<div><span>No radius here</span></div>');
|
|
327
|
+
assert.equal(count, 0);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('handles empty string', () => {
|
|
331
|
+
const { transformed, count } = transformContent('');
|
|
332
|
+
assert.equal(transformed, '');
|
|
333
|
+
assert.equal(count, 0);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('handles d-bar32 at end of attribute (before closing quote)', () => {
|
|
337
|
+
const { transformed } = transformContent('<div class="d-p-200 d-bar32" />');
|
|
338
|
+
assert.equal(transformed, '<div class="d-p-200 d-bar-600" />');
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('handles class at start of attribute (after opening quote)', () => {
|
|
342
|
+
const { transformed } = transformContent('<div class="d-bar6 d-p-200" />');
|
|
343
|
+
assert.equal(transformed, '<div class="d-bar-350 d-p-200" />');
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// ---------------------------------------------------------------------------
|
|
348
|
+
// Real-world patterns
|
|
349
|
+
// ---------------------------------------------------------------------------
|
|
350
|
+
|
|
351
|
+
describe('Real-world patterns', () => {
|
|
352
|
+
it('transforms radius in a card-like component', () => {
|
|
353
|
+
const input = '<div class="d-p-200 d-bgc-primary d-bar8 d-bs-sm">';
|
|
354
|
+
const expected = '<div class="d-p-200 d-bgc-primary d-bar-400 d-bs-sm">';
|
|
355
|
+
const { transformed } = transformContent(input);
|
|
356
|
+
assert.equal(transformed, expected);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it('transforms top-only radius on a header', () => {
|
|
360
|
+
const input = '<div class="d-btr6 d-bgc-moderate">';
|
|
361
|
+
const expected = '<div class="d-bbsr-350 d-bgc-moderate">';
|
|
362
|
+
const { transformed } = transformContent(input);
|
|
363
|
+
assert.equal(transformed, expected);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it('transforms bottom pill radius', () => {
|
|
367
|
+
const input = '<div class="d-bbr-pill d-bgc-info">';
|
|
368
|
+
const expected = '<div class="d-bber-pill d-bgc-info">';
|
|
369
|
+
const { transformed } = transformContent(input);
|
|
370
|
+
assert.equal(transformed, expected);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('transforms mixed numeric and keyword across multiple classes', () => {
|
|
374
|
+
const input = '<div class="d-bar6 d-btr-pill d-bbr-circle d-blr8 d-brr-pill">';
|
|
375
|
+
const expected = '<div class="d-bar-350 d-bbsr-pill d-bber-circle d-bisr-400 d-bier-pill">';
|
|
376
|
+
const { transformed, count } = transformContent(input);
|
|
377
|
+
assert.equal(transformed, expected);
|
|
378
|
+
assert.equal(count, 5);
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
// Contract: parity with ESLint rule maps
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
|
|
386
|
+
describe('Contract: maps match ESLint rule', () => {
|
|
387
|
+
const require = createRequire(import.meta.url);
|
|
388
|
+
|
|
389
|
+
let eslintSource;
|
|
390
|
+
try {
|
|
391
|
+
const fs = require('fs');
|
|
392
|
+
const path = require('path');
|
|
393
|
+
eslintSource = fs.readFileSync(
|
|
394
|
+
path.resolve(
|
|
395
|
+
import.meta.dirname,
|
|
396
|
+
'../../../../../eslint-plugin-dialtone/lib/rules/deprecated-radius-utility-classes.js',
|
|
397
|
+
),
|
|
398
|
+
'utf8',
|
|
399
|
+
);
|
|
400
|
+
} catch { /* will fail tests below with clear message */ }
|
|
401
|
+
|
|
402
|
+
function extractObject (source, varName) {
|
|
403
|
+
const re = new RegExp(`const ${varName}\\s*=\\s*\\{([^}]+)\\}`);
|
|
404
|
+
const match = source?.match(re);
|
|
405
|
+
if (!match) return null;
|
|
406
|
+
return Function(`return {${match[1]}}`)();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
it('RADIUS_STOP_MAP matches ESLint rule', () => {
|
|
410
|
+
assert.ok(eslintSource, 'Could not read ESLint rule source file');
|
|
411
|
+
const eslintMap = extractObject(eslintSource, 'RADIUS_STOP_MAP');
|
|
412
|
+
assert.ok(eslintMap, 'Could not parse RADIUS_STOP_MAP from ESLint rule');
|
|
413
|
+
assert.deepEqual(RADIUS_STOP_MAP, eslintMap);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('PAIR_PREFIX_MAP matches ESLint rule', () => {
|
|
417
|
+
assert.ok(eslintSource, 'Could not read ESLint rule source file');
|
|
418
|
+
const eslintMap = extractObject(eslintSource, 'PAIR_PREFIX_MAP');
|
|
419
|
+
assert.ok(eslintMap, 'Could not parse PAIR_PREFIX_MAP from ESLint rule');
|
|
420
|
+
assert.deepEqual(PAIR_PREFIX_MAP, eslintMap);
|
|
421
|
+
});
|
|
422
|
+
});
|