Merge pull request #59 from LLK/IBE-198-fix-scratch-analysis-bug-that-causes-problem-for-crawler-downstream

Fix for IBE-198
This commit is contained in:
Colby Gutierrez-Kraybill 2022-05-27 12:25:04 -04:00 committed by GitHub
commit 83afe49c90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 311 additions and 101 deletions

View file

@ -1,3 +1,7 @@
{
"parser": "@babel/eslint-parser",
"parserOptions": {
"requireConfigFile": false
},
"extends": ["scratch", "scratch/node"]
}

View file

@ -1,15 +1,14 @@
language: node_js
node_js:
- 8
- 10
- node
- 16
- lts/*
cache:
directories:
- node_modules
jobs:
include:
- stage: release
node_js: 10
node_js: 16
script: echo deploying...
deploy:
- provider: script

8
Dockerfile Normal file
View file

@ -0,0 +1,8 @@
FROM node:16
RUN mkdir -p /var/app/current
WORKDIR /var/app/current
COPY . ./
RUN rm -rf ./node_modules
RUN npm install
RUN npm install -g nodemon tap

30
docker-compose.yml Normal file
View file

@ -0,0 +1,30 @@
version: '3.4'
volumes:
npm_data:
runtime_data:
networks:
default:
external:
name: scratchapi_scratch_network
services:
app:
container_name: scratch-analysis-lib
hostname: scratch-analysis
build:
context: ./
dockerfile: Dockerfile
image: scratch-analysis:latest
command: node -e "require('http').createServer((req, res) => { res.end('OK'); }).listen(8080, () => {console.log('Listening on 8080'); } );"
volumes:
- type: bind
source: ./
target: /var/app/current
consistency: cached
volume:
nocopy: true
- npm_data:/var/app/current/node_modules
- runtime_data:/runtime
ports:
- "9999:8080"

View file

@ -77,7 +77,7 @@ const sprites = function (input) {
let result = 0;
for (let i in input.children) {
if (input.children[i].hasOwnProperty('spriteInfo')) result++;
if (Object.prototype.hasOwnProperty.call(input.children[i], 'spriteInfo')) result++;
}
return {count: result};

View file

@ -120,8 +120,8 @@ const blocks = function (targets) {
const extensions = function (list) {
return {
count: list.length,
id: list
count: (typeof list === 'object' ? list.length : 0),
id: (typeof list === 'object' ? list : [])
};
};

View file

@ -1,6 +1,6 @@
{
"name": "scratch-analysis",
"version": "0.0.0",
"version": "1.0.0",
"description": "Analysis tool for summarizing the structure, composition, and complexity of Scratch programs.",
"main": "lib/index.js",
"directories": {
@ -8,11 +8,9 @@
"test": "test"
},
"scripts": {
"test": "npm run test:lint && npm run test:unit && npm run test:integration",
"test": "npm run test:lint && npm run test:unit",
"test:lint": "eslint .",
"test:unit": "tap test/unit/*.js",
"test:integration": "tap test/integration/*.js",
"test:coverage": "tap test/{unit,integration}/*.js --coverage --coverage-report=lcov"
"test:unit": "tap --reporter nyan test/unit/*.js --statements=97 --branches=97"
},
"author": "Scratch Foundation",
"license": "BSD-3-Clause",
@ -20,9 +18,9 @@
"scratch-parser": "5.0.0"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
"eslint": "^5.10.0",
"eslint-config-scratch": "^5.0.0",
"tap": "^12.1.1"
"@babel/eslint-parser": "^7.5.4",
"eslint": "^8.16.0",
"eslint-config-scratch": "^7.0.0",
"tap": "^16.2.0"
}
}

103
test/fixtures/sb3/badExtensions.json vendored Normal file
View file

@ -0,0 +1,103 @@
{
"targets": [
{
"isStage": true,
"name": "Stage",
"variables": {
"`jEk@4|i[#Fk?(8x)AV.-my variable": [
"my variable",
0
]
},
"lists": {},
"broadcasts": {},
"blocks": {},
"comments": {},
"currentCostume": 0,
"costumes": [
{
"assetId": "cd21514d0531fdffb22204e0ec5ed84a",
"name": "backdrop1",
"md5ext": "cd21514d0531fdffb22204e0ec5ed84a.svg",
"dataFormat": "svg",
"rotationCenterX": 240,
"rotationCenterY": 180
}
],
"sounds": [
{
"assetId": "83a9787d4cb6f3b7632b4ddfebf74367",
"name": "pop",
"dataFormat": "wav",
"format": "",
"rate": 44100,
"sampleCount": 1032,
"md5ext": "83a9787d4cb6f3b7632b4ddfebf74367.wav"
}
],
"volume": 100,
"layerOrder": 0,
"tempo": 60,
"videoTransparency": 50,
"videoState": "on",
"textToSpeechLanguage": null
},
{
"isStage": false,
"name": "Sprite1",
"variables": {},
"lists": {},
"broadcasts": {},
"blocks": {},
"comments": {},
"currentCostume": 0,
"costumes": [
{
"assetId": "b7853f557e4426412e64bb3da6531a99",
"name": "costume1",
"bitmapResolution": 1,
"md5ext": "b7853f557e4426412e64bb3da6531a99.svg",
"dataFormat": "svg",
"rotationCenterX": 48,
"rotationCenterY": 50
},
{
"assetId": "e6ddc55a6ddd9cc9d84fe0b4c21e016f",
"name": "costume2",
"bitmapResolution": 1,
"md5ext": "e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg",
"dataFormat": "svg",
"rotationCenterX": 46,
"rotationCenterY": 53
}
],
"sounds": [
{
"assetId": "83c36d806dc92327b9e7049a565c6bff",
"name": "Meow",
"dataFormat": "wav",
"format": "",
"rate": 44100,
"sampleCount": 37376,
"md5ext": "83c36d806dc92327b9e7049a565c6bff.wav"
}
],
"volume": 100,
"layerOrder": 1,
"visible": true,
"x": 0,
"y": 0,
"size": 100,
"direction": 90,
"draggable": false,
"rotationStyle": "all around"
}
],
"monitors": [],
"meta": {
"semver": "3.0.0",
"vm": "0.2.0-prerelease.20181217191056",
"agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"origin": "test.scratch.mit.edu"
}
}

View file

@ -18,33 +18,33 @@ const sb3Complex = fs.readFileSync(
test('sb2', t => {
analysis(sb2, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.cloud, 'object');
t.equals(result.cloud.count, 1);
t.deepEquals(result.cloud.id, ['☁ baz']);
t.equal(result.cloud.count, 1);
t.same(result.cloud.id, ['☁ baz']);
t.end();
});
});
test('sb3', t => {
analysis(sb3, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.cloud, 'object');
t.equals(result.cloud.count, 1);
t.deepEquals(result.cloud.id, ['☁ baz']);
t.equal(result.cloud.count, 1);
t.same(result.cloud.id, ['☁ baz']);
t.end();
});
});
test('sb2 complex', t => {
analysis(sb2Complex, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.cloud, 'object');
t.equals(result.cloud.count, 8);
t.deepEquals(result.cloud.id, [
t.equal(result.cloud.count, 8);
t.same(result.cloud.id, [
'☁ Player_1',
'☁ Player_2',
'☁ Player_3',
@ -60,11 +60,11 @@ test('sb2 complex', t => {
test('sb3 complex', t => {
analysis(sb3Complex, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.cloud, 'object');
t.equals(result.cloud.count, 8);
t.deepEquals(result.cloud.id, [
t.equal(result.cloud.count, 8);
t.same(result.cloud.id, [
'☁ Player_1',
'☁ Player_2',
'☁ Player_3',

View file

@ -12,11 +12,11 @@ const sb3 = fs.readFileSync(
test('sb2', t => {
analysis(sb2, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.blocks, 'object');
t.type(result.blocks.id, 'object');
t.deepEquals(result.blocks.id, [
t.same(result.blocks.id, [
'whenGreenFlag',
'doForever',
'setVar:to:',
@ -36,11 +36,11 @@ test('sb2', t => {
test('sb3', t => {
analysis(sb3, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.blocks, 'object');
t.type(result.blocks.id, 'object');
t.deepEquals(result.blocks.id, [
t.same(result.blocks.id, [
'event_whenflagclicked',
'control_forever',
'control_wait',

View file

@ -13,9 +13,9 @@ const complexBinary = fs.readFileSync(
path.resolve(__dirname, '../fixtures/sb2/complex.sb2')
);
test('defalt (object)', t => {
test('default (object)', t => {
analysis(defaultObject, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
@ -23,34 +23,34 @@ test('defalt (object)', t => {
t.type(result.variables, 'object');
t.equal(result.variables.count, 0);
t.deepEqual(result.variables.id, []);
t.same(result.variables.id, []);
t.type(result.lists, 'object');
t.equal(result.lists.count, 0);
t.deepEqual(result.lists.id, []);
t.same(result.lists.id, []);
t.type(result.comments, 'object');
t.equal(result.comments.count, 0);
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.deepEqual(result.sounds.id, [
t.same(result.sounds.id, [
'pop',
'meow'
]);
t.deepEqual(result.sounds.hash, [
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.deepEqual(result.costumes.id, [
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.deepEqual(result.costumes.hash, [
t.same(result.costumes.hash, [
'739b5e2a2435f6e1ec2993791b423146.png',
'09dc888b0b7df19f70d81588ae73420e.svg',
'3696356a03a8d938318876a593572843.svg'
@ -62,23 +62,23 @@ test('defalt (object)', t => {
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 0);
t.equal(result.blocks.unique, 0);
t.deepEqual(result.blocks.id, []);
t.deepEqual(result.blocks.frequency, {});
t.same(result.blocks.id, []);
t.same(result.blocks.frequency, {});
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 0);
t.deepEqual(result.extensions.id, []);
t.same(result.extensions.id, []);
t.type(result.meta, 'object');
t.deepEqual(result.meta, {});
t.same(result.meta, {});
t.end();
});
});
test('defalt (binary)', t => {
test('default (binary)', t => {
analysis(defaultBinary, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
@ -86,34 +86,34 @@ test('defalt (binary)', t => {
t.type(result.variables, 'object');
t.equal(result.variables.count, 0);
t.deepEqual(result.variables.id, []);
t.same(result.variables.id, []);
t.type(result.lists, 'object');
t.equal(result.lists.count, 0);
t.deepEqual(result.lists.id, []);
t.same(result.lists.id, []);
t.type(result.comments, 'object');
t.equal(result.comments.count, 0);
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.deepEqual(result.sounds.id, [
t.same(result.sounds.id, [
'pop',
'meow'
]);
t.deepEqual(result.sounds.hash, [
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.deepEqual(result.costumes.id, [
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.deepEqual(result.costumes.hash, [
t.same(result.costumes.hash, [
'739b5e2a2435f6e1ec2993791b423146.png',
'f9a1c175dbe2e5dee472858dd30d16bb.svg',
'6e8bd9ae68fdb02b7e1e3df656a75635.svg'
@ -125,12 +125,12 @@ test('defalt (binary)', t => {
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 0);
t.equal(result.blocks.unique, 0);
t.deepEqual(result.blocks.id, []);
t.deepEqual(result.blocks.frequency, {});
t.same(result.blocks.id, []);
t.same(result.blocks.frequency, {});
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 0);
t.deepEqual(result.extensions.id, []);
t.same(result.extensions.id, []);
t.end();
});
@ -138,7 +138,7 @@ test('defalt (binary)', t => {
test('complex (binary)', t => {
analysis(complexBinary, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
@ -146,14 +146,14 @@ test('complex (binary)', t => {
t.type(result.variables, 'object');
t.equal(result.variables.count, 2);
t.deepEqual(result.variables.id, [
t.same(result.variables.id, [
'global',
'local'
]);
t.type(result.lists, 'object');
t.equal(result.lists.count, 2);
t.deepEqual(result.lists.id, [
t.same(result.lists.id, [
'globallist',
'locallist'
]);
@ -163,23 +163,23 @@ test('complex (binary)', t => {
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.deepEqual(result.sounds.id, [
t.same(result.sounds.id, [
'pop',
'meow'
]);
t.deepEqual(result.sounds.hash, [
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.deepEqual(result.costumes.id, [
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.deepEqual(result.costumes.hash, [
t.same(result.costumes.hash, [
'5b465b3b07d39019109d8dc6d6ee6593.svg',
'f9a1c175dbe2e5dee472858dd30d16bb.svg',
'6e8bd9ae68fdb02b7e1e3df656a75635.svg'
@ -191,7 +191,7 @@ test('complex (binary)', t => {
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 34);
t.equal(result.blocks.unique, 18);
t.deepEqual(result.blocks.id, [
t.same(result.blocks.id, [
'whenGreenFlag',
'doForever',
'changeGraphicEffect:by:',
@ -227,7 +227,7 @@ test('complex (binary)', t => {
'LEGO WeDo 2.0\u001FsetLED',
'randomFrom:to:'
]);
t.deepEqual(result.blocks.frequency, {
t.same(result.blocks.frequency, {
'LEGO WeDo 2.0\u001FsetLED': 1,
'LEGO WeDo 2.0\u001FwhenTilted': 1,
'bounceOffEdge': 1,
@ -250,7 +250,7 @@ test('complex (binary)', t => {
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 1);
t.deepEqual(result.extensions.id, [
t.same(result.extensions.id, [
'LEGO WeDo 2.0'
]);

View file

@ -17,9 +17,13 @@ const extensionsBinary = fs.readFileSync(
path.resolve(__dirname, '../fixtures/sb3/extensions.sb3')
);
test('defalt (object)', t => {
const badExtensions = fs.readFileSync(
path.resolve(__dirname, '../fixtures/sb3/badExtensions.json')
);
test('default (object)', t => {
analysis(defaultObject, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
@ -27,36 +31,36 @@ test('defalt (object)', t => {
t.type(result.variables, 'object');
t.equal(result.variables.count, 1);
t.deepEqual(result.variables.id, [
t.same(result.variables.id, [
'my variable'
]);
t.type(result.lists, 'object');
t.equal(result.lists.count, 0);
t.deepEqual(result.lists.id, []);
t.same(result.lists.id, []);
t.type(result.comments, 'object');
t.equal(result.comments.count, 0);
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.deepEqual(result.sounds.id, [
t.same(result.sounds.id, [
'pop',
'Meow'
]);
t.deepEqual(result.sounds.hash, [
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.deepEqual(result.costumes.id, [
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.deepEqual(result.costumes.hash, [
t.same(result.costumes.hash, [
'cd21514d0531fdffb22204e0ec5ed84a.svg',
'b7853f557e4426412e64bb3da6531a99.svg',
'e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg'
@ -68,12 +72,12 @@ test('defalt (object)', t => {
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 0);
t.equal(result.blocks.unique, 0);
t.deepEqual(result.blocks.id, []);
t.deepEqual(result.blocks.frequency, {});
t.same(result.blocks.id, []);
t.same(result.blocks.frequency, {});
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 0);
t.deepEqual(result.extensions.id, []);
t.same(result.extensions.id, []);
t.type(result.meta, 'object');
t.equal(result.meta.origin, 'test.scratch.mit.edu');
@ -81,9 +85,9 @@ test('defalt (object)', t => {
});
});
test('defalt (binary)', t => {
test('default (binary)', t => {
analysis(defaultBinary, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
@ -91,36 +95,36 @@ test('defalt (binary)', t => {
t.type(result.variables, 'object');
t.equal(result.variables.count, 1);
t.deepEqual(result.variables.id, [
t.same(result.variables.id, [
'my variable'
]);
t.type(result.lists, 'object');
t.equal(result.lists.count, 0);
t.deepEqual(result.lists.id, []);
t.same(result.lists.id, []);
t.type(result.comments, 'object');
t.equal(result.comments.count, 0);
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.deepEqual(result.sounds.id, [
t.same(result.sounds.id, [
'pop',
'Meow'
]);
t.deepEqual(result.sounds.hash, [
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.deepEqual(result.costumes.id, [
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.deepEqual(result.costumes.hash, [
t.same(result.costumes.hash, [
'cd21514d0531fdffb22204e0ec5ed84a.svg',
'b7853f557e4426412e64bb3da6531a99.svg',
'e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg'
@ -132,15 +136,15 @@ test('defalt (binary)', t => {
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 0);
t.equal(result.blocks.unique, 0);
t.deepEqual(result.blocks.id, []);
t.deepEqual(result.blocks.frequency, {});
t.same(result.blocks.id, []);
t.same(result.blocks.frequency, {});
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 0);
t.deepEqual(result.extensions.id, []);
t.same(result.extensions.id, []);
t.type(result.meta, 'object');
t.deepEqual({}, result.meta);
t.same({}, result.meta);
t.end();
});
@ -148,7 +152,7 @@ test('defalt (binary)', t => {
test('complex (binary)', t => {
analysis(complexBinary, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
@ -156,14 +160,14 @@ test('complex (binary)', t => {
t.type(result.variables, 'object');
t.equal(result.variables.count, 2);
t.deepEqual(result.variables.id, [
t.same(result.variables.id, [
'global',
'local'
]);
t.type(result.lists, 'object');
t.equal(result.lists.count, 2);
t.deepEqual(result.lists.id, [
t.same(result.lists.id, [
'globallist',
'locallist'
]);
@ -173,23 +177,23 @@ test('complex (binary)', t => {
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.deepEqual(result.sounds.id, [
t.same(result.sounds.id, [
'pop',
'meow'
]);
t.deepEqual(result.sounds.hash, [
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.deepEqual(result.costumes.id, [
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.deepEqual(result.costumes.hash, [
t.same(result.costumes.hash, [
'7633d36de03d1df75808f581bbccc742.svg',
'e6bcb4046c157f60c9f5c3bb5f299fce.svg',
'64208764c777be25d34d813dc0b743c7.svg'
@ -201,7 +205,7 @@ test('complex (binary)', t => {
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 34);
t.equal(result.blocks.unique, 18);
t.deepEqual(result.blocks.id, [
t.same(result.blocks.id, [
'event_whenflagclicked',
'control_forever',
'looks_changeeffectby',
@ -237,7 +241,7 @@ test('complex (binary)', t => {
'wedo2_setLightHue',
'operator_random'
]);
t.deepEqual(result.blocks.frequency, {
t.same(result.blocks.frequency, {
argument_reporter_string_number: 4,
control_forever: 4,
data_addtolist: 2,
@ -260,7 +264,7 @@ test('complex (binary)', t => {
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 1);
t.deepEqual(result.extensions.id, [
t.same(result.extensions.id, [
'wedo2'
]);
@ -270,12 +274,12 @@ test('complex (binary)', t => {
test('extensions', t => {
analysis(extensionsBinary, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 2);
t.deepEqual(result.extensions.id, [
t.same(result.extensions.id, [
'translate',
'text2speech'
]);
@ -283,3 +287,67 @@ test('extensions', t => {
t.end();
});
});
test('regression test IBE-198, a bad list does not break library', t => {
analysis(badExtensions, (err, result) => {
t.ok(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.scripts, 'object');
t.equal(result.scripts.count, 0);
t.type(result.variables, 'object');
t.equal(result.variables.count, 1);
t.same(result.variables.id, [
'my variable'
]);
t.type(result.lists, 'object');
t.equal(result.lists.count, 0);
t.same(result.lists.id, []);
t.type(result.comments, 'object');
t.equal(result.comments.count, 0);
t.type(result.sounds, 'object');
t.equal(result.sounds.count, 2);
t.same(result.sounds.id, [
'pop',
'Meow'
]);
t.same(result.sounds.hash, [
'83a9787d4cb6f3b7632b4ddfebf74367.wav',
'83c36d806dc92327b9e7049a565c6bff.wav'
]);
t.type(result.costumes, 'object');
t.equal(result.costumes.count, 3);
t.same(result.costumes.id, [
'backdrop1',
'costume1',
'costume2'
]);
t.same(result.costumes.hash, [
'cd21514d0531fdffb22204e0ec5ed84a.svg',
'b7853f557e4426412e64bb3da6531a99.svg',
'e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg'
]);
t.type(result.sprites, 'object');
t.equal(result.sprites.count, 1);
t.type(result.blocks, 'object');
t.equal(result.blocks.count, 0);
t.equal(result.blocks.unique, 0);
t.same(result.blocks.id, []);
t.same(result.blocks.frequency, {});
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 0);
t.same(result.extensions.id, []);
t.type(result.meta, 'object');
t.equal(result.meta.origin, 'test.scratch.mit.edu');
t.end();
});
});

View file

@ -10,7 +10,7 @@ test('spec', t => {
test('frequency', t => {
const input = ['foo', 'foo', 'foo', 'bar', 'bar', 'baz'];
const result = utility.frequency(input);
t.deepEqual(result, {
t.same(result, {
foo: 3,
bar: 2,
baz: 1