konacha 1.5.1 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +7 -0
- data/README.md +71 -57
- data/app/assets/javascripts/konacha/iframe.js +40 -0
- data/app/assets/javascripts/konacha/parent.js +14 -0
- data/app/assets/javascripts/konacha/runner.js +45 -0
- data/app/assets/stylesheets/konacha.css +75 -0
- data/app/controllers/konacha/specs_controller.rb +6 -1
- data/app/models/konacha/spec.rb +1 -1
- data/app/views/konacha/specs/iframe.html.erb +18 -0
- data/app/views/konacha/specs/parent.html.erb +16 -0
- data/config/routes.rb +4 -2
- data/images/frame-select.png +0 -0
- data/konacha.gemspec +1 -1
- data/lib/konacha/engine.rb +1 -0
- data/lib/konacha/runner.rb +22 -57
- data/spec/controllers/specs_controller_spec.rb +4 -4
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/spec/isolated/errors/failing_iframe_spec.js.coffee +1 -0
- data/spec/dummy/spec/javascripts/{test_element_spec.js.coffee → body_spec.js.coffee} +4 -7
- data/spec/dummy/spec/javascripts/isolation/a_spec.js +6 -0
- data/spec/dummy/spec/javascripts/isolation/b_spec.js +6 -0
- data/spec/dummy/spec/javascripts/templating_spec.js +4 -4
- data/spec/dummy/spec/javascripts/ui_spec.js +7 -0
- data/spec/error_handling_spec.rb +33 -0
- data/spec/models/spec_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/views/specs/{specs.html.erb_spec.rb → iframe.html.erb_spec.rb} +12 -8
- data/vendor/assets/javascripts/mocha.js +297 -114
- metadata +195 -180
- data/app/views/konacha/specs/specs.html.erb +0 -16
- data/lib/assets/javascripts/konacha.js +0 -20
- data/lib/assets/javascripts/konacha/runner.js +0 -50
- data/lib/assets/javascripts/konacha/server.js +0 -6
- data/lib/assets/stylesheets/konacha.css +0 -5
- data/spec/dummy/spec/javascripts/konacha_config.js +0 -2
- data/spec/dummy/spec/javascripts/konacha_config_spec.js +0 -9
data/History.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# master
|
2
|
+
|
3
|
+
* Run tests in an iframe, with `<body id="konacha">`
|
4
|
+
* Removed support for konacha_config.js and Konacha.mochaOptions in favor of
|
5
|
+
Mocha's own configuration methods. See the README for update instructions.
|
6
|
+
* Update mocha (1.5.0)
|
7
|
+
|
1
8
|
# 1.x-stable
|
2
9
|
|
3
10
|
# 1.5.1
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Dependency Status](https://gemnasium.com/jfirebaugh/konacha.png)](https://gemnasium.com/jfirebaugh/konacha)
|
5
5
|
|
6
6
|
Konacha is a Rails engine that allows you to test your JavaScript with the
|
7
|
-
[
|
7
|
+
[Mocha](http://visionmedia.github.com/mocha/) test framework and [chai](http://chaijs.com/)
|
8
8
|
assertion library.
|
9
9
|
|
10
10
|
[![Konacha][2]][1]
|
@@ -68,6 +68,9 @@ describe "Array#sum", ->
|
|
68
68
|
[1,2,3].sum().should.equal(6)
|
69
69
|
```
|
70
70
|
|
71
|
+
Your tests are run inside an iframe. You have the entire `<body>` element to
|
72
|
+
yourself, and it is automatically reset between tests.
|
73
|
+
|
71
74
|
## Running (Rake Tasks)
|
72
75
|
|
73
76
|
### In the Browser
|
@@ -85,7 +88,13 @@ to a subdirectory to run a subset of specs (e.g.
|
|
85
88
|
`http://localhost:3500/models`).
|
86
89
|
|
87
90
|
This is the recommended mode for development, since you can simply hit refresh
|
88
|
-
to reload all your test and asset files.
|
91
|
+
to reload all your test and asset files. To debug tests, use the `debugger`
|
92
|
+
statement anywhere in a test to halt execution.
|
93
|
+
|
94
|
+
To run code in the JavaScript console, be sure to select the desired iframe
|
95
|
+
first, so your code runs in the correct context.
|
96
|
+
|
97
|
+
![Selecting the test-context frame in Chrome](https://raw.github.com/jfirebaugh/konacha/master/images/frame-select.png)
|
89
98
|
|
90
99
|
### Command-Line Runner
|
91
100
|
|
@@ -95,7 +104,7 @@ To run your tests from the command line, type:
|
|
95
104
|
$ bundle exec rake konacha:run
|
96
105
|
```
|
97
106
|
|
98
|
-
To run individual specs, pass a comma
|
107
|
+
To run individual specs, pass a comma separated list of spec file names via
|
99
108
|
the `SPEC` environment variable.
|
100
109
|
|
101
110
|
```
|
@@ -107,7 +116,7 @@ $ bundle exec rake konacha:run SPEC=foo_spec,bar_spec,etc_spec
|
|
107
116
|
|
108
117
|
Since Konacha integrates with the asset pipeline, using setup helpers in your specs is
|
109
118
|
easy. Just create a `spec_helper.js` or `spec_helper.js.coffee` file in `specs/javascripts`
|
110
|
-
and require it in your tests
|
119
|
+
and require it in your tests:
|
111
120
|
|
112
121
|
```javascript
|
113
122
|
//= require spec_helper
|
@@ -121,14 +130,27 @@ describe("Array#sum", function() {
|
|
121
130
|
The `spec_helper` is a good place to set Mocha and Chai options as well, for instance:
|
122
131
|
|
123
132
|
```javascript
|
133
|
+
// set the Mocha test interface
|
134
|
+
// see http://visionmedia.github.com/mocha/#interfaces
|
135
|
+
mocha.ui('bdd');
|
136
|
+
|
137
|
+
// ignore the following globals during leak detection
|
138
|
+
mocha.globals(['YUI']);
|
139
|
+
|
140
|
+
// or, ignore all leaks
|
141
|
+
mocha.ignoreLeaks();
|
142
|
+
|
143
|
+
// set slow test timeout in ms
|
144
|
+
mocha.timeout(5);
|
145
|
+
|
124
146
|
// Show stack trace on failing assertion.
|
125
147
|
chai.Assertion.includeStack = true;
|
126
148
|
```
|
127
149
|
|
128
150
|
## Directives and Asset Bundling
|
129
151
|
|
130
|
-
We suggest that you explicitly require just the assets necessary for each spec.
|
131
|
-
|
152
|
+
We suggest that you explicitly require just the assets necessary for each spec.
|
153
|
+
Konacha runs each spec file in isolation, and requiring things explicitly will help
|
132
154
|
ensure your scripts don't accumulate hidden dependencies and tight coupling.
|
133
155
|
|
134
156
|
However, you are free to ignore this advice and require the entire application.js asset
|
@@ -143,42 +165,20 @@ Konacha can be configured in an initializer, e.g. `config/initializers/konacha.r
|
|
143
165
|
|
144
166
|
```ruby
|
145
167
|
Konacha.configure do |config|
|
146
|
-
config.spec_dir
|
147
|
-
config.driver
|
168
|
+
config.spec_dir = "spec/javascripts"
|
169
|
+
config.driver = :selenium
|
170
|
+
config.stylesheets = %w(application)
|
148
171
|
end if defined?(Konacha)
|
149
172
|
```
|
150
173
|
|
151
174
|
The `defined?` check is necessary to avoid a dependency on Konacha in the production
|
152
175
|
environment.
|
153
176
|
|
154
|
-
The `spec_dir` option tells Konacha where to find JavaScript specs. `driver`
|
155
|
-
Capybara driver used for the `run` task (try `:webkit`, after
|
156
|
-
[capybara-webkit](https://github.com/thoughtbot/capybara-webkit)).
|
157
|
-
|
158
|
-
The values above are the defaults.
|
159
|
-
|
160
|
-
### Mocha Configuration
|
161
|
-
|
162
|
-
You can customize the Mocha options passed into `mocha.setup(..)` by creating a file
|
163
|
-
named `konacha_config.js` or `konacha_config.js.coffee` in `spec/javascripts` and
|
164
|
-
setting properties of `Konacha.mochaOptions`:
|
165
|
-
|
166
|
-
```javascript
|
167
|
-
// set the Mocha test interface
|
168
|
-
// see http://visionmedia.github.com/mocha/#interfaces
|
169
|
-
Konacha.mochaOptions.ui = 'bdd';
|
170
|
-
|
171
|
-
// ignore the following globals during leak detection
|
172
|
-
Konacha.mochaOptions.globals = ['YUI'];
|
173
|
-
|
174
|
-
// or, ignore all leaks
|
175
|
-
Konacha.mochaOptions.ignoreLeaks = true;
|
176
|
-
|
177
|
-
// set slow test timeout in ms
|
178
|
-
Konacha.mochaOptions.timeout = 5;
|
179
|
-
```
|
180
|
-
|
181
|
-
The `ui` and `reporter` Mocha options are set by Konacha and must not be modified.
|
177
|
+
The `spec_dir` option tells Konacha where to find JavaScript specs. `driver`
|
178
|
+
names a Capybara driver used for the `run` task (try `:webkit`, after
|
179
|
+
installing [capybara-webkit](https://github.com/thoughtbot/capybara-webkit)).
|
180
|
+
The `stylesheets` option sets the stylesheets to be linked from the `<head>`
|
181
|
+
of the test runner iframe. The values above are the defaults.
|
182
182
|
|
183
183
|
## Test Interface and Assertions
|
184
184
|
|
@@ -194,30 +194,12 @@ If you use jQuery, you may want to check out [chai-jquery](https://github.com/jf
|
|
194
194
|
for some jQuery-specific assertions. You can add it painlessly with the
|
195
195
|
[chai-jquery-rails](https://github.com/wordofchristian/chai-jquery-rails) gem.
|
196
196
|
|
197
|
-
## Transactions
|
198
|
-
|
199
|
-
One problem often faced when writing unit tests for client side code is that changes
|
200
|
-
to the page are not reverted for the next example, so that successive examples become
|
201
|
-
dependent on each other. Konacha adds a special div to your page with an id of `konacha`.
|
202
|
-
This div is automatically emptied before each example. You should avoid appending markup
|
203
|
-
to the page body and instead append it to the `#konacha` div:
|
204
|
-
|
205
|
-
```coffeescript
|
206
|
-
describe "transactions", ->
|
207
|
-
it "should add stuff in one test...", ->
|
208
|
-
$('#konacha').append('<h1 id="added">New Stuff</h1>')
|
209
|
-
$('#konacha h1#added').length.should.equal(1)
|
210
|
-
|
211
|
-
it "... should have been removed before the next starts", ->
|
212
|
-
$('#konacha h1#added').length.should.equal(0)
|
213
|
-
```
|
214
|
-
|
215
197
|
## Templates / Fixtures
|
216
198
|
|
217
199
|
Konacha has no template (a.k.a. HTML fixture) support of its own. Instead, we suggest you use
|
218
200
|
Sprocket's built in support for JavaScript template (`.jst`) files. Add a `spec/javascripts/templates`
|
219
201
|
directory, place template files there (using any JS template language supported by Sprockets),
|
220
|
-
require them in your spec or spec_helper, and render them into the
|
202
|
+
require them in your spec or spec_helper, and render them into the `<body>`.
|
221
203
|
|
222
204
|
For example, in `spec/javascripts/templates/hello.jst.ejs`:
|
223
205
|
|
@@ -238,12 +220,44 @@ And your spec:
|
|
238
220
|
|
239
221
|
describe("templating", function() {
|
240
222
|
it("is built in to Sprockets", function() {
|
241
|
-
$('
|
242
|
-
$('
|
223
|
+
$('body').html(JST['templates/hello']());
|
224
|
+
$('body h1').text().should.equal('Hello Konacha!');
|
243
225
|
});
|
244
226
|
});
|
245
227
|
```
|
246
228
|
|
229
|
+
## Upgrading from Konacha 1.x
|
230
|
+
|
231
|
+
### Iframe
|
232
|
+
|
233
|
+
As of Konacha 2.0, each test file is run inside an isolated iframe. For
|
234
|
+
compatibility with Konacha 1.x, the iframe's `<body>` element will have
|
235
|
+
`id="konacha"` set on it. If your specs are already self-contained, you may be
|
236
|
+
able to upgrade without any changes to your test code.
|
237
|
+
|
238
|
+
### Options
|
239
|
+
|
240
|
+
In Konacha 1.x you would set `Konacha.mochaOptions` in `konacha_config.js`:
|
241
|
+
|
242
|
+
```javascript
|
243
|
+
// Old syntax
|
244
|
+
Konacha.mochaOptions.ignoreLeaks = true;
|
245
|
+
```
|
246
|
+
|
247
|
+
The `konacha_config.js` file is no longer used by Konacha 2.0. Instead, call
|
248
|
+
Mocha's own methods in [`spec_helper.js`](#spec-helper):
|
249
|
+
|
250
|
+
```javascript
|
251
|
+
// New syntax
|
252
|
+
mocha.ignoreLeaks();
|
253
|
+
```
|
254
|
+
|
255
|
+
### Global `mocha`
|
256
|
+
|
257
|
+
Konacha 2.0 ships with an upgraded Mocha. Some objects that were previously
|
258
|
+
available on the global `mocha` object might now be located on `Mocha`. If you
|
259
|
+
get an error message to this effect, adjust your code accordingly.
|
260
|
+
|
247
261
|
## Contributing
|
248
262
|
|
249
263
|
```bash
|
@@ -0,0 +1,40 @@
|
|
1
|
+
window.mocha = parent.mocha;
|
2
|
+
window.Mocha = parent.Mocha;
|
3
|
+
|
4
|
+
window.Konacha = {
|
5
|
+
reset: function() {
|
6
|
+
document.body = document.createElement('body');
|
7
|
+
document.body.id = 'konacha';
|
8
|
+
}
|
9
|
+
};
|
10
|
+
|
11
|
+
var suite = Mocha.Suite.create(mocha.suite);
|
12
|
+
|
13
|
+
mocha.ui = function (name) {
|
14
|
+
this._ui = Mocha.interfaces[name];
|
15
|
+
if (!this._ui) throw new Error('invalid interface "' + name + '"');
|
16
|
+
this._ui = this._ui(suite);
|
17
|
+
suite.emit('pre-require', window, null, this);
|
18
|
+
return this;
|
19
|
+
};
|
20
|
+
|
21
|
+
mocha.ui('bdd');
|
22
|
+
|
23
|
+
suite.beforeAll(function () {
|
24
|
+
var contexts = parent.document.getElementsByClassName("test-context");
|
25
|
+
for (var i = 0; i < contexts.length; ++i) {
|
26
|
+
if (contexts[i].contentWindow == window) {
|
27
|
+
contexts[i].style.display = "block";
|
28
|
+
} else {
|
29
|
+
contexts[i].style.display = null;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
suite.beforeEach(function () {
|
35
|
+
Konacha.reset();
|
36
|
+
});
|
37
|
+
|
38
|
+
var expect = chai.expect,
|
39
|
+
should = chai.should(),
|
40
|
+
assert = chai.assert;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
window.onload = function () {
|
2
|
+
var iframes = document.getElementsByTagName('iframe');
|
3
|
+
for (var i = 0; i < iframes.length; ++i) {
|
4
|
+
if (!iframes[i].contentWindow.mocha) {
|
5
|
+
(function (path) {
|
6
|
+
mocha.suite.addTest(new Mocha.Test(path, function () {
|
7
|
+
throw new Error("Failed to load " + path + ". Perhaps it failed to compile?");
|
8
|
+
}));
|
9
|
+
})(iframes[i].getAttribute("data-path"));
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
mocha.run();
|
14
|
+
};
|
@@ -0,0 +1,45 @@
|
|
1
|
+
Konacha = {
|
2
|
+
dots: "",
|
3
|
+
getResults: function() {
|
4
|
+
return JSON.stringify(Konacha.results);
|
5
|
+
}
|
6
|
+
};
|
7
|
+
|
8
|
+
mocha.reporter(function(runner) {
|
9
|
+
Mocha.reporters.Base.call(this, runner);
|
10
|
+
|
11
|
+
runner.on('start', function() {
|
12
|
+
Konacha.results = [];
|
13
|
+
});
|
14
|
+
|
15
|
+
runner.on('pass', function(test) {
|
16
|
+
Konacha.dots += ".";
|
17
|
+
Konacha.results.push({
|
18
|
+
name:test.title,
|
19
|
+
passed:true
|
20
|
+
});
|
21
|
+
});
|
22
|
+
|
23
|
+
runner.on('fail', function(test) {
|
24
|
+
Konacha.dots += "F";
|
25
|
+
Konacha.results.push({
|
26
|
+
name:test.title,
|
27
|
+
passed:false,
|
28
|
+
message:test.err.message,
|
29
|
+
trace:test.err.stack
|
30
|
+
});
|
31
|
+
});
|
32
|
+
|
33
|
+
runner.on('pending', function(test) {
|
34
|
+
Konacha.dots += "P";
|
35
|
+
Konacha.results.push({
|
36
|
+
name:test.title,
|
37
|
+
passed:false,
|
38
|
+
pending:true
|
39
|
+
});
|
40
|
+
});
|
41
|
+
|
42
|
+
runner.on('end', function() {
|
43
|
+
Konacha.done = true;
|
44
|
+
});
|
45
|
+
});
|
@@ -0,0 +1,75 @@
|
|
1
|
+
/*
|
2
|
+
*= require mocha
|
3
|
+
*/
|
4
|
+
|
5
|
+
body {
|
6
|
+
padding: 60px 0;
|
7
|
+
}
|
8
|
+
|
9
|
+
.test-context {
|
10
|
+
-webkit-transform-origin: right top;
|
11
|
+
-moz-transform-origin: right top;
|
12
|
+
-ms-transform-origin: right top;
|
13
|
+
-o-transform-origin: right top;
|
14
|
+
transform-origin: right top;
|
15
|
+
|
16
|
+
width: 1000px;
|
17
|
+
height: 700px;
|
18
|
+
|
19
|
+
position: fixed;
|
20
|
+
top: 80px;
|
21
|
+
right: 25px;
|
22
|
+
|
23
|
+
/* inset */
|
24
|
+
border-top: 2px solid #c8c8c8;
|
25
|
+
border-bottom: 2px solid #eee;
|
26
|
+
border-left: 2px solid #ddd;
|
27
|
+
border-right: 2px solid #ddd;
|
28
|
+
|
29
|
+
/* opaque */
|
30
|
+
z-index: 1;
|
31
|
+
background-color: white;
|
32
|
+
|
33
|
+
/* dynamically shown */
|
34
|
+
display: none;
|
35
|
+
}
|
36
|
+
|
37
|
+
@media (max-width: 1860px) {
|
38
|
+
.test-context {
|
39
|
+
-webkit-transform: scale(0.6666666666);
|
40
|
+
-moz-transform: scale(0.6666666666);
|
41
|
+
-ms-transform: scale(0.6666666666);
|
42
|
+
-o-transform: scale(0.6666666666);
|
43
|
+
transform: scale(0.6666666666);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
@media (max-width: 1550px) {
|
48
|
+
.test-context {
|
49
|
+
-webkit-transform: scale(0.5);
|
50
|
+
-moz-transform: scale(0.5);
|
51
|
+
-ms-transform: scale(0.5);
|
52
|
+
-o-transform: scale(0.5);
|
53
|
+
transform: scale(0.5);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
@media (max-width: 1230px) {
|
58
|
+
.test-context {
|
59
|
+
-webkit-transform: scale(0.3333333333);
|
60
|
+
-moz-transform: scale(0.3333333333);
|
61
|
+
-ms-transform: scale(0.3333333333);
|
62
|
+
-o-transform: scale(0.3333333333);
|
63
|
+
transform: scale(0.3333333333);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
@media (max-width: 1050px) {
|
68
|
+
.test-context {
|
69
|
+
-webkit-transform: scale(0.2);
|
70
|
+
-moz-transform: scale(0.2);
|
71
|
+
-ms-transform: scale(0.2);
|
72
|
+
-o-transform: scale(0.2);
|
73
|
+
transform: scale(0.2);
|
74
|
+
}
|
75
|
+
}
|
@@ -4,8 +4,13 @@ module Konacha
|
|
4
4
|
render :text => "Not found", :status => 404
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
7
|
+
def parent
|
8
8
|
@specs = Konacha::Spec.find(params[:path] || "")
|
9
9
|
end
|
10
|
+
|
11
|
+
def iframe
|
12
|
+
@specs = Konacha::Spec.find(params[:path])
|
13
|
+
@stylesheets = Konacha::Engine.config.konacha.stylesheets
|
14
|
+
end
|
10
15
|
end
|
11
16
|
end
|
data/app/models/konacha/spec.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
|
5
|
+
<title>Konacha Tests</title>
|
6
|
+
|
7
|
+
<% @stylesheets.each do |file| %>
|
8
|
+
<%# Use :debug => false for stylesheets to improve page load performance. %>
|
9
|
+
<%= stylesheet_link_tag file, :debug => false %>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<%= javascript_include_tag "chai", "konacha/iframe", :debug => false %>
|
13
|
+
|
14
|
+
<%= spec_include_tag *@specs %>
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
</body>
|
18
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
|
5
|
+
<title>Konacha Tests</title>
|
6
|
+
<%= stylesheet_link_tag "konacha", :debug => false %>
|
7
|
+
<%= javascript_include_tag "mocha", "konacha/parent", :debug => false %>
|
8
|
+
<%= javascript_include_tag("konacha/runner", :debug => false) if Konacha.mode == :runner %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<% @specs.each do |spec| %>
|
12
|
+
<%= content_tag :iframe, '', :src => spec.url, :class => 'test-context', "data-path" => spec.path %>
|
13
|
+
<% end %>
|
14
|
+
<div id="mocha"></div>
|
15
|
+
</body>
|
16
|
+
</html>
|