konacha 2.1.0 → 2.2.0
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/.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
|