Skip to content

Commit 7e85ab2

Browse files
authored
Merge branch 'develop' into main
2 parents 1c5dd85 + 4a7885f commit 7e85ab2

21 files changed

+446
-277
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ will make the accessibility checker fail with status code 123 if the test suite
5353
### Linting Pass
5454
A typical linting pass would look like this:
5555
```
56-
npx srlint -p path/to/the/game
56+
npx srlint -p path/to/the/game/src
5757
```
5858

5959
This will start at the root of the passed directory, and crawl it looking for non-asset JavaScript and TypeScript files.

bin/srac

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
const packageJson = require('../package.json');
44
const { program } = require('commander');
5+
const { isDirectory } = require('../src/lib/path-validation.js');
56

6-
const { isDirectory } = require('../lib/path-validation.js');
7-
const runner = require('../lib/runner.js');
7+
const accessibilityChecker = require('../src').accessibilityChecker;
88

99
program.version(packageJson.version);
1010
program
@@ -18,20 +18,8 @@ if (!isDirectory(program.path)) {
1818
process.exit(program.exitCode);
1919
}
2020

21-
console.log('About to run tests');
22-
runner
23-
.runTests(program.path)
24-
.then((testResults) => {
25-
if (testResults.lastResult.failed > 0) {
26-
const failedCount = testResults.lastResult.failed;
27-
console.log(`${failedCount} test${failedCount > 1 ? 's' : ''} failed!`);
28-
process.exit(program.exitCode);
29-
} else {
30-
console.log('Done!');
31-
process.exit(0);
32-
}
33-
})
34-
.catch((e) => {
35-
console.error(e);
36-
process.exit(program.exitCode);
37-
});
21+
accessibilityChecker.run(program.path, true).then(() => {
22+
process.exit();
23+
}).catch(() => {
24+
process.exit(program.exitCode);
25+
});

bin/sras

Lines changed: 6 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,11 @@
33
const packageJson = require('../package.json');
44
const { program } = require('commander');
55

6-
const path = require('path');
76
const fs = require('fs');
8-
const promisify = require('util').promisify;
9-
const imageSize = require('image-size');
10-
const musicMetadata = require('music-metadata');
117

12-
const { isDirectory } = require('../lib/path-validation.js');
13-
const { formatHRTFileSize, formatMsToHRT } = require('../lib/format.js');
14-
const { parseSRASConfig } = require('../lib/srasConfig.js');
15-
const { isPowerOfTwo } = require('../lib/mathHelpers.js');
8+
const assetScanner = require('../src/').assetScanner;
9+
const { isDirectory } = require('../src/lib/path-validation.js');
1610

17-
let scannedFiles = 0;
18-
let skippedFiles = 0;
19-
let ignoredFiles = 0;
20-
21-
const scannedTypes = {};
22-
const unpermittedTypes = {};
23-
const scanReports = [];
24-
25-
const fsReadDir = promisify(fs.readdir);
26-
const fsStat = promisify(fs.stat);
27-
const sizeOf = promisify(imageSize);
28-
29-
const buildReportMsg = (...segments) => segments.join(' ');
3011
const fail = (err) => {
3112
console.log('Scan failed:');
3213
console.error(err);
@@ -46,205 +27,8 @@ if (!isDirectory(program.path)) {
4627
}
4728

4829
const config = JSON.parse(fs.readFileSync(program.config));
49-
const scanConfig = parseSRASConfig(config);
50-
51-
const scanJs = async (filePath, scanRules) => {
52-
try {
53-
const stat = await fsStat(filePath);
54-
const maxSize = scanRules.maxSize || Infinity;
55-
if (maxSize > 0 && stat.size > maxSize) {
56-
const fileName = path.basename(filePath);
57-
scanReports.push(buildReportMsg(
58-
'JS file size is larger than the recommended file size',
59-
`[recommended = ${formatHRTFileSize(maxSize)}],`,
60-
`[${fileName} = ${formatHRTFileSize(stat.size)}]`,
61-
));
62-
}
63-
} catch (e) {
64-
fail(e);
65-
}
66-
};
67-
68-
const scanImage = async (filePath, scanRules) => {
69-
try {
70-
const stat = await fsStat(filePath);
71-
const dimensions = await sizeOf(filePath);
72-
73-
const maxWidth = scanRules.maxWidth || Infinity;
74-
const maxHeight = scanRules.maxHeight || Infinity;
75-
const maxSize = scanRules.maxSize || Infinity;
76-
77-
const fileName = filePath.split('\\').pop();
78-
79-
if (dimensions.width > maxWidth || dimensions.height > maxHeight) {
80-
scanReports.push(buildReportMsg(
81-
'Image is larger than the recommended max dimensions',
82-
`[recommended = ${maxHeight}x${maxHeight}],`,
83-
`[${fileName} = ${dimensions.width}x${dimensions.height}]`,
84-
));
85-
}
86-
87-
if (!!scanRules.powerOfTwo && (!isPowerOfTwo(dimensions.width) || !isPowerOfTwo(dimensions.height))) {
88-
scanReports.push(buildReportMsg(
89-
'Image dimensions are recommended to be powers of two',
90-
`[${fileName} = ${dimensions.width}x${dimensions.height}]`,
91-
));
92-
}
93-
94-
if (maxSize > 0 && stat.size > maxSize) {
95-
scanReports.push(buildReportMsg(
96-
'Image file size is larger than the recommended file size',
97-
`[recommended = ${formatHRTFileSize(maxSize)}],`,
98-
`[${fileName} = ${formatHRTFileSize(stat.size)}]`,
99-
));
100-
}
101-
} catch (err) {
102-
fail(err);
103-
}
104-
};
105-
106-
const scanAudio = async (filePath, scanRules) => {
107-
try {
108-
const stat = await fsStat(filePath);
109-
const metadata = await musicMetadata.parseFile(filePath);
110-
111-
const maxSize = scanRules.maxSize || 0;
112-
const maxChannels = scanRules.maxChannels || 0;
113-
const sampleRate = scanRules.sampleRate || 0;
114-
const duration = scanRules.duration || 0;
115-
116-
const fileName = filePath.split('\\').pop();
117-
118-
if (maxSize > 0 && stat.size > maxSize) {
119-
scanReports.push(buildReportMsg(
120-
'Audio file size is larger than the recommended file size',
121-
`[recommended = ${maxSize}],`,
122-
`[${fileName} = ${formatHRTFileSize(stat.size)}]`,
123-
));
124-
}
125-
126-
if (maxChannels > 0 && metadata.format.numberOfChannels > maxChannels) {
127-
scanReports.push(buildReportMsg(
128-
'Audio file contains more than the recommended number of channels',
129-
`[recommended = ${maxChannels}],`,
130-
`[${fileName} = ${metadata.format.numberOfChannels}]`,
131-
));
132-
}
133-
134-
if (sampleRate > 0 && metadata.format.sampleRate !== sampleRate) {
135-
scanReports.push(buildReportMsg(
136-
'Audio sample rate does not match the recommended sample rate',
137-
`[recommended = ${sampleRate}],`,
138-
`[${fileName} = ${metadata.format.sampleRate}]`,
139-
));
140-
}
141-
142-
const convertedDuration = metadata.format.duration * 1000; // S to MS
143-
if (duration > 0 && convertedDuration > duration) {
144-
scanReports.push(buildReportMsg(
145-
'Audio duration is larger than recommended duration',
146-
`[recommended = ${duration}],`,
147-
`[${fileName} = ${convertedDuration}]`,
148-
));
149-
}
150-
} catch (err) {
151-
fail(err);
152-
}
153-
};
154-
155-
const scanDirectory = async (filePath) => {
156-
if (!isDirectory(filePath)) {
157-
const ext = path.extname(filePath).slice(1);
158-
159-
if (scanConfig.ignored.test(ext)) {
160-
// Track total ignored files.
161-
ignoredFiles++;
162-
return;
163-
} else if (scanConfig.unpermitted.test(ext)) {
164-
// Track how times we have scanned an this unpermitted file type.
165-
unpermittedTypes[ext] = (unpermittedTypes[ext] || 0) + 1;
166-
skippedFiles++; // skipped or ignored ??????
167-
return;
168-
}
169-
170-
// Check if there is a rule category for this file extension.
171-
const hasJsRule = scanConfig.codeRules && scanConfig.codeRules.js && ext === 'js';
172-
const hasImgRule = scanConfig.imgRules[ext] !== undefined;
173-
const hasAudRule = !hasImgRule && scanConfig.audRules[ext] !== undefined;
174-
175-
if (hasJsRule) {
176-
await scanJs(filePath, scanConfig.codeRules.js);
177-
} else if (hasImgRule) {
178-
await scanImage(filePath, scanConfig.imgRules[ext]);
179-
} else if (hasAudRule) {
180-
await scanAudio(filePath, scanConfig.audRules[ext]);
181-
} else {
182-
// Cannot find rules for this file type so it will be skipped.
183-
// Track total skipped files.
184-
skippedFiles++;
185-
return;
186-
}
187-
188-
// Track how many times we have scanned this file type.
189-
scannedTypes[ext] = (scannedTypes[ext] || 0) + 1;
190-
191-
// Track total scanned files.
192-
scannedFiles++;
193-
} else {
194-
try {
195-
const files = await fsReadDir(filePath);
196-
for (let i = 0; i < files.length; i++) {
197-
await scanDirectory(path.join(filePath, files[i]));
198-
}
199-
} catch (err) {
200-
fail(err);
201-
}
202-
}
203-
};
204-
205-
const assetScan = async () => {
206-
const startTime = Date.now();
207-
208-
console.log(`Scanning assets at [path = ${program.path}]`);
209-
210-
await scanDirectory(program.path);
211-
212-
const counts = [];
213-
const unpermittedReports = [];
214-
const missingRequiredReports = [];
215-
216-
Object.keys(scannedTypes).forEach((i) => counts.push(`${scannedTypes[i]} ${i}(s)`));
217-
Object.keys(unpermittedTypes).forEach((i) => unpermittedReports.push(
218-
`Detected ${unpermittedTypes[i]} unpermitted file type(s) [type = ${i}]`,
219-
));
220-
221-
scanConfig.requiredTypes.forEach((type) => {
222-
if (scannedTypes[type] === undefined) {
223-
missingRequiredReports.push(`Could not find file types matching [type = ${type}]`);
224-
}
225-
});
226-
227-
// RENDER SCAN REPORTS
228-
229-
if (scanReports.length > 0) {
230-
console.log(scanReports.join('\n'));
231-
}
232-
if (unpermittedReports.length > 0) {
233-
console.log(unpermittedReports.join('\n'));
234-
}
235-
if (missingRequiredReports.length > 0) {
236-
console.log(missingRequiredReports.join('\n'));
237-
}
238-
if (counts.length > 0) {
239-
console.log(`Scanned ${counts.join(', ')}`);
240-
}
241-
console.log(
242-
`Scan complete [time = ${formatMsToHRT(Date.now() - startTime)}]:`,
243-
`${scannedFiles} file(s) scanned, ${skippedFiles} file(s) skipped, ${ignoredFiles} file(s) ignored`,
244-
);
245-
30+
assetScanner.run(program.path, config, true).then(() => {
24631
process.exit();
247-
};
248-
249-
// Begin scanning
250-
assetScan();
32+
}).catch((err) => {
33+
fail(err);
34+
});

bin/srlint

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
#!/usr/bin/env node
22

33
const path = require('path');
4-
const eslint = require('eslint');
54
const packageJson = require('../package.json');
65
const { program } = require('commander');
7-
const expandPath = require('../lib/expand-path.js');
8-
const { isDirectory } = require('../lib/path-validation.js');
9-
const eslintignore = require('../lib/eslintignore.js');
10-
const pad = require('../lib/pad.js');
6+
const expandPath = require('../src/lib/expand-path.js');
7+
const { isDirectory } = require('../src/lib/path-validation.js');
8+
const fileLinter = require('../src').fileLinter;
119

1210
program.version(packageJson.version);
1311
program
@@ -23,32 +21,14 @@ if (!isDirectory(gameFullPath)) {
2321
process.exit(0);
2422
}
2523

26-
const cliEngine = new eslint.CLIEngine({
24+
const lintConfig = {
2725
configFile: path.resolve(__dirname, '../config/eslint.json'),
2826
extensions: [ '.js', '.ts' ],
2927
useEslintrc: false,
30-
});
31-
32-
// resolve the list of files and lint them
33-
const eslintIgnorePath = eslintignore.findEslintIgnore(gameFullPath);
34-
const filesToIgnore = eslintIgnorePath === null ? new Set() : eslintignore.expandEslintIgnore(eslintIgnorePath);
35-
const filesToLint = eslintignore.expandRootToNonIgnoredFiles(gameFullPath, filesToIgnore);
36-
const report = cliEngine.executeOnFiles(filesToLint);
37-
38-
for (const record of report.results) {
39-
if (record.errorCount === 0) {
40-
continue;
41-
}
28+
};
4229

43-
console.error(`${record.filePath}`);
44-
for (const message of record.messages) {
45-
const lineNumber = pad.left(`${message.line}`, 4, ' ');
46-
const column = pad.right(`${message.column}`, 4, ' ');
47-
const rule = pad.left(`${message.ruleId}`, 25, ' ');
48-
const paddedMessage = pad.left(`${message.message}`, 50, ' ');
49-
console.log(`${lineNumber}:${column} ${rule} ${paddedMessage}`);
50-
}
51-
}
52-
53-
const exitCode = report.errorCount === 0 ? 0 : program.exitCode;
54-
process.exit(exitCode);
30+
fileLinter.run(gameFullPath, lintConfig, true).then(() => {
31+
process.exit();
32+
}).catch(() => {
33+
process.exit(program.exitCode);
34+
});

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "springroll-automated-qa",
3-
"version": "1.0.3",
3+
"version": "1.1.0",
44
"description": "An automated QA tool for SpringRoll games",
5-
"main": "index.js",
5+
"main": "src/index.js",
66
"bin": {
77
"srac": "bin/srac",
88
"srlint": "bin/srlint",
99
"sras": "bin/sras"
1010
},
1111
"scripts": {
12-
"lint": "eslint --fix bin/* config/*.js lib/*.js tests/*.js",
12+
"lint": "eslint --fix bin/* config/*.js src/**/*.js tests/*.js",
1313
"start": "node index.js"
1414
},
1515
"keywords": [],

src/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
assetScanner: require('./tools/AssetScanner'),
3+
fileLinter: require('./tools/FileLinter'),
4+
accessibilityChecker: require('./tools/AccessibilityChecker'),
5+
};
File renamed without changes.

lib/eslintignore.js renamed to src/lib/eslintignore.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const expandPath = require('./expand-path');
22
const fs = require('fs');
33
const glob = require('glob');
44
const path = require('path');
5-
const { isFile } = require('../lib/path-validation.js');
5+
const { isFile } = require('./path-validation.js');
66

77
/**
88
* Crawls upward from a path, looking for an .eslintignore file
@@ -19,6 +19,10 @@ const findEslintIgnore = (startingPath) => {
1919
return eslintIgnorePath;
2020
}
2121

22+
if (currentDirectory === path.dirname(currentDirectory)) {
23+
return null;
24+
}
25+
2226
// Go back a directory and look there
2327
currentDirectory = path.dirname(currentDirectory);
2428
}
File renamed without changes.

0 commit comments

Comments
 (0)