bringing the Scratch html5 project under test

This commit is contained in:
Brian Pilati 2014-02-19 20:11:08 -07:00
parent 5f6195177a
commit 051e1e4778
12 changed files with 340 additions and 25 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
*.swp
test/lib/*
logs
npm-debug.log
node_modules

View file

@ -19,3 +19,49 @@ Running the HTML5 player on your own website, or locally, you will need to have
PHP so that the `proxy.php` file can be used to load assets from the same domain. This is done to be compatible with Javascript security models in today's browsers. To test the HTML5 player against the Flash player you can use the compare.html web page.
See the file `TESTING.md` for more details.
Unit Tests
----------
The tests are written using Karma and there should be a 100% passing rate in order to commit any code to the project.
The expectation is to add a unit test for any code that you contribute to the project.
Install Node (NPM) (https://npmjs.org/)
---------------------------------------
Brew:
```
$ brew install npm
```
Mac Ports:
```
$ port install npm
```
```
$ npm install
```
Local copy of jQuery and mock-ajax
----------------------------------
```
$ cd test/lib
$ curl http://code.jquery.com/jquery-1.11.0.min.js > jquery-1.11.0.min.js
$ curl http://cloud.github.com/downloads/pivotal/jasmine-ajax/mock-ajax.js > mock-ajax.js
```
To Run the tests
----------------
```
$ ./scripts/test.sh
```
To configure the unit tests
---------------------------
The karam.conf.js file is location in the config directory

37
config/karma.conf.js Normal file
View file

@ -0,0 +1,37 @@
module.exports = function(config){
config.set({
basePath : '../',
files : [
'test/artifacts/**/*.js',
'test/lib/mock-ajax.js',
'test/unit/**/*.js',
'test/lib/jquery-1.11.0.min.js',
'js/sound/SoundDecoder.js',
'js/sound/**/*.js',
'js/util/**/*.js',
'js/**/*.js'
],
exclude : [
],
autoWatch : true,
frameworks: ['jasmine'],
browsers : ['Chrome'],
plugins : [
'karma-junit-reporter',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-jasmine'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
}
})}

View file

@ -12,31 +12,12 @@
<script src=//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js></script>
<script src=js/util/Timer.js></script>
<script src=js/util/OffsetBuffer.js></script>
<script src=js/util/Color.js></script>
<script src=js/util/Rectangle.js></script>
<script src=js/Sprite.js></script>
<script src=js/Reporter.js></script>
<script src=js/Stage.js></script>
<script src=js/sound/WAVFile.js></script>
<script src=js/sound/SoundDecoder.js></script>
<script src=js/sound/SoundBank.js></script>
<script src=js/sound/NotePlayer.js></script>
<script src=soundbank/Instr.js></script>
<script src=js/IO.js></script>
<script src=js/primitives/VarListPrims.js></script>
<script src=js/primitives/MotionAndPenPrims.js></script>
<script src=js/primitives/LooksPrims.js></script>
<script src=js/primitives/SensingPrims.js></script>
<script src=js/primitives/SoundPrims.js></script>
<script src=js/primitives/Primitives.js></script>
<script src=js/Interpreter.js></script>
<script src=js/Runtime.js></script>
<script src=js/Scratch.js></script>
<script>
<script type="text/javascript">
$(document).ready(function() {
var project_id = location.hash && parseInt(location.hash.substr(1)) || 10000160;
var scratch = new Scratch(project_id);
});
</script>
<div id=player-container>
@ -68,3 +49,27 @@
<h1>Scratch HTML5 player</h1>
<p>The Scratch HTML5 player is still in development. Feedback is welcome! Please report any bugs (or differences from the Flash player) <a href=https://github.com/LLK/scratch-html5>on Github</a>.</p>
<script src=js/util/Timer.js></script>
<script src=js/util/OffsetBuffer.js></script>
<script src=js/util/Color.js></script>
<script src=js/util/Rectangle.js></script>
<script src=js/Sprite.js></script>
<script src=js/Reporter.js></script>
<script src=js/Stage.js></script>
<script src=js/sound/WAVFile.js></script>
<script src=js/sound/SoundDecoder.js></script>
<script src=js/sound/SoundBank.js></script>
<script src=js/sound/NotePlayer.js></script>
<script src=soundbank/Instr.js></script>
<script src=js/IO.js></script>
<script src=js/primitives/VarListPrims.js></script>
<script src=js/primitives/MotionAndPenPrims.js></script>
<script src=js/primitives/LooksPrims.js></script>
<script src=js/primitives/SensingPrims.js></script>
<script src=js/primitives/SoundPrims.js></script>
<script src=js/primitives/Primitives.js></script>
<script src=js/Interpreter.js></script>
<script src=js/Runtime.js></script>
<!-- <script src=js/Scratch.js></script> -->
<script type="text/JavaScript" src="js/Scratch.js"></script>

View file

@ -23,7 +23,7 @@
'use strict';
var runtime, interp, io, iosAudioActive = false;
$(function() {
function Scratch(project_id) {
runtime = new Runtime();
runtime.init();
@ -151,4 +151,4 @@ $(function() {
// Load the requested project and go!
io = new IO();
io.loadProject(project_id);
});
};

13
package.json Normal file
View file

@ -0,0 +1,13 @@
{
"name": "scratch-html5",
"description": "HTML 5 based Scratch project player",
"repository": "https://github.com/LLK/scratch-html5",
"devDependencies": {
"phantomjs" : "~1.9",
"karma" : "~0.10",
"karma-junit-reporter" : "~0.1",
"karma-jasmine" : "~0.1",
"karma-ng-scenario" : "~0.1",
"jquery" : "~1.11.0"
}
}

9
scripts/test.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
BASE_DIR=`dirname $0`
echo ""
echo "Starting Karma Server (http://karma-runner.github.io)"
echo "-------------------------------------------------------------------"
$BASE_DIR/../node_modules/karma/bin/karma start $BASE_DIR/../config/karma.conf.js $*

View file

@ -0,0 +1,9 @@
'use strict';
var io_base = 'proxy.php?resource=internalapi/';
var project_base = io_base + 'project/';
var project_suffix = '/get/';
var asset_base = io_base + 'asset/';
var asset_suffix = '/get/';
var soundbank_base = 'soundbank/';
var spriteLayerCount = 0;

View file

@ -0,0 +1,117 @@
'use strict';
var project_id = 123456789;
var returnData = {
"objName": "Stage",
"sounds": [{
"soundName": "pop",
"soundID": -1,
"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
"sampleCount": 258,
"rate": 11025,
"format": ""
}],
"costumes": [{
"costumeName": "Scene 1",
"baseLayerID": -1,
"baseLayerMD5": "510da64cf172d53750dffd23fbf73563.png",
"rotationCenterX": 240,
"rotationCenterY": 180,
"spritesHiddenInScene": null
}],
"currentCostumeIndex": 0,
"penLayerMD5": "279467d0d49e152706ed66539b577c00.png",
"tempoBPM": 60,
"children": [{
"objName": "Sprite1",
"scripts": [[283,
151,
[["whenClicked"],
["clearPenTrails"],
["penColor:", 10485886],
["putPenDown"],
["doForever",
[["gotoX:y:", ["randomFrom:to:", -240, 240], ["randomFrom:to:", -180, 180]], ["changePenShadeBy:", 10]]]]]],
"sounds": [{
"soundName": "pop",
"soundID": -1,
"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
"sampleCount": 258,
"rate": 11025,
"format": ""
}],
"costumes": [{
"costumeName": "Costume1",
"baseLayerID": -1,
"baseLayerMD5": "cce61b6e9ad98ea8c8c2e9556a94b7ab.png",
"rotationCenterX": 47,
"rotationCenterY": 55,
"spritesHiddenInScene": null
},
{
"costumeName": "Costume2",
"baseLayerID": -1,
"baseLayerMD5": "51f6fa1871f17de1a21cdfead7aad574.png",
"rotationCenterX": 47,
"rotationCenterY": 55,
"spritesHiddenInScene": null
}],
"currentCostumeIndex": 0,
"scratchX": 120,
"scratchY": -101,
"scale": 1,
"direction": 90,
"rotationStyle": "normal",
"isDraggable": false,
"indexInLibrary": 0,
"visible": true
},
{
"objName": "fish31",
"scripts": [[181, 138, [["whenClicked"], ["nextCostume"]]]],
"sounds": [{
"soundName": "pop",
"soundID": -1,
"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
"sampleCount": 258,
"rate": 11025,
"format": ""
}],
"costumes": [{
"costumeName": "fish3",
"baseLayerID": -1,
"baseLayerMD5": "5ab571cf8c6e6bcf0ee2443b5df17dcb.png",
"rotationCenterX": 90,
"rotationCenterY": 79,
"spritesHiddenInScene": null
},
{
"costumeName": "crab1-a",
"baseLayerID": -1,
"baseLayerMD5": "110bf75ed212eb072acec2fa2c39456d.png",
"rotationCenterX": 92,
"rotationCenterY": 62,
"spritesHiddenInScene": null
},
{
"costumeName": "ballerina-a",
"baseLayerID": -1,
"baseLayerMD5": "4c789664cc6f69d1ef4678ac8b4cb812.png",
"rotationCenterX": 51,
"rotationCenterY": 84,
"spritesHiddenInScene": null
}],
"currentCostumeIndex": 2,
"scratchX": 108,
"scratchY": -28,
"scale": 1,
"direction": 90,
"rotationStyle": "normal",
"isDraggable": false,
"indexInLibrary": 0,
"visible": true
}],
"info": {
}
};

0
test/lib/.git-keep Normal file
View file

47
test/unit/ioSpec.js Normal file
View file

@ -0,0 +1,47 @@
'use strict';
/* jasmine specs for IO.js go here */
describe('IO', function(){
var io;
beforeEach(function() {
io = new IO();
});
it('should have "null" data', function() {
expect(io.data).toBe(null);
});
it('should have "null" data', function() {
expect(io.data).toBe(null);
});
it('should have a base', function() {
expect(io.base).toBe(io_base);
});
it('should have a project_base', function() {
expect(io.project_base).toBe(project_base);
});
it('should have a project_suffix', function() {
expect(io.project_suffix).toBe(project_suffix);
});
it('should have an asset_base', function() {
expect(io.asset_base).toBe(asset_base);
});
it('should have an asset_suffix', function() {
expect(io.asset_suffix).toBe(asset_suffix);
});
it('should have an soundbank_base', function() {
expect(io.soundbank_base).toBe(soundbank_base);
});
it('should have a spriteLayerCount', function() {
expect(io.spriteLayerCount).toBe(spriteLayerCount);
});
});

25
test/unit/scratchSpec.js Normal file
View file

@ -0,0 +1,25 @@
'use strict';
/* jasmine specs for Scratch.js go here */
describe('Scratch', function(){
var getScript, request, scratch;
var uri = "http://getScript.example.com";
var callBack = jasmine.createSpy('onSuccess');
var testResponseText = 'This is a script';
var TestResponses = { status: 200, responseText: returnData};
beforeEach(function() {
jasmine.Ajax.useMock();
scratch = Scratch;
scratch(project_id);
request = mostRecentAjaxRequest();
request.promise(TestResponses, callBack);
});
it('should call the internalapi project', function() {
expect(request.url).toBe("proxy.php?resource=internalapi/project/" + project_id + "/get/");
expect(callBack).toHaveBeenCalled();
});
});