pulse-js-framework 1.7.12 → 1.7.15
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/README.md +87 -7
- package/cli/docs.js +712 -0
- package/cli/doctor.js +702 -0
- package/cli/index.js +338 -65
- package/cli/scaffold.js +1037 -0
- package/cli/test.js +455 -0
- package/package.json +19 -3
- package/runtime/a11y.js +824 -1
- package/runtime/dom-adapter.js +663 -0
package/cli/test.js
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse CLI - Test Command
|
|
3
|
+
* Integrated test runner with coverage support
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, writeFileSync } from 'fs';
|
|
8
|
+
import { join, relative, resolve, dirname } from 'path';
|
|
9
|
+
import { log } from './logger.js';
|
|
10
|
+
import { findPulseFiles, parseArgs } from './utils/file-utils.js';
|
|
11
|
+
import { createTimer, formatDuration } from './utils/cli-ui.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default test file patterns
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_TEST_PATTERNS = [
|
|
17
|
+
'**/*.test.js',
|
|
18
|
+
'**/*.spec.js',
|
|
19
|
+
'**/*.test.pulse',
|
|
20
|
+
'**/*.spec.pulse',
|
|
21
|
+
'test/**/*.js',
|
|
22
|
+
'tests/**/*.js',
|
|
23
|
+
'__tests__/**/*.js'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Find test files in the project
|
|
28
|
+
* @param {string[]} patterns - Glob patterns
|
|
29
|
+
* @param {Object} options - Options
|
|
30
|
+
* @returns {string[]} Array of test file paths
|
|
31
|
+
*/
|
|
32
|
+
export function findTestFiles(patterns = [], options = {}) {
|
|
33
|
+
const { extensions = ['.js', '.mjs', '.ts'] } = options;
|
|
34
|
+
const files = new Set();
|
|
35
|
+
const root = process.cwd();
|
|
36
|
+
|
|
37
|
+
// Use provided patterns or defaults
|
|
38
|
+
const testPatterns = patterns.length > 0 ? patterns : DEFAULT_TEST_PATTERNS;
|
|
39
|
+
|
|
40
|
+
for (const pattern of testPatterns) {
|
|
41
|
+
// Skip options
|
|
42
|
+
if (pattern.startsWith('-')) continue;
|
|
43
|
+
|
|
44
|
+
if (pattern.includes('*')) {
|
|
45
|
+
// Glob pattern - simple implementation
|
|
46
|
+
const matches = globMatchTest(root, pattern, extensions);
|
|
47
|
+
for (const match of matches) {
|
|
48
|
+
files.add(match);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
const fullPath = resolve(root, pattern);
|
|
52
|
+
if (existsSync(fullPath)) {
|
|
53
|
+
const stat = statSync(fullPath);
|
|
54
|
+
if (stat.isDirectory()) {
|
|
55
|
+
walkDirTest(fullPath, files, extensions);
|
|
56
|
+
} else if (isTestFile(fullPath)) {
|
|
57
|
+
files.add(fullPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return Array.from(files).sort();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check if a file is a test file
|
|
68
|
+
*/
|
|
69
|
+
function isTestFile(filePath) {
|
|
70
|
+
return /\.(test|spec)\.(js|mjs|ts|pulse)$/.test(filePath) ||
|
|
71
|
+
/[\\/](test|tests|__tests__)[\\/]/.test(filePath);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Simple glob matching for test files
|
|
76
|
+
*/
|
|
77
|
+
function globMatchTest(base, pattern, extensions) {
|
|
78
|
+
const results = [];
|
|
79
|
+
|
|
80
|
+
function walk(dir) {
|
|
81
|
+
if (!existsSync(dir)) return;
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const entries = readdirSync(dir);
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
// Skip node_modules and hidden directories
|
|
87
|
+
if (entry === 'node_modules' || entry.startsWith('.')) continue;
|
|
88
|
+
|
|
89
|
+
const full = join(dir, entry);
|
|
90
|
+
try {
|
|
91
|
+
const stat = statSync(full);
|
|
92
|
+
if (stat.isDirectory()) {
|
|
93
|
+
walk(full);
|
|
94
|
+
} else if (isTestFile(full)) {
|
|
95
|
+
results.push(full);
|
|
96
|
+
}
|
|
97
|
+
} catch (e) {
|
|
98
|
+
// Skip inaccessible files
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (e) {
|
|
102
|
+
// Skip inaccessible directories
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
walk(base);
|
|
107
|
+
return results;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Walk directory for test files
|
|
112
|
+
*/
|
|
113
|
+
function walkDirTest(dir, results, extensions) {
|
|
114
|
+
try {
|
|
115
|
+
const entries = readdirSync(dir);
|
|
116
|
+
for (const entry of entries) {
|
|
117
|
+
if (entry === 'node_modules' || entry.startsWith('.')) continue;
|
|
118
|
+
|
|
119
|
+
const full = join(dir, entry);
|
|
120
|
+
try {
|
|
121
|
+
const stat = statSync(full);
|
|
122
|
+
if (stat.isDirectory()) {
|
|
123
|
+
walkDirTest(full, results, extensions);
|
|
124
|
+
} else if (isTestFile(full)) {
|
|
125
|
+
results.add(full);
|
|
126
|
+
}
|
|
127
|
+
} catch (e) {
|
|
128
|
+
// Skip inaccessible files
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} catch (e) {
|
|
132
|
+
// Skip inaccessible directories
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Run tests using Node.js built-in test runner
|
|
138
|
+
* @param {string[]} files - Test files to run
|
|
139
|
+
* @param {Object} options - Test options
|
|
140
|
+
* @returns {Promise<{passed: number, failed: number, skipped: number, duration: number}>}
|
|
141
|
+
*/
|
|
142
|
+
export async function runTests(files, options = {}) {
|
|
143
|
+
const {
|
|
144
|
+
coverage = false,
|
|
145
|
+
watch = false,
|
|
146
|
+
filter = null,
|
|
147
|
+
timeout = 30000,
|
|
148
|
+
concurrency = true,
|
|
149
|
+
reporter = 'spec',
|
|
150
|
+
bail = false,
|
|
151
|
+
verbose = false
|
|
152
|
+
} = options;
|
|
153
|
+
|
|
154
|
+
const timer = createTimer();
|
|
155
|
+
|
|
156
|
+
// Build Node.js test runner arguments
|
|
157
|
+
const nodeArgs = ['--test'];
|
|
158
|
+
|
|
159
|
+
// Coverage support (Node.js 20+)
|
|
160
|
+
if (coverage) {
|
|
161
|
+
nodeArgs.push('--experimental-test-coverage');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Watch mode
|
|
165
|
+
if (watch) {
|
|
166
|
+
nodeArgs.push('--watch');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Filter tests by name
|
|
170
|
+
if (filter) {
|
|
171
|
+
nodeArgs.push(`--test-name-pattern=${filter}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Test timeout
|
|
175
|
+
nodeArgs.push(`--test-timeout=${timeout}`);
|
|
176
|
+
|
|
177
|
+
// Concurrency
|
|
178
|
+
if (!concurrency) {
|
|
179
|
+
nodeArgs.push('--test-concurrency=1');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Reporter
|
|
183
|
+
if (reporter === 'tap') {
|
|
184
|
+
nodeArgs.push('--test-reporter=tap');
|
|
185
|
+
} else if (reporter === 'dot') {
|
|
186
|
+
nodeArgs.push('--test-reporter=dot');
|
|
187
|
+
} else if (reporter === 'json') {
|
|
188
|
+
nodeArgs.push('--test-reporter=json');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Bail on first failure
|
|
192
|
+
if (bail) {
|
|
193
|
+
nodeArgs.push('--test-only');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Add test files
|
|
197
|
+
nodeArgs.push(...files);
|
|
198
|
+
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
if (verbose) {
|
|
201
|
+
log.debug(`Running: node ${nodeArgs.join(' ')}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const child = spawn('node', nodeArgs, {
|
|
205
|
+
stdio: 'inherit',
|
|
206
|
+
cwd: process.cwd(),
|
|
207
|
+
env: {
|
|
208
|
+
...process.env,
|
|
209
|
+
NODE_ENV: 'test',
|
|
210
|
+
FORCE_COLOR: '1'
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
child.on('error', (error) => {
|
|
215
|
+
if (error.code === 'ENOENT') {
|
|
216
|
+
log.error('Node.js not found. Please ensure Node.js is installed.');
|
|
217
|
+
} else {
|
|
218
|
+
log.error(`Test runner error: ${error.message}`);
|
|
219
|
+
}
|
|
220
|
+
reject(error);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
child.on('close', (code) => {
|
|
224
|
+
const duration = timer.elapsed();
|
|
225
|
+
|
|
226
|
+
if (code === 0) {
|
|
227
|
+
resolve({ passed: true, code: 0, duration });
|
|
228
|
+
} else {
|
|
229
|
+
resolve({ passed: false, code, duration });
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Generate coverage report
|
|
237
|
+
* @param {Object} options - Report options
|
|
238
|
+
*/
|
|
239
|
+
export async function generateCoverageReport(options = {}) {
|
|
240
|
+
const { format = 'text', outputDir = 'coverage' } = options;
|
|
241
|
+
|
|
242
|
+
// Node.js coverage generates v8 coverage files
|
|
243
|
+
// We can use c8 or similar tools if available
|
|
244
|
+
|
|
245
|
+
// Check if c8 is available
|
|
246
|
+
try {
|
|
247
|
+
const { execSync } = await import('child_process');
|
|
248
|
+
execSync('npx c8 --version', { stdio: 'ignore' });
|
|
249
|
+
|
|
250
|
+
log.info('\nGenerating coverage report...');
|
|
251
|
+
|
|
252
|
+
const reportCmd = `npx c8 report --reporter=${format}`;
|
|
253
|
+
if (format !== 'text') {
|
|
254
|
+
// Create output directory
|
|
255
|
+
if (!existsSync(outputDir)) {
|
|
256
|
+
mkdirSync(outputDir, { recursive: true });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
execSync(reportCmd, { stdio: 'inherit', cwd: process.cwd() });
|
|
261
|
+
} catch (e) {
|
|
262
|
+
log.info('\nTo generate detailed coverage reports, install c8:');
|
|
263
|
+
log.info(' npm install -D c8');
|
|
264
|
+
log.info('\nThen run: npx c8 npm test');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Create a test file template
|
|
270
|
+
* @param {string} name - Test name
|
|
271
|
+
* @param {string} type - Test type (unit, integration, e2e)
|
|
272
|
+
* @returns {string} Test file content
|
|
273
|
+
*/
|
|
274
|
+
export function createTestTemplate(name, type = 'unit') {
|
|
275
|
+
const pascalName = name.replace(/[-_]./g, m => m[1].toUpperCase())
|
|
276
|
+
.replace(/^./, m => m.toUpperCase());
|
|
277
|
+
|
|
278
|
+
if (type === 'e2e') {
|
|
279
|
+
return `/**
|
|
280
|
+
* E2E Test: ${pascalName}
|
|
281
|
+
*/
|
|
282
|
+
|
|
283
|
+
import { test, describe, before, after } from 'node:test';
|
|
284
|
+
import assert from 'node:assert';
|
|
285
|
+
|
|
286
|
+
describe('${pascalName} E2E', () => {
|
|
287
|
+
before(async () => {
|
|
288
|
+
// Setup: Start server, initialize browser, etc.
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
after(async () => {
|
|
292
|
+
// Cleanup: Stop server, close browser, etc.
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test('should load the page', async () => {
|
|
296
|
+
// Your e2e test logic here
|
|
297
|
+
assert.ok(true);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test('should handle user interaction', async () => {
|
|
301
|
+
// Your e2e test logic here
|
|
302
|
+
assert.ok(true);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
`;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (type === 'integration') {
|
|
309
|
+
return `/**
|
|
310
|
+
* Integration Test: ${pascalName}
|
|
311
|
+
*/
|
|
312
|
+
|
|
313
|
+
import { test, describe, beforeEach, afterEach } from 'node:test';
|
|
314
|
+
import assert from 'node:assert';
|
|
315
|
+
|
|
316
|
+
describe('${pascalName} Integration', () => {
|
|
317
|
+
let context;
|
|
318
|
+
|
|
319
|
+
beforeEach(() => {
|
|
320
|
+
// Setup test context
|
|
321
|
+
context = {};
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
afterEach(() => {
|
|
325
|
+
// Cleanup
|
|
326
|
+
context = null;
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test('should integrate components correctly', async () => {
|
|
330
|
+
// Your integration test logic here
|
|
331
|
+
assert.ok(true);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test('should handle data flow', async () => {
|
|
335
|
+
// Your integration test logic here
|
|
336
|
+
assert.ok(true);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Default: unit test
|
|
343
|
+
return `/**
|
|
344
|
+
* Unit Test: ${pascalName}
|
|
345
|
+
*/
|
|
346
|
+
|
|
347
|
+
import { test, describe } from 'node:test';
|
|
348
|
+
import assert from 'node:assert';
|
|
349
|
+
|
|
350
|
+
// Import the module to test
|
|
351
|
+
// import { ${name} } from '../src/${name}.js';
|
|
352
|
+
|
|
353
|
+
describe('${pascalName}', () => {
|
|
354
|
+
test('should exist', () => {
|
|
355
|
+
// Replace with actual test
|
|
356
|
+
assert.ok(true);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
test('should handle basic case', () => {
|
|
360
|
+
// Your test logic here
|
|
361
|
+
assert.ok(true);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test('should handle edge cases', () => {
|
|
365
|
+
// Your test logic here
|
|
366
|
+
assert.ok(true);
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
`;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Main test command handler
|
|
374
|
+
*/
|
|
375
|
+
export async function runTestCommand(args) {
|
|
376
|
+
const { options, patterns } = parseArgs(args);
|
|
377
|
+
|
|
378
|
+
const coverage = options.coverage || options.c || false;
|
|
379
|
+
const watch = options.watch || options.w || false;
|
|
380
|
+
const filter = options.filter || options.f || null;
|
|
381
|
+
const timeout = parseInt(options.timeout || options.t || '30000', 10);
|
|
382
|
+
const reporter = options.reporter || options.r || 'spec';
|
|
383
|
+
const bail = options.bail || options.b || false;
|
|
384
|
+
const verbose = options.verbose || options.v || false;
|
|
385
|
+
const create = options.create || null;
|
|
386
|
+
|
|
387
|
+
// Handle --create flag to generate test file
|
|
388
|
+
if (create) {
|
|
389
|
+
const testType = options.type || 'unit';
|
|
390
|
+
const testContent = createTestTemplate(create, testType);
|
|
391
|
+
const testDir = options.dir || 'test';
|
|
392
|
+
const testPath = join(process.cwd(), testDir, `${create}.test.js`);
|
|
393
|
+
|
|
394
|
+
// Create test directory if needed
|
|
395
|
+
const dir = dirname(testPath);
|
|
396
|
+
if (!existsSync(dir)) {
|
|
397
|
+
mkdirSync(dir, { recursive: true });
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
writeFileSync(testPath, testContent);
|
|
401
|
+
log.success(`Created test file: ${relative(process.cwd(), testPath)}`);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Find test files
|
|
406
|
+
const files = findTestFiles(patterns);
|
|
407
|
+
|
|
408
|
+
if (files.length === 0) {
|
|
409
|
+
log.warn('No test files found.');
|
|
410
|
+
log.info('\nLooking for files matching:');
|
|
411
|
+
for (const pattern of DEFAULT_TEST_PATTERNS) {
|
|
412
|
+
log.info(` - ${pattern}`);
|
|
413
|
+
}
|
|
414
|
+
log.info('\nTo create a test file:');
|
|
415
|
+
log.info(' pulse test --create <name>');
|
|
416
|
+
log.info(' pulse test --create <name> --type integration');
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
log.info(`Found ${files.length} test file(s)\n`);
|
|
421
|
+
|
|
422
|
+
if (verbose) {
|
|
423
|
+
for (const file of files) {
|
|
424
|
+
log.debug(` ${relative(process.cwd(), file)}`);
|
|
425
|
+
}
|
|
426
|
+
log.debug('');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Run tests
|
|
430
|
+
const result = await runTests(files, {
|
|
431
|
+
coverage,
|
|
432
|
+
watch,
|
|
433
|
+
filter,
|
|
434
|
+
timeout,
|
|
435
|
+
reporter,
|
|
436
|
+
bail,
|
|
437
|
+
verbose
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// Generate coverage report if requested
|
|
441
|
+
if (coverage && !watch && result.passed) {
|
|
442
|
+
await generateCoverageReport({ format: options.format || 'text' });
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Print summary
|
|
446
|
+
const durationStr = formatDuration(result.duration);
|
|
447
|
+
log.info('');
|
|
448
|
+
|
|
449
|
+
if (result.passed) {
|
|
450
|
+
log.success(`Tests passed (${durationStr})`);
|
|
451
|
+
} else {
|
|
452
|
+
log.error(`Tests failed with code ${result.code} (${durationStr})`);
|
|
453
|
+
process.exit(result.code);
|
|
454
|
+
}
|
|
455
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pulse-js-framework",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.15",
|
|
4
4
|
"description": "A declarative DOM framework with CSS selector-based structure and reactive pulsations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"./compiler/lexer": "./compiler/lexer.js",
|
|
89
89
|
"./compiler/parser": "./compiler/parser.js",
|
|
90
90
|
"./compiler/transformer": "./compiler/transformer.js",
|
|
91
|
-
"./core/errors": "./
|
|
91
|
+
"./core/errors": "./runtime/errors.js",
|
|
92
92
|
"./vite": {
|
|
93
93
|
"types": "./types/index.d.ts",
|
|
94
94
|
"default": "./loader/vite-plugin.js"
|
|
@@ -109,14 +109,17 @@
|
|
|
109
109
|
"LICENSE"
|
|
110
110
|
],
|
|
111
111
|
"scripts": {
|
|
112
|
-
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:dom-adapter && npm run test:router && npm run test:store && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze && npm run test:cli && npm run test:cli-ui && npm run test:lru-cache && npm run test:utils && npm run test:docs && npm run test:async && npm run test:form && npm run test:http && npm run test:devtools && npm run test:native && npm run test:a11y && npm run test:logger && npm run test:errors && npm run test:security && npm run test:websocket && npm run test:graphql",
|
|
112
|
+
"test": "npm run test:compiler && npm run test:sourcemap && npm run test:pulse && npm run test:dom && npm run test:dom-element && npm run test:dom-adapter && npm run test:enhanced-mock-adapter && npm run test:router && npm run test:store && npm run test:context && npm run test:hmr && npm run test:lint && npm run test:format && npm run test:analyze && npm run test:cli && npm run test:cli-ui && npm run test:lru-cache && npm run test:utils && npm run test:docs && npm run test:docs-nav && npm run test:async && npm run test:form && npm run test:http && npm run test:devtools && npm run test:native && npm run test:a11y && npm run test:a11y-enhanced && npm run test:logger && npm run test:errors && npm run test:security && npm run test:websocket && npm run test:graphql && npm run test:doctor && npm run test:scaffold && npm run test:test-runner && npm run test:build && npm run test:integration && npm run test:context-stress && npm run test:form-edge-cases && npm run test:graphql-subscriptions && npm run test:http-edge-cases && npm run test:integration-advanced && npm run test:websocket-stress",
|
|
113
113
|
"test:compiler": "node test/compiler.test.js",
|
|
114
114
|
"test:sourcemap": "node test/sourcemap.test.js",
|
|
115
115
|
"test:pulse": "node test/pulse.test.js",
|
|
116
116
|
"test:dom": "node test/dom.test.js",
|
|
117
|
+
"test:dom-element": "node test/dom-element.test.js",
|
|
117
118
|
"test:dom-adapter": "node test/dom-adapter.test.js",
|
|
119
|
+
"test:enhanced-mock-adapter": "node test/enhanced-mock-adapter.test.js",
|
|
118
120
|
"test:router": "node test/router.test.js",
|
|
119
121
|
"test:store": "node test/store.test.js",
|
|
122
|
+
"test:context": "node test/context.test.js",
|
|
120
123
|
"test:hmr": "node test/hmr.test.js",
|
|
121
124
|
"test:lint": "node test/lint.test.js",
|
|
122
125
|
"test:format": "node test/format.test.js",
|
|
@@ -126,17 +129,30 @@
|
|
|
126
129
|
"test:lru-cache": "node test/lru-cache.test.js",
|
|
127
130
|
"test:utils": "node test/utils.test.js",
|
|
128
131
|
"test:docs": "node test/docs.test.js",
|
|
132
|
+
"test:docs-nav": "node test/docs-navigation.test.js",
|
|
129
133
|
"test:async": "node test/async.test.js",
|
|
130
134
|
"test:form": "node test/form.test.js",
|
|
131
135
|
"test:http": "node test/http.test.js",
|
|
132
136
|
"test:devtools": "node test/devtools.test.js",
|
|
133
137
|
"test:native": "node test/native.test.js",
|
|
134
138
|
"test:a11y": "node test/a11y.test.js",
|
|
139
|
+
"test:a11y-enhanced": "node test/a11y-enhanced.test.js",
|
|
135
140
|
"test:logger": "node test/logger.test.js",
|
|
136
141
|
"test:errors": "node test/errors.test.js",
|
|
137
142
|
"test:security": "node test/security.test.js",
|
|
138
143
|
"test:websocket": "node test/websocket.test.js",
|
|
139
144
|
"test:graphql": "node test/graphql.test.js",
|
|
145
|
+
"test:doctor": "node test/doctor.test.js",
|
|
146
|
+
"test:scaffold": "node test/scaffold.test.js",
|
|
147
|
+
"test:test-runner": "node test/test-runner.test.js",
|
|
148
|
+
"test:build": "node test/build.test.js",
|
|
149
|
+
"test:integration": "node test/integration.test.js",
|
|
150
|
+
"test:context-stress": "node test/context-stress.test.js",
|
|
151
|
+
"test:form-edge-cases": "node test/form-edge-cases.test.js",
|
|
152
|
+
"test:graphql-subscriptions": "node test/graphql-subscriptions.test.js",
|
|
153
|
+
"test:http-edge-cases": "node test/http-edge-cases.test.js",
|
|
154
|
+
"test:integration-advanced": "node test/integration-advanced.test.js",
|
|
155
|
+
"test:websocket-stress": "node test/websocket-stress.test.js",
|
|
140
156
|
"build:netlify": "node scripts/build-netlify.js",
|
|
141
157
|
"version": "node scripts/sync-version.js",
|
|
142
158
|
"docs": "node cli/index.js dev docs"
|