cruyff 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/Readme.md +29 -0
- data/SpecRunner.html +43 -0
- data/cruyff.gemspec +21 -0
- data/lib/cruyff/version.rb +3 -0
- data/lib/generators/cruyff_generator.rb +14 -0
- data/lib/generators/templates/jquery.cruyff.js +174 -0
- data/spec/CruyffSpec.js +159 -0
- data/spec/SpecHelper.js +0 -0
- data/spec/fixtures/view.html +1 -0
- data/spec/js_lib/jasmine-1.0.1/jasmine-html.js +188 -0
- data/spec/js_lib/jasmine-1.0.1/jasmine.css +166 -0
- data/spec/js_lib/jasmine-1.0.1/jasmine.js +2421 -0
- data/spec/js_lib/jasmine-fixture.js +24 -0
- data/spec/js_lib/jasmine-jquery-1.1.3.js +205 -0
- data/spec/js_lib/jquery-1.4.4.js +7179 -0
- data/spec/js_lib/jquery.ba-bbq-1.2.1.js +1137 -0
- data/spec/js_lib/jquery.form-2.52.js +791 -0
- data/spec/js_lib/rails-11.01.12.js +137 -0
- metadata +99 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
# Cruyff
|
3
|
+
|
4
|
+
Cruyff is a Ajax CRUD solution for Rails applications.
|
5
|
+
|
6
|
+
## License
|
7
|
+
|
8
|
+
(The MIT License)
|
9
|
+
|
10
|
+
Copyright (c) 2011
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
13
|
+
a copy of this software and associated documentation files (the
|
14
|
+
'Software'), to deal in the Software without restriction, including
|
15
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
16
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
17
|
+
permit persons to whom the Software is furnished to do so, subject to
|
18
|
+
the following conditions:
|
19
|
+
|
20
|
+
The above copyright notice and this permission notice shall be
|
21
|
+
included in all copies or substantial portions of the Software.
|
22
|
+
|
23
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
24
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
25
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
26
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
27
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
28
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
29
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/SpecRunner.html
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Jasmine Test Runner</title>
|
4
|
+
<link rel="stylesheet" type="text/css" href="spec/js_lib/jasmine-1.0.1/jasmine.css">
|
5
|
+
<script type="text/javascript" src="spec/js_lib/jasmine-1.0.1/jasmine.js"></script>
|
6
|
+
<script type="text/javascript" src="spec/js_lib/jasmine-1.0.1/jasmine-html.js"></script>
|
7
|
+
|
8
|
+
<script type="text/javascript" src="spec/js_lib/jquery-1.4.4.js"></script>
|
9
|
+
<script type="text/javascript" src="spec/js_lib/jquery.ba-bbq-1.2.1.js"></script>
|
10
|
+
<script type="text/javascript" src="spec/js_lib/jquery.form-2.52.js"></script>
|
11
|
+
<script type="text/javascript" src="spec/js_lib/rails-11.01.12.js"></script>
|
12
|
+
<script type="text/javascript" src="spec/js_lib/jasmine-jquery-1.1.3.js"></script>
|
13
|
+
|
14
|
+
<script type="text/javascript" src="lib/generators/templates/jquery.cruyff.js"></script>
|
15
|
+
|
16
|
+
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
17
|
+
<script type="text/javascript" src="spec/js_lib/jasmine-fixture.js"></script>
|
18
|
+
|
19
|
+
<script type="text/javascript" src="spec/CruyffSpec.js"></script>
|
20
|
+
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
|
24
|
+
<script type="text/javascript">
|
25
|
+
$(function() {
|
26
|
+
/*
|
27
|
+
$.ajax({
|
28
|
+
url: 'spec/fixtures/view.html',
|
29
|
+
success: function(data, status, xhr) {
|
30
|
+
console.log(data);
|
31
|
+
}
|
32
|
+
});*/
|
33
|
+
|
34
|
+
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
|
35
|
+
jasmine.getEnv().execute();
|
36
|
+
});
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
</script>
|
41
|
+
</body>
|
42
|
+
|
43
|
+
</html>
|
data/cruyff.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "cruyff/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "cruyff"
|
7
|
+
s.version = Cruyff::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Charger Tec"]
|
10
|
+
s.email = ["DM @andrefarina"]
|
11
|
+
s.homepage = "https://github.com/andref5/cruyff"
|
12
|
+
s.summary = %q{Ajax CRUD solution for Rails applications.}
|
13
|
+
s.description = %q{Cruyff is a Ajax CRUD solution for Rails applications.}
|
14
|
+
|
15
|
+
s.add_dependency("jquery-rails", "~> 0.2.6")
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class CruyffGenerator < Rails::Generators::Base
|
4
|
+
def self.source_root
|
5
|
+
File.join(File.dirname(__FILE__), 'templates')
|
6
|
+
end
|
7
|
+
|
8
|
+
def install_cruyff
|
9
|
+
copy_file(
|
10
|
+
'jquery.cruyff.js',
|
11
|
+
'public/javascripts/jquery.cruyff.js'
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
(function($) {
|
2
|
+
|
3
|
+
var cruyffSettings = {
|
4
|
+
url: "",
|
5
|
+
method: "",
|
6
|
+
dataType: "",
|
7
|
+
data: "",
|
8
|
+
responseSelector: "#response",
|
9
|
+
response: [],
|
10
|
+
};
|
11
|
+
|
12
|
+
$.fn.handleRemoteCrud = function(element) {
|
13
|
+
var cs = this.cruyffSetup(element);
|
14
|
+
|
15
|
+
//call ajaxSubmit from jquery.form because provides a file upload mechanism.
|
16
|
+
element.ajaxSubmit({
|
17
|
+
url: cs.url,
|
18
|
+
type: cs.method || 'GET',
|
19
|
+
data: cs.data,
|
20
|
+
dataType: cs.dataType,
|
21
|
+
// stopping the "ajax:beforeSend" event will cancel the ajax request
|
22
|
+
beforeSend: function(xhr, settings) {
|
23
|
+
if (settings.dataType === undefined) {
|
24
|
+
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
|
25
|
+
}
|
26
|
+
return fire(element, 'ajax:beforeSend', [xhr, settings]);
|
27
|
+
},
|
28
|
+
success: function(data, status, xhr) {
|
29
|
+
element.trigger('ajax:success', [data, status, xhr]);
|
30
|
+
cs.response.html(data);
|
31
|
+
},
|
32
|
+
complete: function(xhr, status) {
|
33
|
+
element.trigger('ajax:complete', [xhr, status]);
|
34
|
+
},
|
35
|
+
error: function(xhr, status, error) {
|
36
|
+
element.trigger('ajax:error', [xhr, status, error]);
|
37
|
+
cs.response.html(error.toString());
|
38
|
+
}
|
39
|
+
});
|
40
|
+
|
41
|
+
$.bbq.pushState("app=" + cs.url);
|
42
|
+
|
43
|
+
};
|
44
|
+
function handleRemote(element) {
|
45
|
+
$.fn.handleRemoteCrud(element);
|
46
|
+
}
|
47
|
+
|
48
|
+
$.fn.cruyffSetup = function(element) {
|
49
|
+
var cs = cruyffSettings;
|
50
|
+
|
51
|
+
cs.response = $(cs.responseSelector);
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Rails.js Code 2011-01-12
|
55
|
+
**/
|
56
|
+
cs.dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
|
57
|
+
|
58
|
+
if (element.is('form')) {
|
59
|
+
cs.method = element.attr('method');
|
60
|
+
cs.url = element.attr('action');
|
61
|
+
cs.data = element.serializeArray();
|
62
|
+
// memoized value from clicked submit button
|
63
|
+
var button = element.data('ujs:submit-button');
|
64
|
+
if (button) {
|
65
|
+
cs.data.push(button);
|
66
|
+
element.data('ujs:submit-button', null);
|
67
|
+
}
|
68
|
+
} else {
|
69
|
+
cs.method = element.attr('data-method');
|
70
|
+
cs.url = element.attr('href');
|
71
|
+
cs.data = null;
|
72
|
+
}
|
73
|
+
/**
|
74
|
+
* End Rails.js $.bbq.getState
|
75
|
+
**/
|
76
|
+
|
77
|
+
return cs;
|
78
|
+
};
|
79
|
+
|
80
|
+
$.fn.cruyffUrl = $.bbq.getState("app");
|
81
|
+
|
82
|
+
console.log($.fn.cruyffUrl);
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Rails.js Code 2011-01-12. I don't know yet how to override inner functions.
|
86
|
+
**/
|
87
|
+
function fire(obj, name, data) {
|
88
|
+
var event = new $.Event(name);
|
89
|
+
obj.trigger(event, data);
|
90
|
+
return event.result !== false;
|
91
|
+
}
|
92
|
+
// Handles "data-method" on links such as:
|
93
|
+
// <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
|
94
|
+
function handleMethod(link) {
|
95
|
+
var href = link.attr('href'),
|
96
|
+
method = link.attr('data-method'),
|
97
|
+
csrf_token = $('meta[name=csrf-token]').attr('content'),
|
98
|
+
csrf_param = $('meta[name=csrf-param]').attr('content'),
|
99
|
+
form = $('<form method="post" action="' + href + '"></form>'),
|
100
|
+
metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
|
101
|
+
|
102
|
+
if (csrf_param !== undefined && csrf_token !== undefined) {
|
103
|
+
metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
|
104
|
+
}
|
105
|
+
|
106
|
+
form.hide().append(metadata_input).appendTo('body');
|
107
|
+
form.submit();
|
108
|
+
}
|
109
|
+
|
110
|
+
function disableFormElements(form) {
|
111
|
+
form.find('input[data-disable-with]').each(function() {
|
112
|
+
var input = $(this);
|
113
|
+
input.data('ujs:enable-with', input.val())
|
114
|
+
.val(input.attr('data-disable-with'))
|
115
|
+
.attr('disabled', 'disabled');
|
116
|
+
});
|
117
|
+
}
|
118
|
+
|
119
|
+
function enableFormElements(form) {
|
120
|
+
form.find('input[data-disable-with]').each(function() {
|
121
|
+
var input = $(this);
|
122
|
+
input.val(input.data('ujs:enable-with')).removeAttr('disabled');
|
123
|
+
});
|
124
|
+
}
|
125
|
+
|
126
|
+
function allowAction(element) {
|
127
|
+
var message = element.attr('data-confirm');
|
128
|
+
return !message || (fire(element, 'confirm') && confirm(message));
|
129
|
+
}
|
130
|
+
|
131
|
+
$('a[data-confirm], a[data-method], a[data-remote]').die('click.rails').live('click.rails', function(e) {
|
132
|
+
var link = $(this);
|
133
|
+
if (!allowAction(link)) return false;
|
134
|
+
|
135
|
+
if (link.attr('data-remote')) {
|
136
|
+
handleRemote(link);
|
137
|
+
return false;
|
138
|
+
} else if (link.attr('data-method')) {
|
139
|
+
handleMethod(link);
|
140
|
+
return false;
|
141
|
+
}
|
142
|
+
});
|
143
|
+
|
144
|
+
$('form').die('submit.rails').live('submit.rails', function(e) {
|
145
|
+
var form = $(this);
|
146
|
+
if (!allowAction(form)) return false;
|
147
|
+
|
148
|
+
if (form.attr('data-remote')) {
|
149
|
+
handleRemote(form);
|
150
|
+
return false;
|
151
|
+
} else {
|
152
|
+
disableFormElements(form);
|
153
|
+
}
|
154
|
+
});
|
155
|
+
|
156
|
+
$('form input[type=submit], form button[type=submit], form button:not([type])').die('click.rails').live('click.rails', function() {
|
157
|
+
var button = $(this);
|
158
|
+
if (!allowAction(button)) return false;
|
159
|
+
// register the pressed submit button
|
160
|
+
var name = button.attr('name'), data = name ? {name:name, value:button.val()} : null;
|
161
|
+
button.closest('form').data('ujs:submit-button', data);
|
162
|
+
});
|
163
|
+
|
164
|
+
$('form').live('ajax:beforeSend.rails', function(event) {
|
165
|
+
if (this == event.target) disableFormElements($(this));
|
166
|
+
});
|
167
|
+
|
168
|
+
$('form').live('ajax:complete.rails', function(event) {
|
169
|
+
if (this == event.target) enableFormElements($(this));
|
170
|
+
});
|
171
|
+
/**
|
172
|
+
* End Rails.js
|
173
|
+
**/
|
174
|
+
})( jQuery );
|
data/spec/CruyffSpec.js
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
describe('Cruyff',function() {
|
2
|
+
var cruyffSettings,
|
3
|
+
element;
|
4
|
+
|
5
|
+
beforeEach(function() {
|
6
|
+
$.jasmine.inject('<div id="response"></div>');
|
7
|
+
});
|
8
|
+
|
9
|
+
describe('Setup from hyperlink', function() {
|
10
|
+
beforeEach(function() {
|
11
|
+
$.jasmine.inject('<a href="spec/fixtures/view.html"\
|
12
|
+
data-type="json"\
|
13
|
+
data-method="delete"\
|
14
|
+
data-remote="true">remote_link</a>');
|
15
|
+
element = $('a[data-remote]');
|
16
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
17
|
+
});
|
18
|
+
|
19
|
+
it('should setup url',function(){
|
20
|
+
expect(cruyffSettings.url).toEqual('spec/fixtures/view.html');
|
21
|
+
});
|
22
|
+
|
23
|
+
it('should setup method',function(){
|
24
|
+
expect(cruyffSettings.method).toEqual('delete');
|
25
|
+
});
|
26
|
+
|
27
|
+
it('should setup data type from hyperlink',function(){
|
28
|
+
expect(cruyffSettings.dataType).toEqual('json');
|
29
|
+
});
|
30
|
+
|
31
|
+
it('should setup data type from ajax Settings',function(){
|
32
|
+
element.attr('data-type', '');
|
33
|
+
var _ajaxSettings = $.ajaxSettings;
|
34
|
+
$.ajaxSettings = {dataType: 'xml'};
|
35
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
36
|
+
expect(cruyffSettings.dataType).toEqual('xml');
|
37
|
+
$.ajaxSettings = _ajaxSettings;
|
38
|
+
});
|
39
|
+
|
40
|
+
it('should setup data',function(){
|
41
|
+
expect(cruyffSettings.data).toBeNull();
|
42
|
+
});
|
43
|
+
|
44
|
+
it('should setup response',function(){
|
45
|
+
expect(cruyffSettings.responseSelector).toEqual('#response');
|
46
|
+
expect(cruyffSettings.response).toBeDefined();
|
47
|
+
});
|
48
|
+
|
49
|
+
});
|
50
|
+
|
51
|
+
describe('Setup from form', function() {
|
52
|
+
beforeEach(function() {
|
53
|
+
$.jasmine.inject('<form action="spec/fixtures/view.html"\
|
54
|
+
data-type="json"\
|
55
|
+
method="get"\
|
56
|
+
data-remote="true">\
|
57
|
+
<input type="text" value="a1" name="post[title]" id="post_title">\
|
58
|
+
<input type="submit" value="Update" name="commit" id="post_submit">\
|
59
|
+
</form>');
|
60
|
+
element = $('form[data-remote]');
|
61
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
62
|
+
});
|
63
|
+
|
64
|
+
it('should setup url',function(){
|
65
|
+
expect(cruyffSettings.url).toEqual('spec/fixtures/view.html');
|
66
|
+
});
|
67
|
+
|
68
|
+
it('should setup method',function(){
|
69
|
+
expect(cruyffSettings.method).toEqual('get');
|
70
|
+
});
|
71
|
+
|
72
|
+
it('should setup data type from form',function(){
|
73
|
+
expect(cruyffSettings.dataType).toEqual('json');
|
74
|
+
});
|
75
|
+
|
76
|
+
it('should setup data type from ajax Settings',function(){
|
77
|
+
element.attr('data-type', '');
|
78
|
+
var _ajaxSettings = $.ajaxSettings;
|
79
|
+
$.ajaxSettings = {dataType: 'xml'};
|
80
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
81
|
+
expect(cruyffSettings.dataType).toEqual('xml');
|
82
|
+
$.ajaxSettings = _ajaxSettings;
|
83
|
+
});
|
84
|
+
|
85
|
+
it('should setup data',function(){
|
86
|
+
expect(cruyffSettings.data).toEqual([{name:'post[title]', value:'a1'}]);
|
87
|
+
});
|
88
|
+
|
89
|
+
it('should setup data with submit button',function(){
|
90
|
+
element.data('ujs:submit-button', 'button');
|
91
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
92
|
+
expect(cruyffSettings.data).toEqual([{name:'post[title]', value:'a1'}, 'button']);
|
93
|
+
expect(element.data('ujs:submit-button')).toBeNull();
|
94
|
+
});
|
95
|
+
|
96
|
+
it('should setup response',function(){
|
97
|
+
expect(cruyffSettings.responseSelector).toEqual('#response');
|
98
|
+
expect(cruyffSettings.response).toBeDefined();
|
99
|
+
});
|
100
|
+
|
101
|
+
});
|
102
|
+
|
103
|
+
describe('Render Ajax Response', function() {
|
104
|
+
beforeEach(function() {
|
105
|
+
$.jasmine.inject('<a href="spec/fixtures/view.html"\
|
106
|
+
data-remote="true">remote_link</a>');
|
107
|
+
element = $('a[data-remote]');
|
108
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
109
|
+
});
|
110
|
+
|
111
|
+
it('should render success response',function(){
|
112
|
+
runs(function() {
|
113
|
+
$.fn.handleRemoteCrud(element);
|
114
|
+
});
|
115
|
+
waits(100);
|
116
|
+
runs(function() {
|
117
|
+
expect(cruyffSettings.response).toHaveHtml('view html');
|
118
|
+
});
|
119
|
+
});
|
120
|
+
|
121
|
+
it('should render error response',function(){
|
122
|
+
element.attr('href', 'bad/url');
|
123
|
+
runs(function() {
|
124
|
+
$.fn.handleRemoteCrud(element);
|
125
|
+
});
|
126
|
+
waits(100);
|
127
|
+
runs(function() {
|
128
|
+
expect(cruyffSettings.response.html()).toContain('NS_ERROR_DOM_BAD_URI');
|
129
|
+
});
|
130
|
+
});
|
131
|
+
|
132
|
+
});
|
133
|
+
|
134
|
+
describe('Bookmark Ajax calls', function() {
|
135
|
+
beforeEach(function() {
|
136
|
+
$.jasmine.inject('<a href="spec/fixtures/view.html"\
|
137
|
+
data-remote="true">remote_link</a>');
|
138
|
+
element = $('a[data-remote]');
|
139
|
+
cruyffSettings = $.fn.cruyffSetup(element);
|
140
|
+
});
|
141
|
+
|
142
|
+
it('should bookmark',function() {
|
143
|
+
runs(function() {
|
144
|
+
$.fn.handleRemoteCrud(element);
|
145
|
+
});
|
146
|
+
waits(100);
|
147
|
+
runs(function() {
|
148
|
+
expect($.bbq.getState('app')).toEqual('spec/fixtures/view.html');
|
149
|
+
});
|
150
|
+
});
|
151
|
+
|
152
|
+
it('should load browser url',function() {
|
153
|
+
$.bbq.pushState('app=spec/fixtures/view.html');
|
154
|
+
expect($.fn.cruyffUrl).toEqual('spec/fixtures/view.html');
|
155
|
+
});
|
156
|
+
|
157
|
+
});
|
158
|
+
|
159
|
+
});
|
data/spec/SpecHelper.js
ADDED
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<html><body>view html</body></html>
|
@@ -0,0 +1,188 @@
|
|
1
|
+
jasmine.TrivialReporter = function(doc) {
|
2
|
+
this.document = doc || document;
|
3
|
+
this.suiteDivs = {};
|
4
|
+
this.logRunningSpecs = false;
|
5
|
+
};
|
6
|
+
|
7
|
+
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
8
|
+
var el = document.createElement(type);
|
9
|
+
|
10
|
+
for (var i = 2; i < arguments.length; i++) {
|
11
|
+
var child = arguments[i];
|
12
|
+
|
13
|
+
if (typeof child === 'string') {
|
14
|
+
el.appendChild(document.createTextNode(child));
|
15
|
+
} else {
|
16
|
+
if (child) { el.appendChild(child); }
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
for (var attr in attrs) {
|
21
|
+
if (attr == "className") {
|
22
|
+
el[attr] = attrs[attr];
|
23
|
+
} else {
|
24
|
+
el.setAttribute(attr, attrs[attr]);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
return el;
|
29
|
+
};
|
30
|
+
|
31
|
+
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
32
|
+
var showPassed, showSkipped;
|
33
|
+
|
34
|
+
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
35
|
+
this.createDom('div', { className: 'banner' },
|
36
|
+
this.createDom('div', { className: 'logo' },
|
37
|
+
this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"),
|
38
|
+
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
39
|
+
this.createDom('div', { className: 'options' },
|
40
|
+
"Show ",
|
41
|
+
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
42
|
+
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
43
|
+
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
44
|
+
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
45
|
+
)
|
46
|
+
),
|
47
|
+
|
48
|
+
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
49
|
+
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
50
|
+
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
51
|
+
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
52
|
+
);
|
53
|
+
|
54
|
+
this.document.body.appendChild(this.outerDiv);
|
55
|
+
|
56
|
+
var suites = runner.suites();
|
57
|
+
for (var i = 0; i < suites.length; i++) {
|
58
|
+
var suite = suites[i];
|
59
|
+
var suiteDiv = this.createDom('div', { className: 'suite' },
|
60
|
+
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
61
|
+
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
62
|
+
this.suiteDivs[suite.id] = suiteDiv;
|
63
|
+
var parentDiv = this.outerDiv;
|
64
|
+
if (suite.parentSuite) {
|
65
|
+
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
66
|
+
}
|
67
|
+
parentDiv.appendChild(suiteDiv);
|
68
|
+
}
|
69
|
+
|
70
|
+
this.startedAt = new Date();
|
71
|
+
|
72
|
+
var self = this;
|
73
|
+
showPassed.onclick = function(evt) {
|
74
|
+
if (showPassed.checked) {
|
75
|
+
self.outerDiv.className += ' show-passed';
|
76
|
+
} else {
|
77
|
+
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
78
|
+
}
|
79
|
+
};
|
80
|
+
|
81
|
+
showSkipped.onclick = function(evt) {
|
82
|
+
if (showSkipped.checked) {
|
83
|
+
self.outerDiv.className += ' show-skipped';
|
84
|
+
} else {
|
85
|
+
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
86
|
+
}
|
87
|
+
};
|
88
|
+
};
|
89
|
+
|
90
|
+
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
91
|
+
var results = runner.results();
|
92
|
+
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
93
|
+
this.runnerDiv.setAttribute("class", className);
|
94
|
+
//do it twice for IE
|
95
|
+
this.runnerDiv.setAttribute("className", className);
|
96
|
+
var specs = runner.specs();
|
97
|
+
var specCount = 0;
|
98
|
+
for (var i = 0; i < specs.length; i++) {
|
99
|
+
if (this.specFilter(specs[i])) {
|
100
|
+
specCount++;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
104
|
+
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
105
|
+
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
106
|
+
|
107
|
+
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
108
|
+
};
|
109
|
+
|
110
|
+
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
111
|
+
var results = suite.results();
|
112
|
+
var status = results.passed() ? 'passed' : 'failed';
|
113
|
+
if (results.totalCount == 0) { // todo: change this to check results.skipped
|
114
|
+
status = 'skipped';
|
115
|
+
}
|
116
|
+
this.suiteDivs[suite.id].className += " " + status;
|
117
|
+
};
|
118
|
+
|
119
|
+
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
120
|
+
if (this.logRunningSpecs) {
|
121
|
+
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
122
|
+
}
|
123
|
+
};
|
124
|
+
|
125
|
+
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
126
|
+
var results = spec.results();
|
127
|
+
var status = results.passed() ? 'passed' : 'failed';
|
128
|
+
if (results.skipped) {
|
129
|
+
status = 'skipped';
|
130
|
+
}
|
131
|
+
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
132
|
+
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
133
|
+
this.createDom('a', {
|
134
|
+
className: 'description',
|
135
|
+
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
136
|
+
title: spec.getFullName()
|
137
|
+
}, spec.description));
|
138
|
+
|
139
|
+
|
140
|
+
var resultItems = results.getItems();
|
141
|
+
var messagesDiv = this.createDom('div', { className: 'messages' });
|
142
|
+
for (var i = 0; i < resultItems.length; i++) {
|
143
|
+
var result = resultItems[i];
|
144
|
+
|
145
|
+
if (result.type == 'log') {
|
146
|
+
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
147
|
+
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
148
|
+
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
149
|
+
|
150
|
+
if (result.trace.stack) {
|
151
|
+
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
if (messagesDiv.childNodes.length > 0) {
|
157
|
+
specDiv.appendChild(messagesDiv);
|
158
|
+
}
|
159
|
+
|
160
|
+
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
161
|
+
};
|
162
|
+
|
163
|
+
jasmine.TrivialReporter.prototype.log = function() {
|
164
|
+
var console = jasmine.getGlobal().console;
|
165
|
+
if (console && console.log) {
|
166
|
+
if (console.log.apply) {
|
167
|
+
console.log.apply(console, arguments);
|
168
|
+
} else {
|
169
|
+
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
170
|
+
}
|
171
|
+
}
|
172
|
+
};
|
173
|
+
|
174
|
+
jasmine.TrivialReporter.prototype.getLocation = function() {
|
175
|
+
return this.document.location;
|
176
|
+
};
|
177
|
+
|
178
|
+
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
179
|
+
var paramMap = {};
|
180
|
+
var params = this.getLocation().search.substring(1).split('&');
|
181
|
+
for (var i = 0; i < params.length; i++) {
|
182
|
+
var p = params[i].split('=');
|
183
|
+
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
184
|
+
}
|
185
|
+
|
186
|
+
if (!paramMap["spec"]) return true;
|
187
|
+
return spec.getFullName().indexOf(paramMap["spec"]) == 0;
|
188
|
+
};
|