konacha 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +8 -1
- data/Gemfile-rails4 +7 -0
- data/History.md +4 -0
- data/README.md +5 -2
- data/Rakefile +4 -0
- data/app/views/konacha/specs/parent.html.erb +1 -1
- data/config.ru +2 -0
- data/config/routes.rb +1 -1
- data/konacha.gemspec +6 -4
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/environments/development.rb +2 -2
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/error_handling_spec.rb +1 -1
- data/spec/runner_spec.rb +101 -85
- data/spec/server_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -2
- data/spec/views/specs/iframe.html.erb_spec.rb +6 -5
- data/spec/views/specs/parent.html.erb_spec.rb +20 -0
- data/vendor/assets/javascripts/chai.js +212 -52
- data/vendor/assets/javascripts/mocha.js +372 -32
- data/vendor/assets/stylesheets/mocha.css +8 -4
- metadata +48 -13
data/.travis.yml
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
language: ruby
|
1
2
|
rvm:
|
2
3
|
- 1.8.7
|
3
4
|
- 1.9.3
|
5
|
+
gemfile:
|
6
|
+
- Gemfile
|
7
|
+
- Gemfile-rails4
|
4
8
|
before_script:
|
5
9
|
- sh -e /etc/init.d/xvfb start
|
6
10
|
- export DISPLAY=:99.0
|
7
11
|
matrix:
|
12
|
+
exclude:
|
13
|
+
- gemfile: Gemfile-rails4
|
14
|
+
rvm: 1.8.7
|
8
15
|
allow_failures:
|
9
|
-
- {
|
16
|
+
- { gemfile: Gemfile-rails4 }
|
data/Gemfile-rails4
ADDED
data/History.md
CHANGED
data/README.md
CHANGED
@@ -208,8 +208,11 @@ Konacha will make all three of chai's assertion styles available to you: `expect
|
|
208
208
|
`should`, and `assert`. See the chai documentation for the details.
|
209
209
|
|
210
210
|
If you use jQuery, you may want to check out [chai-jquery](https://github.com/jfirebaugh/chai-jquery)
|
211
|
-
for some jQuery-specific assertions.
|
212
|
-
[chai
|
211
|
+
for some jQuery-specific assertions. There are a lot of interesting chai
|
212
|
+
matchers out there, see [the chai plugins page](http://chaijs.com/plugins)
|
213
|
+
|
214
|
+
To make all these available for your konacha environment, see the
|
215
|
+
[Konacha-chai-matchers gem](https://github.com/matthijsgroen/konacha-chai-matchers)
|
213
216
|
|
214
217
|
## Templates / Fixtures
|
215
218
|
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<% @specs.each do |spec| %>
|
12
|
-
<%= content_tag :iframe, "", :src =>
|
12
|
+
<%= content_tag :iframe, "", :src => iframe_path(spec.asset_name), :class => "test-context", "data-path" => spec.path %>
|
13
13
|
<% end %>
|
14
14
|
<div id="mocha"></div>
|
15
15
|
</body>
|
data/config.ru
ADDED
data/config/routes.rb
CHANGED
data/konacha.gemspec
CHANGED
@@ -17,18 +17,20 @@ the asset pipeline and engines.}
|
|
17
17
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
gem.name = "konacha"
|
19
19
|
gem.require_paths = ["lib"]
|
20
|
-
gem.version = "2.
|
20
|
+
gem.version = "2.2.0"
|
21
|
+
gem.license = "MIT"
|
21
22
|
|
22
|
-
gem.add_dependency "railties", "
|
23
|
-
gem.add_dependency "actionpack", "
|
23
|
+
gem.add_dependency "railties", ">= 3.1", "< 5"
|
24
|
+
gem.add_dependency "actionpack", ">= 3.1", "< 5"
|
24
25
|
gem.add_dependency "sprockets"
|
25
26
|
gem.add_dependency "capybara"
|
26
27
|
gem.add_dependency "colorize"
|
27
28
|
|
28
29
|
gem.add_development_dependency "jquery-rails"
|
29
|
-
gem.add_development_dependency "rspec-rails"
|
30
|
+
gem.add_development_dependency "rspec-rails", "~> 2.12"
|
30
31
|
gem.add_development_dependency "capybara-firebug", "~> 1.1"
|
31
32
|
gem.add_development_dependency "coffee-script"
|
32
33
|
gem.add_development_dependency "ejs"
|
33
34
|
gem.add_development_dependency "tzinfo"
|
35
|
+
gem.add_development_dependency "poltergeist"
|
34
36
|
end
|
@@ -6,8 +6,8 @@ Dummy::Application.configure do
|
|
6
6
|
# since you don't have to restart the web server when you make code changes.
|
7
7
|
config.cache_classes = false
|
8
8
|
|
9
|
-
#
|
10
|
-
config.
|
9
|
+
# Do not eager load in development.
|
10
|
+
config.eager_load = false
|
11
11
|
|
12
12
|
# Show full error reports and disable caching
|
13
13
|
config.consider_all_requests_local = true
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Your secret key for verifying the integrity of signed cookies.
|
4
|
+
# If you change this key, all old signed cookies will become invalid!
|
5
|
+
|
6
|
+
# Make sure the secret is at least 30 characters and all random,
|
7
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
8
|
+
# You can use `rake secret` to generate a secure secret key.
|
9
|
+
|
10
|
+
# Make sure your secret_key_base is kept private
|
11
|
+
# if you're sharing your code publicly.
|
12
|
+
Dummy::Application.config.secret_key_base = '58633e8901c06c9cd6484fcc4fee564f1329e8b5c44c93101479868598ce73ffb1438ee6a0f819ab719c4724683434f7d78285ba0badd06440d64bb6417f84dc'
|
data/spec/error_handling_spec.rb
CHANGED
data/spec/runner_spec.rb
CHANGED
@@ -26,99 +26,115 @@ describe Konacha::Runner do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
'title' => 'failure',
|
35
|
-
'fullTitle' => 'failure',
|
36
|
-
'path' => 'failing_spec.js'
|
37
|
-
}}
|
29
|
+
shared_examples_for "Konacha::Runner" do |driver|
|
30
|
+
before do
|
31
|
+
Konacha.configure do |config|
|
32
|
+
config.driver = driver
|
33
|
+
end
|
38
34
|
end
|
39
35
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
'
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
36
|
+
describe "#run" do
|
37
|
+
let(:suite) do
|
38
|
+
{'event' => 'suite',
|
39
|
+
'type' => 'suite',
|
40
|
+
'data' => {
|
41
|
+
'title' => 'failure',
|
42
|
+
'fullTitle' => 'failure',
|
43
|
+
'path' => 'failing_spec.js'
|
44
|
+
}}
|
45
|
+
end
|
49
46
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
47
|
+
let(:suite_end) do
|
48
|
+
{'event' => 'suite end',
|
49
|
+
'type' => 'suite',
|
50
|
+
'data' => {
|
51
|
+
'title' => 'failure',
|
52
|
+
'fullTitle' => 'failure',
|
53
|
+
'path' => 'failing_spec.js'
|
54
|
+
}}
|
55
|
+
end
|
59
56
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
'error' => {'message' => 'expected 4 to equal 5', 'name' => 'AssertionError'}}}
|
70
|
-
end
|
57
|
+
let(:test) do
|
58
|
+
{'event' => 'test',
|
59
|
+
'type' => 'test',
|
60
|
+
'data' => {
|
61
|
+
'title' => 'fails',
|
62
|
+
'fullTitle' => 'failure fails',
|
63
|
+
'parentFullTitle' => 'failure',
|
64
|
+
'path' => 'failing_spec.js'}}
|
65
|
+
end
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
67
|
+
let(:failure) do
|
68
|
+
{'event' => 'fail',
|
69
|
+
'type' => 'test',
|
70
|
+
'data' => {
|
71
|
+
'title' => 'fails',
|
72
|
+
'fullTitle' => 'failure fails',
|
73
|
+
'parentFullTitle' => 'failure',
|
74
|
+
'status' => 'failed',
|
75
|
+
'path' => 'failing_spec.js',
|
76
|
+
'error' => {'message' => 'expected 4 to equal 5', 'name' => 'AssertionError'}}}
|
77
|
+
end
|
83
78
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
79
|
+
let(:error) do
|
80
|
+
{'event' => 'fail',
|
81
|
+
'type' => 'test',
|
82
|
+
'data' => {
|
83
|
+
'title' => 'errors',
|
84
|
+
'fullTitle' => 'failure errors',
|
85
|
+
'parentFullTitle' => 'failure',
|
86
|
+
'status' => 'failed',
|
87
|
+
'path' => 'failing_spec.js',
|
88
|
+
'error' => {'message' => 'this one errors out', 'name' => 'Error'}}}
|
89
|
+
end
|
95
90
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
91
|
+
let(:pass) do
|
92
|
+
{'event' => 'pass',
|
93
|
+
'type' => 'test',
|
94
|
+
'data' => {
|
95
|
+
'title' => 'is empty',
|
96
|
+
'fullTitle' => 'the body#konacha element is empty',
|
97
|
+
'parentFullTitle' => 'the body#konacha element',
|
98
|
+
'status' => 'passed',
|
99
|
+
'path' => 'body_spec.js.coffee',
|
100
|
+
'duration' => anything}}
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:pending) do
|
104
|
+
{'event' => 'pending',
|
105
|
+
'type' => 'test',
|
106
|
+
'data' => {
|
107
|
+
'title' => 'is pending',
|
108
|
+
'fullTitle' => 'pending test is pending',
|
109
|
+
'parentFullTitle' => 'pending test',
|
110
|
+
'path' => 'pending_spec.js',
|
111
|
+
'status' => 'pending'}}
|
112
|
+
end
|
113
|
+
|
114
|
+
let(:start) { {'event' => 'start', 'testCount' => kind_of(Integer), 'data' => {} } }
|
115
|
+
let(:end_event) { {'event' => 'end', 'data' => {} } }
|
106
116
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
subject.reporter.should_receive(:process_mocha_event).any_number_of_times
|
121
|
-
subject.run
|
117
|
+
it "passes along the right events" do
|
118
|
+
subject.reporter.should_receive(:process_mocha_event).with(start)
|
119
|
+
subject.reporter.should_receive(:process_mocha_event).with(suite)
|
120
|
+
subject.reporter.should_receive(:process_mocha_event).with(suite_end)
|
121
|
+
subject.reporter.should_receive(:process_mocha_event).with(test)
|
122
|
+
subject.reporter.should_receive(:process_mocha_event).with(failure)
|
123
|
+
subject.reporter.should_receive(:process_mocha_event).with(error)
|
124
|
+
subject.reporter.should_receive(:process_mocha_event).with(pass)
|
125
|
+
subject.reporter.should_receive(:process_mocha_event).with(pending)
|
126
|
+
subject.reporter.should_receive(:process_mocha_event).with(end_event)
|
127
|
+
subject.reporter.should_receive(:process_mocha_event).any_number_of_times
|
128
|
+
subject.run
|
129
|
+
end
|
122
130
|
end
|
123
131
|
end
|
132
|
+
|
133
|
+
describe "with selenium" do
|
134
|
+
it_behaves_like "Konacha::Runner", :selenium
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "with poltergeist" do
|
138
|
+
it_behaves_like "Konacha::Runner", :poltergeist
|
139
|
+
end
|
124
140
|
end
|
data/spec/server_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -13,6 +13,7 @@ require "ejs"
|
|
13
13
|
|
14
14
|
require "capybara/rails"
|
15
15
|
require "capybara/firebug"
|
16
|
+
require "capybara/poltergeist"
|
16
17
|
|
17
18
|
Capybara.configure do |config|
|
18
19
|
config.default_selector = :css
|
@@ -21,7 +22,7 @@ Capybara.configure do |config|
|
|
21
22
|
end
|
22
23
|
|
23
24
|
module Konacha
|
24
|
-
module
|
25
|
+
module FeatureSpec
|
25
26
|
def app
|
26
27
|
# Override the RSpec default of `Rails.application`.
|
27
28
|
Konacha.application
|
@@ -30,7 +31,7 @@ module Konacha
|
|
30
31
|
end
|
31
32
|
|
32
33
|
RSpec.configure do |config|
|
33
|
-
config.include Konacha::
|
34
|
+
config.include Konacha::FeatureSpec, :type => :feature
|
34
35
|
end
|
35
36
|
|
36
37
|
Konacha.configure do |config|
|
@@ -12,19 +12,20 @@ describe "konacha/specs/iframe" do
|
|
12
12
|
it "renders a script tag for @spec" do
|
13
13
|
assign(:spec, spec_double("a_spec"))
|
14
14
|
|
15
|
-
|
15
|
+
view.stub(:javascript_include_tag)
|
16
|
+
view.should_receive(:javascript_include_tag).with("a_spec")
|
16
17
|
|
17
|
-
|
18
|
+
render
|
18
19
|
end
|
19
20
|
|
20
21
|
it "renders the stylesheets" do
|
21
22
|
assign(:spec, spec_double("a_spec"))
|
22
23
|
assign(:stylesheets, %w(foo bar))
|
23
24
|
|
24
|
-
|
25
|
+
view.should_receive(:stylesheet_link_tag).with("foo", :debug => false)
|
26
|
+
view.should_receive(:stylesheet_link_tag).with("bar", :debug => false)
|
25
27
|
|
26
|
-
|
27
|
-
rendered.should have_selector("link[href='/assets/bar.css']")
|
28
|
+
render
|
28
29
|
end
|
29
30
|
|
30
31
|
it "includes a path data attribute" do
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "konacha/specs/parent" do
|
4
|
+
def spec_double(asset_name)
|
5
|
+
double("spec called '#{asset_name}'", :asset_name => asset_name, :path => "#{asset_name}.js")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "renders an iframe tag for a spec" do
|
9
|
+
# https://github.com/rails/rails/issues/4364
|
10
|
+
# https://github.com/rspec/rspec-rails/pull/539
|
11
|
+
view.singleton_class.send(:include, Konacha::Engine.routes.url_helpers)
|
12
|
+
|
13
|
+
spec = spec_double("a_spec")
|
14
|
+
assign(:specs, [spec])
|
15
|
+
|
16
|
+
render
|
17
|
+
|
18
|
+
Capybara.string(rendered).find("iframe")[:src].should == "/iframe/a_spec"
|
19
|
+
end
|
20
|
+
end
|
@@ -74,7 +74,7 @@
|
|
74
74
|
* Chai version
|
75
75
|
*/
|
76
76
|
|
77
|
-
exports.version = '1.
|
77
|
+
exports.version = '1.4.2';
|
78
78
|
|
79
79
|
/*!
|
80
80
|
* Primary `Assertion` prototype
|
@@ -86,7 +86,7 @@
|
|
86
86
|
* Assertion Error
|
87
87
|
*/
|
88
88
|
|
89
|
-
exports.AssertionError = require('./chai/
|
89
|
+
exports.AssertionError = require('./chai/error');
|
90
90
|
|
91
91
|
/*!
|
92
92
|
* Utils for plugins (not exported)
|
@@ -155,7 +155,7 @@
|
|
155
155
|
* Module dependencies.
|
156
156
|
*/
|
157
157
|
|
158
|
-
var AssertionError = require('./
|
158
|
+
var AssertionError = require('./error')
|
159
159
|
, util = require('./utils')
|
160
160
|
, flag = util.flag;
|
161
161
|
|
@@ -228,8 +228,9 @@
|
|
228
228
|
* @api private
|
229
229
|
*/
|
230
230
|
|
231
|
-
Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual) {
|
231
|
+
Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
|
232
232
|
var ok = util.test(this, arguments);
|
233
|
+
if (true !== showDiff) showDiff = false;
|
233
234
|
|
234
235
|
if (!ok) {
|
235
236
|
var msg = util.getMessage(this, arguments)
|
@@ -239,6 +240,7 @@
|
|
239
240
|
, actual: actual
|
240
241
|
, expected: expected
|
241
242
|
, stackStartFunction: (Assertion.includeStack) ? this.assert : flag(this, 'ssfi')
|
243
|
+
, showDiff: showDiff
|
242
244
|
});
|
243
245
|
}
|
244
246
|
};
|
@@ -262,38 +264,6 @@
|
|
262
264
|
|
263
265
|
}); // module: chai/assertion.js
|
264
266
|
|
265
|
-
require.register("chai/browser/error.js", function(module, exports, require){
|
266
|
-
/*!
|
267
|
-
* chai
|
268
|
-
* Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
|
269
|
-
* MIT Licensed
|
270
|
-
*/
|
271
|
-
|
272
|
-
module.exports = AssertionError;
|
273
|
-
|
274
|
-
function AssertionError (options) {
|
275
|
-
options = options || {};
|
276
|
-
this.message = options.message;
|
277
|
-
this.actual = options.actual;
|
278
|
-
this.expected = options.expected;
|
279
|
-
this.operator = options.operator;
|
280
|
-
|
281
|
-
if (options.stackStartFunction && Error.captureStackTrace) {
|
282
|
-
var stackStartFunction = options.stackStartFunction;
|
283
|
-
Error.captureStackTrace(this, stackStartFunction);
|
284
|
-
}
|
285
|
-
}
|
286
|
-
|
287
|
-
AssertionError.prototype = Object.create(Error.prototype);
|
288
|
-
AssertionError.prototype.name = 'AssertionError';
|
289
|
-
AssertionError.prototype.constructor = AssertionError;
|
290
|
-
|
291
|
-
AssertionError.prototype.toString = function() {
|
292
|
-
return this.message;
|
293
|
-
};
|
294
|
-
|
295
|
-
}); // module: chai/browser/error.js
|
296
|
-
|
297
267
|
require.register("chai/core/assertions.js", function(module, exports, require){
|
298
268
|
/*!
|
299
269
|
* chai
|
@@ -325,6 +295,8 @@
|
|
325
295
|
* - and
|
326
296
|
* - have
|
327
297
|
* - with
|
298
|
+
* - at
|
299
|
+
* - of
|
328
300
|
*
|
329
301
|
* @name language chains
|
330
302
|
* @api public
|
@@ -332,7 +304,8 @@
|
|
332
304
|
|
333
305
|
[ 'to', 'be', 'been'
|
334
306
|
, 'is', 'and', 'have'
|
335
|
-
, 'with', 'that'
|
307
|
+
, 'with', 'that', 'at'
|
308
|
+
, 'of' ].forEach(function (chain) {
|
336
309
|
Assertion.addProperty(chain, function () {
|
337
310
|
return this;
|
338
311
|
});
|
@@ -671,6 +644,8 @@
|
|
671
644
|
, 'expected #{this} to equal #{exp}'
|
672
645
|
, 'expected #{this} to not equal #{exp}'
|
673
646
|
, val
|
647
|
+
, this._obj
|
648
|
+
, true
|
674
649
|
);
|
675
650
|
}
|
676
651
|
}
|
@@ -700,6 +675,8 @@
|
|
700
675
|
, 'expected #{this} to deeply equal #{exp}'
|
701
676
|
, 'expected #{this} to not deeply equal #{exp}'
|
702
677
|
, obj
|
678
|
+
, this._obj
|
679
|
+
, true
|
703
680
|
);
|
704
681
|
});
|
705
682
|
|
@@ -743,7 +720,7 @@
|
|
743
720
|
this.assert(
|
744
721
|
obj > n
|
745
722
|
, 'expected #{this} to be above ' + n
|
746
|
-
, 'expected #{this} to be
|
723
|
+
, 'expected #{this} to be at most ' + n
|
747
724
|
);
|
748
725
|
}
|
749
726
|
}
|
@@ -752,6 +729,53 @@
|
|
752
729
|
Assertion.addMethod('gt', assertAbove);
|
753
730
|
Assertion.addMethod('greaterThan', assertAbove);
|
754
731
|
|
732
|
+
/**
|
733
|
+
* ### .least(value)
|
734
|
+
*
|
735
|
+
* Asserts that the target is greater than or equal to `value`.
|
736
|
+
*
|
737
|
+
* expect(10).to.be.at.least(10);
|
738
|
+
*
|
739
|
+
* Can also be used in conjunction with `length` to
|
740
|
+
* assert a minimum length. The benefit being a
|
741
|
+
* more informative error message than if the length
|
742
|
+
* was supplied directly.
|
743
|
+
*
|
744
|
+
* expect('foo').to.have.length.of.at.least(2);
|
745
|
+
* expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
|
746
|
+
*
|
747
|
+
* @name least
|
748
|
+
* @alias gte
|
749
|
+
* @param {Number} value
|
750
|
+
* @param {String} message _optional_
|
751
|
+
* @api public
|
752
|
+
*/
|
753
|
+
|
754
|
+
function assertLeast (n, msg) {
|
755
|
+
if (msg) flag(this, 'message', msg);
|
756
|
+
var obj = flag(this, 'object');
|
757
|
+
if (flag(this, 'doLength')) {
|
758
|
+
new Assertion(obj, msg).to.have.property('length');
|
759
|
+
var len = obj.length;
|
760
|
+
this.assert(
|
761
|
+
len >= n
|
762
|
+
, 'expected #{this} to have a length at least #{exp} but got #{act}'
|
763
|
+
, 'expected #{this} to not have a length below #{exp}'
|
764
|
+
, n
|
765
|
+
, len
|
766
|
+
);
|
767
|
+
} else {
|
768
|
+
this.assert(
|
769
|
+
obj >= n
|
770
|
+
, 'expected #{this} to be at least ' + n
|
771
|
+
, 'expected #{this} to be below ' + n
|
772
|
+
);
|
773
|
+
}
|
774
|
+
}
|
775
|
+
|
776
|
+
Assertion.addMethod('least', assertLeast);
|
777
|
+
Assertion.addMethod('gte', assertLeast);
|
778
|
+
|
755
779
|
/**
|
756
780
|
* ### .below(value)
|
757
781
|
*
|
@@ -792,7 +816,7 @@
|
|
792
816
|
this.assert(
|
793
817
|
obj < n
|
794
818
|
, 'expected #{this} to be below ' + n
|
795
|
-
, 'expected #{this} to be
|
819
|
+
, 'expected #{this} to be at least ' + n
|
796
820
|
);
|
797
821
|
}
|
798
822
|
}
|
@@ -801,6 +825,53 @@
|
|
801
825
|
Assertion.addMethod('lt', assertBelow);
|
802
826
|
Assertion.addMethod('lessThan', assertBelow);
|
803
827
|
|
828
|
+
/**
|
829
|
+
* ### .most(value)
|
830
|
+
*
|
831
|
+
* Asserts that the target is less than or equal to `value`.
|
832
|
+
*
|
833
|
+
* expect(5).to.be.at.most(5);
|
834
|
+
*
|
835
|
+
* Can also be used in conjunction with `length` to
|
836
|
+
* assert a maximum length. The benefit being a
|
837
|
+
* more informative error message than if the length
|
838
|
+
* was supplied directly.
|
839
|
+
*
|
840
|
+
* expect('foo').to.have.length.of.at.most(4);
|
841
|
+
* expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
|
842
|
+
*
|
843
|
+
* @name most
|
844
|
+
* @alias lte
|
845
|
+
* @param {Number} value
|
846
|
+
* @param {String} message _optional_
|
847
|
+
* @api public
|
848
|
+
*/
|
849
|
+
|
850
|
+
function assertMost (n, msg) {
|
851
|
+
if (msg) flag(this, 'message', msg);
|
852
|
+
var obj = flag(this, 'object');
|
853
|
+
if (flag(this, 'doLength')) {
|
854
|
+
new Assertion(obj, msg).to.have.property('length');
|
855
|
+
var len = obj.length;
|
856
|
+
this.assert(
|
857
|
+
len <= n
|
858
|
+
, 'expected #{this} to have a length at most #{exp} but got #{act}'
|
859
|
+
, 'expected #{this} to not have a length above #{exp}'
|
860
|
+
, n
|
861
|
+
, len
|
862
|
+
);
|
863
|
+
} else {
|
864
|
+
this.assert(
|
865
|
+
obj <= n
|
866
|
+
, 'expected #{this} to be at most ' + n
|
867
|
+
, 'expected #{this} to be above ' + n
|
868
|
+
);
|
869
|
+
}
|
870
|
+
}
|
871
|
+
|
872
|
+
Assertion.addMethod('most', assertMost);
|
873
|
+
Assertion.addMethod('lte', assertMost);
|
874
|
+
|
804
875
|
/**
|
805
876
|
* ### .within(start, finish)
|
806
877
|
*
|
@@ -1392,6 +1463,70 @@
|
|
1392
1463
|
|
1393
1464
|
}); // module: chai/core/assertions.js
|
1394
1465
|
|
1466
|
+
require.register("chai/error.js", function(module, exports, require){
|
1467
|
+
/*!
|
1468
|
+
* chai
|
1469
|
+
* Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com>
|
1470
|
+
* MIT Licensed
|
1471
|
+
*/
|
1472
|
+
|
1473
|
+
/*!
|
1474
|
+
* Main export
|
1475
|
+
*/
|
1476
|
+
|
1477
|
+
module.exports = AssertionError;
|
1478
|
+
|
1479
|
+
/**
|
1480
|
+
* # AssertionError (constructor)
|
1481
|
+
*
|
1482
|
+
* Create a new assertion error based on the Javascript
|
1483
|
+
* `Error` prototype.
|
1484
|
+
*
|
1485
|
+
* **Options**
|
1486
|
+
* - message
|
1487
|
+
* - actual
|
1488
|
+
* - expected
|
1489
|
+
* - operator
|
1490
|
+
* - startStackFunction
|
1491
|
+
*
|
1492
|
+
* @param {Object} options
|
1493
|
+
* @api public
|
1494
|
+
*/
|
1495
|
+
|
1496
|
+
function AssertionError (options) {
|
1497
|
+
options = options || {};
|
1498
|
+
this.message = options.message;
|
1499
|
+
this.actual = options.actual;
|
1500
|
+
this.expected = options.expected;
|
1501
|
+
this.operator = options.operator;
|
1502
|
+
this.showDiff = options.showDiff;
|
1503
|
+
|
1504
|
+
if (options.stackStartFunction && Error.captureStackTrace) {
|
1505
|
+
var stackStartFunction = options.stackStartFunction;
|
1506
|
+
Error.captureStackTrace(this, stackStartFunction);
|
1507
|
+
}
|
1508
|
+
}
|
1509
|
+
|
1510
|
+
/*!
|
1511
|
+
* Inherit from Error
|
1512
|
+
*/
|
1513
|
+
|
1514
|
+
AssertionError.prototype = Object.create(Error.prototype);
|
1515
|
+
AssertionError.prototype.name = 'AssertionError';
|
1516
|
+
AssertionError.prototype.constructor = AssertionError;
|
1517
|
+
|
1518
|
+
/**
|
1519
|
+
* # toString()
|
1520
|
+
*
|
1521
|
+
* Override default to string method
|
1522
|
+
*/
|
1523
|
+
|
1524
|
+
AssertionError.prototype.toString = function() {
|
1525
|
+
return this.message;
|
1526
|
+
};
|
1527
|
+
|
1528
|
+
}); // module: chai/error.js
|
1529
|
+
|
1395
1530
|
require.register("chai/interface/assert.js", function(module, exports, require){
|
1396
1531
|
/*!
|
1397
1532
|
* chai
|
@@ -2255,13 +2390,17 @@
|
|
2255
2390
|
};
|
2256
2391
|
|
2257
2392
|
/**
|
2258
|
-
* ### .throws(function, [constructor/regexp], [message])
|
2393
|
+
* ### .throws(function, [constructor/string/regexp], [string/regexp], [message])
|
2259
2394
|
*
|
2260
2395
|
* Asserts that `function` will throw an error that is an instance of
|
2261
2396
|
* `constructor`, or alternately that it will throw an error with message
|
2262
2397
|
* matching `regexp`.
|
2263
2398
|
*
|
2399
|
+
* assert.throw(fn, 'function throws a reference error');
|
2400
|
+
* assert.throw(fn, /function throws a reference error/);
|
2401
|
+
* assert.throw(fn, ReferenceError);
|
2264
2402
|
* assert.throw(fn, ReferenceError, 'function throws a reference error');
|
2403
|
+
* assert.throw(fn, ReferenceError, /function throws a reference error/);
|
2265
2404
|
*
|
2266
2405
|
* @name throws
|
2267
2406
|
* @alias throw
|
@@ -2274,13 +2413,13 @@
|
|
2274
2413
|
* @api public
|
2275
2414
|
*/
|
2276
2415
|
|
2277
|
-
assert.Throw = function (fn,
|
2278
|
-
if ('string' === typeof
|
2279
|
-
|
2280
|
-
|
2416
|
+
assert.Throw = function (fn, errt, errs, msg) {
|
2417
|
+
if ('string' === typeof errt || errt instanceof RegExp) {
|
2418
|
+
errs = errt;
|
2419
|
+
errt = null;
|
2281
2420
|
}
|
2282
2421
|
|
2283
|
-
new Assertion(fn, msg).to.Throw(
|
2422
|
+
new Assertion(fn, msg).to.Throw(errt, errs);
|
2284
2423
|
};
|
2285
2424
|
|
2286
2425
|
/**
|
@@ -2649,7 +2788,7 @@
|
|
2649
2788
|
};
|
2650
2789
|
}
|
2651
2790
|
|
2652
|
-
function _deepEqual(actual, expected) {
|
2791
|
+
function _deepEqual(actual, expected, memos) {
|
2653
2792
|
|
2654
2793
|
// 7.1. All identical values are equivalent, as determined by ===.
|
2655
2794
|
if (actual === expected) {
|
@@ -2681,7 +2820,7 @@
|
|
2681
2820
|
// corresponding key, and an identical 'prototype' property. Note: this
|
2682
2821
|
// accounts for both named and indexed properties on Arrays.
|
2683
2822
|
} else {
|
2684
|
-
return objEquiv(actual, expected);
|
2823
|
+
return objEquiv(actual, expected, memos);
|
2685
2824
|
}
|
2686
2825
|
}
|
2687
2826
|
|
@@ -2693,11 +2832,25 @@
|
|
2693
2832
|
return Object.prototype.toString.call(object) == '[object Arguments]';
|
2694
2833
|
}
|
2695
2834
|
|
2696
|
-
function objEquiv(a, b) {
|
2835
|
+
function objEquiv(a, b, memos) {
|
2697
2836
|
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
2698
2837
|
return false;
|
2838
|
+
|
2699
2839
|
// an identical 'prototype' property.
|
2700
2840
|
if (a.prototype !== b.prototype) return false;
|
2841
|
+
|
2842
|
+
// check if we have already compared a and b
|
2843
|
+
var i;
|
2844
|
+
if (memos) {
|
2845
|
+
for(i = 0; i < memos.length; i++) {
|
2846
|
+
if ((memos[i][0] === a && memos[i][1] === b) ||
|
2847
|
+
(memos[i][0] === b && memos[i][1] === a))
|
2848
|
+
return true;
|
2849
|
+
}
|
2850
|
+
} else {
|
2851
|
+
memos = [];
|
2852
|
+
}
|
2853
|
+
|
2701
2854
|
//~~~I've managed to break Object.keys through screwy arguments passing.
|
2702
2855
|
// Converting to array solves the problem.
|
2703
2856
|
if (isArguments(a)) {
|
@@ -2706,19 +2859,21 @@
|
|
2706
2859
|
}
|
2707
2860
|
a = pSlice.call(a);
|
2708
2861
|
b = pSlice.call(b);
|
2709
|
-
return _deepEqual(a, b);
|
2862
|
+
return _deepEqual(a, b, memos);
|
2710
2863
|
}
|
2711
2864
|
try {
|
2712
2865
|
var ka = Object.keys(a),
|
2713
2866
|
kb = Object.keys(b),
|
2714
|
-
key
|
2867
|
+
key;
|
2715
2868
|
} catch (e) {//happens when one is a string literal and the other isn't
|
2716
2869
|
return false;
|
2717
2870
|
}
|
2871
|
+
|
2718
2872
|
// having the same number of owned properties (keys incorporates
|
2719
2873
|
// hasOwnProperty)
|
2720
2874
|
if (ka.length != kb.length)
|
2721
2875
|
return false;
|
2876
|
+
|
2722
2877
|
//the same set of keys (although not necessarily the same order),
|
2723
2878
|
ka.sort();
|
2724
2879
|
kb.sort();
|
@@ -2727,12 +2882,17 @@
|
|
2727
2882
|
if (ka[i] != kb[i])
|
2728
2883
|
return false;
|
2729
2884
|
}
|
2885
|
+
|
2886
|
+
// remember objects we have compared to guard against circular references
|
2887
|
+
memos.push([ a, b ]);
|
2888
|
+
|
2730
2889
|
//equivalent values for every corresponding key, and
|
2731
2890
|
//~~~possibly expensive deep test
|
2732
2891
|
for (i = ka.length - 1; i >= 0; i--) {
|
2733
2892
|
key = ka[i];
|
2734
|
-
if (!_deepEqual(a[key], b[key])) return false;
|
2893
|
+
if (!_deepEqual(a[key], b[key], memos)) return false;
|
2735
2894
|
}
|
2895
|
+
|
2736
2896
|
return true;
|
2737
2897
|
}
|
2738
2898
|
|
@@ -2792,7 +2952,7 @@
|
|
2792
2952
|
|
2793
2953
|
module.exports = function (obj, args) {
|
2794
2954
|
var actual = args[4];
|
2795
|
-
return 'undefined' !== actual ? actual : obj._obj;
|
2955
|
+
return 'undefined' !== typeof actual ? actual : obj._obj;
|
2796
2956
|
};
|
2797
2957
|
|
2798
2958
|
}); // module: chai/utils/getActual.js
|