brainstem-js 0.2.1
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.
- data/.gitignore +8 -0
- data/.pairs +21 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.tm_properties +1 -0
- data/.travis.yml +12 -0
- data/Assetfile +79 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +50 -0
- data/LICENSE.txt +22 -0
- data/README.md +143 -0
- data/Rakefile +25 -0
- data/brainstemjs.gemspec +24 -0
- data/lib/brainstem/js/engine.rb +5 -0
- data/lib/brainstem/js/version.rb +5 -0
- data/lib/brainstem/js.rb +10 -0
- data/spec/brainstem-collection-spec.coffee +141 -0
- data/spec/brainstem-model-spec.coffee +283 -0
- data/spec/brainstem-sync-spec.coffee +22 -0
- data/spec/brainstem-utils-spec.coffee +12 -0
- data/spec/brianstem-expectation-spec.coffee +209 -0
- data/spec/helpers/builders.coffee +80 -0
- data/spec/helpers/jquery-matchers.js +137 -0
- data/spec/helpers/models/post.coffee +14 -0
- data/spec/helpers/models/project.coffee +13 -0
- data/spec/helpers/models/task.coffee +14 -0
- data/spec/helpers/models/time-entry.coffee +13 -0
- data/spec/helpers/models/user.coffee +8 -0
- data/spec/helpers/spec-helper.coffee +79 -0
- data/spec/storage-manager-spec.coffee +613 -0
- data/spec/support/.DS_Store +0 -0
- data/spec/support/console-runner.js +103 -0
- data/spec/support/headless.coffee +47 -0
- data/spec/support/headless.html +60 -0
- data/spec/support/runner.html +85 -0
- data/spec/vendor/backbone-factory.js +62 -0
- data/spec/vendor/backbone.js +1571 -0
- data/spec/vendor/inflection.js +448 -0
- data/spec/vendor/jquery-1.7.js +9300 -0
- data/spec/vendor/jquery.cookie.js +47 -0
- data/spec/vendor/minispade.js +67 -0
- data/spec/vendor/sinon-1.3.4.js +3561 -0
- data/spec/vendor/underscore.js +1221 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/brainstem/brainstem-collection.coffee +53 -0
- data/vendor/assets/javascripts/brainstem/brainstem-expectation.coffee +65 -0
- data/vendor/assets/javascripts/brainstem/brainstem-inflections.js +449 -0
- data/vendor/assets/javascripts/brainstem/brainstem-model.coffee +141 -0
- data/vendor/assets/javascripts/brainstem/brainstem-sync.coffee +76 -0
- data/vendor/assets/javascripts/brainstem/index.js +1 -0
- data/vendor/assets/javascripts/brainstem/iso8601.js +41 -0
- data/vendor/assets/javascripts/brainstem/loading-mixin.coffee +13 -0
- data/vendor/assets/javascripts/brainstem/storage-manager.coffee +275 -0
- data/vendor/assets/javascripts/brainstem/utils.coffee +35 -0
- metadata +198 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
/**
|
2
|
+
Jasmine Reporter that outputs test results to the browser console.
|
3
|
+
Useful for running in a headless environment such as PhantomJs, ZombieJs etc.
|
4
|
+
|
5
|
+
Usage:
|
6
|
+
// From your html file that loads jasmine:
|
7
|
+
jasmine.getEnv().addReporter(new jasmine.ConsoleReporter());
|
8
|
+
jasmine.getEnv().execute();
|
9
|
+
*/
|
10
|
+
|
11
|
+
(function(jasmine, console) {
|
12
|
+
if (!jasmine) {
|
13
|
+
throw "jasmine library isn't loaded!";
|
14
|
+
}
|
15
|
+
|
16
|
+
var ANSI = {}
|
17
|
+
ANSI.color_map = {
|
18
|
+
"green" : 32,
|
19
|
+
"red" : 31
|
20
|
+
}
|
21
|
+
|
22
|
+
ANSI.colorize_text = function(text, color) {
|
23
|
+
var color_code = this.color_map[color];
|
24
|
+
return "\033[" + color_code + "m" + text + "\033[0m";
|
25
|
+
}
|
26
|
+
|
27
|
+
var ConsoleReporter = function() {
|
28
|
+
if (!console || !console.log) { throw "console isn't present!"; }
|
29
|
+
this.status = this.statuses.stopped;
|
30
|
+
};
|
31
|
+
|
32
|
+
var proto = ConsoleReporter.prototype;
|
33
|
+
proto.statuses = {
|
34
|
+
stopped : "stopped",
|
35
|
+
running : "running",
|
36
|
+
fail : "fail",
|
37
|
+
success : "success"
|
38
|
+
};
|
39
|
+
|
40
|
+
proto.reportRunnerStarting = function(runner) {
|
41
|
+
this.status = this.statuses.running;
|
42
|
+
this.start_time = (new Date()).getTime();
|
43
|
+
this.executed_specs = 0;
|
44
|
+
this.passed_specs = 0;
|
45
|
+
this.log("Starting...");
|
46
|
+
};
|
47
|
+
|
48
|
+
proto.reportRunnerResults = function(runner) {
|
49
|
+
var failed = this.executed_specs - this.passed_specs;
|
50
|
+
var spec_str = this.executed_specs + (this.executed_specs === 1 ? " spec, " : " specs, ");
|
51
|
+
var fail_str = failed + (failed === 1 ? " failure in " : " failures in ");
|
52
|
+
var color = (failed > 0)? "red" : "green";
|
53
|
+
var dur = (new Date()).getTime() - this.start_time;
|
54
|
+
|
55
|
+
this.log("");
|
56
|
+
this.log("Finished");
|
57
|
+
this.log("-----------------");
|
58
|
+
this.log(spec_str + fail_str + (dur/1000) + "s.", color);
|
59
|
+
|
60
|
+
this.status = (failed > 0)? this.statuses.fail : this.statuses.success;
|
61
|
+
|
62
|
+
/* Print something that signals that testing is over so that headless browsers
|
63
|
+
like PhantomJs know when to terminate. */
|
64
|
+
this.log("");
|
65
|
+
this.log("ConsoleReporter finished");
|
66
|
+
};
|
67
|
+
|
68
|
+
|
69
|
+
proto.reportSpecStarting = function(spec) {
|
70
|
+
this.executed_specs++;
|
71
|
+
};
|
72
|
+
|
73
|
+
proto.reportSpecResults = function(spec) {
|
74
|
+
if (spec.results().passed()) {
|
75
|
+
this.passed_specs++;
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
79
|
+
var resultText = spec.suite.description + " : " + spec.description;
|
80
|
+
this.log(resultText, "red");
|
81
|
+
|
82
|
+
var items = spec.results().getItems()
|
83
|
+
for (var i = 0; i < items.length; i++) {
|
84
|
+
var trace = items[i].trace.stack || items[i].trace;
|
85
|
+
this.log(trace, "red");
|
86
|
+
}
|
87
|
+
};
|
88
|
+
|
89
|
+
proto.reportSuiteResults = function(suite) {
|
90
|
+
if (!suite.parentSuite) { return; }
|
91
|
+
var results = suite.results();
|
92
|
+
var failed = results.totalCount - results.passedCount;
|
93
|
+
var color = (failed > 0)? "red" : "green";
|
94
|
+
this.log(suite.getFullName() + ": " + results.passedCount + " of " + results.totalCount + " passed.", color);
|
95
|
+
};
|
96
|
+
|
97
|
+
proto.log = function(str, color) {
|
98
|
+
var text = (color != undefined)? ANSI.colorize_text(str, color) : str;
|
99
|
+
console.log(text)
|
100
|
+
};
|
101
|
+
|
102
|
+
jasmine.ConsoleReporter = ConsoleReporter;
|
103
|
+
})(jasmine, console);
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/local/bin/phantomjs
|
2
|
+
|
3
|
+
# Runs a Jasmine Suite from an html page
|
4
|
+
# @page is a PhantomJs page object
|
5
|
+
# @exit_func is the function to call in order to exit the script
|
6
|
+
|
7
|
+
class PhantomJasmineRunner
|
8
|
+
constructor: (@page, @exit_func = phantom.exit) ->
|
9
|
+
@tries = 0
|
10
|
+
@max_tries = 10
|
11
|
+
|
12
|
+
get_status: -> @page.evaluate(-> console_reporter.status)
|
13
|
+
|
14
|
+
terminate: ->
|
15
|
+
switch @get_status()
|
16
|
+
when "success" then @exit_func 0
|
17
|
+
when "fail" then @exit_func 1
|
18
|
+
else @exit_func 2
|
19
|
+
|
20
|
+
# Script Begin
|
21
|
+
if phantom.args.length == 0
|
22
|
+
console.log "Need a url as the argument"
|
23
|
+
phantom.exit 1
|
24
|
+
|
25
|
+
page = new WebPage()
|
26
|
+
|
27
|
+
runner = new PhantomJasmineRunner(page)
|
28
|
+
|
29
|
+
# Don't supress console output
|
30
|
+
page.onConsoleMessage = (msg) ->
|
31
|
+
console.log msg
|
32
|
+
|
33
|
+
# Terminate when the reporter singals that testing is over.
|
34
|
+
# We cannot use a callback function for this (because page.evaluate is sandboxed),
|
35
|
+
# so we have to *observe* the website.
|
36
|
+
if msg == "ConsoleReporter finished"
|
37
|
+
runner.terminate()
|
38
|
+
|
39
|
+
address = phantom.args[0]
|
40
|
+
|
41
|
+
page.open address, (status) ->
|
42
|
+
if status != "success"
|
43
|
+
console.log "can't load the address!"
|
44
|
+
phantom.exit 1
|
45
|
+
|
46
|
+
# Now we wait until onConsoleMessage reads the termination signal from the log.
|
47
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
5
|
+
<title>Jasmine suite</title>
|
6
|
+
|
7
|
+
<link rel="stylesheet" href="jasmine/jasmine.css" type="text/css" charset="utf-8">
|
8
|
+
<script src="jasmine/json2.js" type="text/javascript" charset="utf-8"></script>
|
9
|
+
<script src="jasmine/jasmine.js" type="text/javascript" charset="utf-8"></script>
|
10
|
+
<script src="jasmine/jasmine-html.js" type="text/javascript" charset="utf-8"></script>
|
11
|
+
|
12
|
+
<script type="text/javascript" src="console-runner.js"></script>
|
13
|
+
|
14
|
+
<!-- require dependencies here -->
|
15
|
+
<script src="vendor/jquery-1.7.js" type="text/javascript" charset="utf-8"></script>
|
16
|
+
<script src="vendor/underscore.js" type="text/javascript" charset="utf-8"></script>
|
17
|
+
<script src="vendor/backbone.js" type="text/javascript" charset="utf-8"></script>
|
18
|
+
<script src="vendor/backbone-factory.js" type="text/javascript" charset="utf-8"></script>
|
19
|
+
<script src="vendor/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
|
20
|
+
<script src="vendor/inflection.js" type="text/javascript" charset="utf-8"></script>
|
21
|
+
<script src="vendor/sinon-1.3.4.js" type="text/javascript" charset="utf-8"></script>
|
22
|
+
<script src="vendor/minispade.js" type="text/javascript" charset="utf-8"></script>
|
23
|
+
|
24
|
+
|
25
|
+
<script src="helpers.js" type="text/javascript" charset="utf-8"></script>
|
26
|
+
<script type="text/javascript" charset="utf-8">
|
27
|
+
minispade.require('builders');
|
28
|
+
minispade.require('jquery-matchers');
|
29
|
+
minispade.require('spec-helper');
|
30
|
+
</script>
|
31
|
+
|
32
|
+
<script src="brainstem.js" type="text/javascript" charset="utf-8"></script>
|
33
|
+
<script type="text/javascript" charset="utf-8">
|
34
|
+
minispade.require('utils');
|
35
|
+
minispade.require('loading-mixin');
|
36
|
+
minispade.require('brainstem-model');
|
37
|
+
minispade.require('brainstem-collection');
|
38
|
+
minispade.require('storage-manager');
|
39
|
+
minispade.require('brainstem-sync');
|
40
|
+
minispade.requireAll(/models\/.*/);
|
41
|
+
minispade.requireAll(/.*/);
|
42
|
+
</script>
|
43
|
+
|
44
|
+
<!-- require specs themselves here -->
|
45
|
+
<script src="specs.js" type="text/javascript" charset="utf-8"></script>
|
46
|
+
<script type="text/javascript" charset="utf-8">
|
47
|
+
minispade.requireAll(/.*/);
|
48
|
+
</script>
|
49
|
+
|
50
|
+
</head>
|
51
|
+
|
52
|
+
<body>
|
53
|
+
<script type="text/javascript" charset="utf-8">
|
54
|
+
var console_reporter = new jasmine.ConsoleReporter()
|
55
|
+
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
|
56
|
+
jasmine.getEnv().addReporter(console_reporter);
|
57
|
+
jasmine.getEnv().execute();
|
58
|
+
</script>
|
59
|
+
</body>
|
60
|
+
</html>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
5
|
+
<title>Jasmine suite</title>
|
6
|
+
|
7
|
+
<link rel="stylesheet" href="jasmine/jasmine.css" type="text/css" charset="utf-8">
|
8
|
+
<script src="jasmine/json2.js" type="text/javascript" charset="utf-8"></script>
|
9
|
+
<script src="jasmine/jasmine.js" type="text/javascript" charset="utf-8"></script>
|
10
|
+
<script src="jasmine/jasmine-html.js" type="text/javascript" charset="utf-8"></script>
|
11
|
+
|
12
|
+
<script type="text/javascript">
|
13
|
+
//TODO: make this a js file that gets passed in, then iterate over only js_files
|
14
|
+
var jsApiReporter;
|
15
|
+
(function() {
|
16
|
+
var jasmineEnv = jasmine.getEnv();
|
17
|
+
|
18
|
+
jsApiReporter = new jasmine.JsApiReporter();
|
19
|
+
var htmlReporter = new jasmine.HtmlReporter();
|
20
|
+
|
21
|
+
jasmineEnv.addReporter(jsApiReporter);
|
22
|
+
jasmineEnv.addReporter(htmlReporter);
|
23
|
+
|
24
|
+
jasmineEnv.specFilter = function(spec) {
|
25
|
+
return htmlReporter.specFilter(spec);
|
26
|
+
};
|
27
|
+
|
28
|
+
var currentWindowOnload = window.onload;
|
29
|
+
|
30
|
+
window.onload = function() {
|
31
|
+
if (currentWindowOnload) {
|
32
|
+
currentWindowOnload();
|
33
|
+
}
|
34
|
+
execJasmine();
|
35
|
+
};
|
36
|
+
|
37
|
+
function execJasmine() {
|
38
|
+
jasmineEnv.execute();
|
39
|
+
}
|
40
|
+
|
41
|
+
})();
|
42
|
+
</script>
|
43
|
+
|
44
|
+
<!-- require dependencies here -->
|
45
|
+
<script src="vendor/jquery-1.7.js" type="text/javascript" charset="utf-8"></script>
|
46
|
+
<script src="vendor/underscore.js" type="text/javascript" charset="utf-8"></script>
|
47
|
+
<script src="vendor/backbone.js" type="text/javascript" charset="utf-8"></script>
|
48
|
+
<script src="vendor/backbone-factory.js" type="text/javascript" charset="utf-8"></script>
|
49
|
+
<script src="vendor/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
|
50
|
+
<script src="vendor/inflection.js" type="text/javascript" charset="utf-8"></script>
|
51
|
+
<script src="vendor/sinon-1.3.4.js" type="text/javascript" charset="utf-8"></script>
|
52
|
+
<script src="vendor/minispade.js" type="text/javascript" charset="utf-8"></script>
|
53
|
+
|
54
|
+
|
55
|
+
<script src="helpers.js" type="text/javascript" charset="utf-8"></script>
|
56
|
+
<script type="text/javascript" charset="utf-8">
|
57
|
+
minispade.require('builders');
|
58
|
+
minispade.require('jquery-matchers');
|
59
|
+
minispade.require('spec-helper');
|
60
|
+
</script>
|
61
|
+
|
62
|
+
<script src="brainstem.js" type="text/javascript" charset="utf-8"></script>
|
63
|
+
<script type="text/javascript" charset="utf-8">
|
64
|
+
minispade.require('utils');
|
65
|
+
minispade.require('loading-mixin');
|
66
|
+
minispade.require('brainstem-model');
|
67
|
+
minispade.require('brainstem-collection');
|
68
|
+
minispade.require('storage-manager');
|
69
|
+
minispade.require('brainstem-sync');
|
70
|
+
minispade.requireAll(/models\/.*/);
|
71
|
+
minispade.requireAll(/.*/);
|
72
|
+
</script>
|
73
|
+
|
74
|
+
<!-- require specs themselves here -->
|
75
|
+
<script src="specs.js" type="text/javascript" charset="utf-8"></script>
|
76
|
+
<script type="text/javascript" charset="utf-8">
|
77
|
+
minispade.requireAll(/.*/);
|
78
|
+
</script>
|
79
|
+
|
80
|
+
</head>
|
81
|
+
|
82
|
+
<body>
|
83
|
+
<div id="jasmine_content"></div>
|
84
|
+
</body>
|
85
|
+
</html>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
// Backbone Factory JS
|
2
|
+
// https://github.com/SupportBee/Backbone-Factory
|
3
|
+
|
4
|
+
(function(){
|
5
|
+
window.BackboneFactory = {
|
6
|
+
|
7
|
+
factories: {},
|
8
|
+
sequences: {},
|
9
|
+
|
10
|
+
define: function(factory_name, klass, defaults){
|
11
|
+
// Check for arguments' sanity
|
12
|
+
if(factory_name.match(/[^\w_]+/)){
|
13
|
+
throw "Factory name should not contain spaces or other funky characters";
|
14
|
+
}
|
15
|
+
|
16
|
+
if(defaults === undefined) defaults = function(){return {}};
|
17
|
+
|
18
|
+
// The object creator
|
19
|
+
this.factories[factory_name] = function(options){
|
20
|
+
if(options === undefined) options = function(){return {}};
|
21
|
+
var arguments = _.extend({}, {id: BackboneFactory.next("_" + factory_name + "_id")}, defaults.call(), options.call());
|
22
|
+
return new klass(arguments, { error: function() { console.log("Error when creating factory", arguments); }});
|
23
|
+
};
|
24
|
+
|
25
|
+
// Lets define a sequence for id
|
26
|
+
BackboneFactory.define_sequence("_"+ factory_name +"_id", function(n){
|
27
|
+
return n
|
28
|
+
});
|
29
|
+
},
|
30
|
+
|
31
|
+
create: function(factory_name, options){
|
32
|
+
if(this.factories[factory_name] === undefined){
|
33
|
+
throw "Factory with name " + factory_name + " does not exist";
|
34
|
+
}
|
35
|
+
|
36
|
+
var args = {}
|
37
|
+
$.each(options, function(key, value){
|
38
|
+
if (typeof(value) === "function"){
|
39
|
+
args[key] = value.call();
|
40
|
+
}
|
41
|
+
else
|
42
|
+
args[key] = value;
|
43
|
+
});
|
44
|
+
|
45
|
+
return this.factories[factory_name].apply(null, [function(){ return args;}]);
|
46
|
+
},
|
47
|
+
|
48
|
+
define_sequence: function(sequence_name, callback){
|
49
|
+
this.sequences[sequence_name] = {}
|
50
|
+
this.sequences[sequence_name]['counter'] = 0;
|
51
|
+
this.sequences[sequence_name]['callback'] = callback;
|
52
|
+
},
|
53
|
+
|
54
|
+
next: function(sequence_name){
|
55
|
+
if(this.sequences[sequence_name] === undefined){
|
56
|
+
throw "Sequence with name " + sequence_name + " does not exist";
|
57
|
+
}
|
58
|
+
this.sequences[sequence_name]['counter'] += 1;
|
59
|
+
return this.sequences[sequence_name]['callback'].apply(null, [this.sequences[sequence_name]['counter']]); //= callback;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
})();
|