decko 0.3.3 → 0.3.4

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/decko/generators/decko/templates/Gemfile +1 -0
  3. metadata +5 -109
  4. data/.rspec +0 -4
  5. data/Guardfile +0 -32
  6. data/decko.gemspec +0 -42
  7. data/features/attach.feature +0 -85
  8. data/features/autonaming.feature +0 -19
  9. data/features/conflict.feature +0 -41
  10. data/features/follow.feature +0 -64
  11. data/features/history.feature +0 -27
  12. data/features/layouts.feature +0 -25
  13. data/features/navbox.feature +0 -34
  14. data/features/notifications.feature +0 -33
  15. data/features/paging.feature +0 -34
  16. data/features/pointer_inputs.feature +0 -81
  17. data/features/presetting_content.feature +0 -13
  18. data/features/reference.feature +0 -26
  19. data/features/reset_password.feature +0 -35
  20. data/features/rules.feature +0 -45
  21. data/features/setup.feature +0 -32
  22. data/features/signup.feature +0 -61
  23. data/features/step_definitions/decko_steps.rb +0 -532
  24. data/features/step_definitions/email_steps.rb +0 -216
  25. data/features/step_definitions/history_steps.rb +0 -5
  26. data/features/step_definitions/web_steps.rb +0 -155
  27. data/features/step_definitions/window_steps.rb +0 -27
  28. data/features/structure.feature +0 -41
  29. data/features/support/debugger.rb +0 -44
  30. data/features/support/delayed_job.rb +0 -20
  31. data/features/support/env.rb +0 -115
  32. data/features/support/file.txt +0 -1
  33. data/features/support/image.png +0 -0
  34. data/features/support/image2.jpg +0 -0
  35. data/features/support/paths.rb +0 -63
  36. data/features/support/scopes.rb +0 -34
  37. data/features/support/wagn_env.rb +0 -11
  38. data/features/table_of_contents.feature +0 -36
  39. data/features/toolbar.feature +0 -29
  40. data/features/update_includers.feature +0 -75
  41. data/lib/decko/tasks/.gitkeep +0 -0
  42. data/spec/controllers/card_controller_spec.rb +0 -407
  43. data/spec/controllers/location_spec.rb +0 -25
  44. data/spec/javascripts/helpers/.gitkeep +0 -0
  45. data/spec/javascripts/helpers/jasmine-jquery.js +0 -812
  46. data/spec/javascripts/support/jasmine.yml.erb +0 -79
  47. data/spec/javascripts/support/jasmine_config.rb +0 -21
  48. data/spec/javascripts/support/jasmine_runner.rb +0 -21
  49. data/spec/javascripts/wagn_spec.coffee +0 -42
  50. data/test/1.10.0-data-dump.sql +0 -359
  51. data/test/performance/card_create_test.rb +0 -21
  52. data/test/performance/fetch_test.rb +0 -9
  53. data/test/performance/homepage_test.rb +0 -9
  54. data/test/performance/render_test.rb +0 -10
  55. data/test/script/run_engine_deck.sh +0 -47
  56. data/test/script/run_mig.sh +0 -29
  57. data/test/test_helper.rb +0 -125
File without changes
@@ -1,407 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
- RSpec.describe CardController, type: :controller do
4
- routes { Decko::Engine.routes }
5
-
6
- include Capybara::DSL
7
- describe "- route generation" do
8
- def card_route_to opts={}
9
- route_to opts.merge(controller: "card")
10
- end
11
-
12
- it "recognizes type" do
13
- # all_routes = Rails.application.routes.routes
14
- # require 'rails/application/route_inspector'
15
- # warn "rountes#{ENV['CONTROLLER']}:\n" + Rails::Application::RouteInspector.new.format(all_routes, ENV['CONTROLLER'])* "\n"
16
-
17
- expect(get: "/new/Phrase")
18
- .to card_route_to(action: "read", type: "Phrase", view: "new")
19
- end
20
-
21
- it "recognizes .rss on /recent" do
22
- expect(get: "/recent.rss")
23
- .to card_route_to(action: "read", id: ":recent", format: "rss")
24
- end
25
-
26
- it "handles RESTful posts" do
27
- expect(put: "/mycard").to card_route_to(action: "update", id: "mycard")
28
- expect(put: "/").to card_route_to(action: "update")
29
- end
30
-
31
- it "handle asset requests" do
32
- expect(get: "/asset/application.js")
33
- .to card_route_to(action: "asset", id: "application", format: "js")
34
- end
35
-
36
- ["/wagn", ""].each do |prefix|
37
- describe "routes prefixed with '#{prefix}'" do
38
- it "recognizes .rss format" do
39
- expect(get: "#{prefix}/*recent.rss")
40
- .to card_route_to(action: "read", id: "*recent", format: "rss")
41
- end
42
-
43
- it "recognizes .xml format" do
44
- expect(get: "#{prefix}/*recent.xml")
45
- .to card_route_to(action: "read", id: "*recent", format: "xml")
46
- end
47
-
48
- it "accepts cards without dots" do
49
- expect(get: "#{prefix}/random")
50
- .to card_route_to(action: "read", id: "random")
51
- end
52
- end
53
- end
54
- end
55
-
56
- describe "#create" do
57
- before do
58
- login_as "joe_user"
59
- end
60
-
61
- # FIXME: several of these tests go all the way to DB,
62
- # which means they're closer to integration than unit tests.
63
- # maybe think about refactoring to use mocks etc. to reduce
64
- # test dependencies.
65
- it "creates cards" do
66
- post :create, params: { card: {
67
- name: "NewCardFoo",
68
- type: "Basic",
69
- content: "Bananas"
70
- } }
71
- assert_response 302
72
- c = Card["NewCardFoo"]
73
- expect(c.type_code).to eq(:basic)
74
- expect(c.content).to eq("Bananas")
75
- end
76
-
77
- it "handles permission denials" do
78
- post :create, params: { card: { name: "LackPerms", type: "Html" } }
79
- assert_response 403
80
- expect(Card["LackPerms"]).to be_nil
81
- end
82
-
83
- # no controller-specific handling. move test elsewhere
84
- it "creates cardtype cards" do
85
- post :create,
86
- xhr: true,
87
- params: { card: {
88
- "content" => "test", type: "Cardtype", name: "Editor"
89
- } }
90
- expect(assigns["card"]).not_to be_nil
91
- assert_response 200
92
- c = Card["Editor"]
93
- expect(c.type_code).to eq(:cardtype)
94
- end
95
-
96
- # no controller-specific handling. move test elsewhere
97
- it "pulls deleted cards from trash" do
98
- @c = Card.create! name: "Problem", content: "boof"
99
- @c.delete!
100
- post :create,
101
- params: { card: {
102
- "name" => "Problem", "type" => "Phrase", "content" => "noof"
103
- } }
104
- assert_response 302
105
- c = Card["Problem"]
106
- expect(c.type_code).to eq(:phrase)
107
- end
108
-
109
- context "multi-create" do
110
- it "catches missing name error" do
111
- post :create, params: { "card" => {
112
- "name" => "",
113
- "type" => "Fruit",
114
- "subcards" => { "+text" => { "content" => "<p>abraid</p>" } }
115
- }, "view" => "open" }
116
- assert_response 422
117
- expect(assigns["card"].errors[:name].first).to eq("can't be blank")
118
- end
119
-
120
- it "creates card with subcards" do
121
- login_as "joe_admin"
122
- $stop = true
123
- post :create, xhr: true, params: { success: "REDIRECT: /", card: {
124
- name: "Gala",
125
- type: "Fruit",
126
- subcards: {
127
- "+kind" => { content: "apple" },
128
- "+color" => { type: "Phrase", content: "red" }
129
- }
130
- } }
131
- assert_response 200
132
- expect(Card["Gala"]).not_to be_nil
133
- expect(Card["Gala+kind"].content).to eq("apple")
134
- expect(Card["Gala+color"].type_name).to eq("Phrase")
135
- end
136
- end
137
-
138
- it "renders errors if create fails" do
139
- post :create, params: { card: { name: "Joe User" } }
140
- assert_response 422
141
- end
142
-
143
- it "redirects to thanks if present" do
144
- login_as "joe_admin"
145
- post :create, xhr: true, params: { success: "REDIRECT: /thank_you",
146
- card: { "name" => "Wombly" } }
147
- assert_response 200
148
- json = JSON.parse response.body
149
- expect(json["redirect"]).to match(/^http.*\/thank_you$/)
150
- end
151
-
152
- it "redirects to card if thanks is blank" do
153
- login_as "joe_admin"
154
- post :create, params: { success: "REDIRECT: _self",
155
- card: { name: "Joe+boop" } }
156
- assert_redirected_to "/Joe+boop"
157
- end
158
-
159
- it "redirects to previous" do
160
- # Fruits (from shared_data) are anon creatable but not readable
161
- login_as :anonymous
162
- post :create, params: { success: "REDIRECT: *previous",
163
- "card" => { "type" => "Fruit", name: "papaya" } },
164
- session: { history: ["/blam"] }
165
- assert_redirected_to "/blam"
166
- end
167
- end
168
-
169
- describe "#read" do
170
- it "works for basic request" do
171
- get :read, params: { id: "Sample_Basic" }
172
- expect(response.body).to match(/\<body[^>]*\>/im)
173
- # have_selector broke in commit 8d3bf2380eb8197410e962304c5e640fced684b9,
174
- # presumably because of a gem (like capybara?)
175
- # response.should have_selector('body')
176
- assert_response :success
177
- expect("Sample Basic").to eq(assigns["card"].name)
178
- end
179
-
180
- it "handles nonexistent card with create permission" do
181
- login_as "joe_user"
182
- get :read, params: { id: "Sample_Fako" }
183
- assert_response :success
184
- end
185
-
186
- it "handles nonexistent card without create permissions" do
187
- get :read, params: { id: "Sample_Fako" }
188
- assert_response 404
189
- end
190
-
191
- it "handles nonexistent card ids" do
192
- get :read, params: { id: "~9999999" }
193
- assert_response 404
194
- end
195
-
196
- it "returns denial when no read permission" do
197
- Card::Auth.as_bot do
198
- Card.create! name: "Strawberry", type: "Fruit" # only admin can read
199
- end
200
- get :read, params: { id: "Strawberry" }
201
- assert_response 403
202
- get :read, params: { id: "Strawberry", format: "txt" }
203
- assert_response 403
204
- end
205
-
206
- context "view = new" do
207
- before do
208
- login_as "joe_user"
209
- end
210
-
211
- it "works on index" do
212
- get :read, params: { view: "new" }
213
- expect(assigns["card"].name).to eq("")
214
- assert_response :success, "response should succeed"
215
- assert_equal Card::BasicID, assigns["card"].type_id,
216
- "@card type should == Basic"
217
- end
218
-
219
- it "new with name" do
220
- post :read, params: { card: { name: "BananaBread" }, view: "new" }
221
- assert_response :success, "response should succeed"
222
- assert_equal "BananaBread", assigns["card"].name,
223
- "@card.name should == BananaBread"
224
- end
225
-
226
- it "new with existing name" do
227
- get :read, params: { card: { name: "A" }, view: "new" }
228
- # really?? how come this is ok?
229
- assert_response :success, "response should succeed"
230
- end
231
-
232
- it "new with type_code" do
233
- post :read, params: { card: { type: "Date" }, view: "new" }
234
- assert_response :success, "response should succeed"
235
- assert_equal Card::DateID, assigns["card"].type_id,
236
- "@card type should == Date"
237
- end
238
-
239
- it "new should work for creatable nonviewable cardtype" do
240
- login_as :anonymous
241
- get :read, params: { type: "Fruit", view: "new" }
242
- assert_response :success
243
- end
244
-
245
- it "uses card params name over id in new cards" do
246
- get :read, params: { id: "my_life",
247
- card: { name: "My LIFE" }, view: "new" }
248
- expect(assigns["card"].name).to eq("My LIFE")
249
- end
250
- end
251
-
252
- context "css" do
253
- before do
254
- @all_style = Card["#{Card[:all].name}+#{Card[:style].name}"]
255
- @all_style.reset_machine_output
256
- end
257
-
258
- it "creates missing machine output file" do
259
- args = { params: { id: @all_style.machine_output_card.name,
260
- format: "css",
261
- explicit_file: true } }
262
- get :read, args
263
- # output_card = Card[:all, :style, :machine_output]
264
- expect(response).to redirect_to(@all_style.machine_output_url)
265
- get :read, args
266
- expect(response.status).to eq(200)
267
- expect(response.content_type).to eq("text/css")
268
- end
269
- end
270
-
271
- context "js" do
272
- let(:all_js) { Card[:all, :script] }
273
-
274
- it "has correct MIME type" do
275
- get :read, params: { id: all_js.machine_output_card.name, format: "js" }
276
- expect(response.status).to eq 200
277
- expect(response.content_type).to eq "text/javascript"
278
- end
279
- end
280
-
281
- context "file" do
282
- before do
283
- Card::Auth.as_bot do
284
- Card.create! name: "mao2", type_code: "image",
285
- image: File.new(File.join(CARD_TEST_SEED_PATH, "mao2.jpg"))
286
- Card.create! name: "mao2+*self+*read", content: "[[Administrator]]"
287
- end
288
- end
289
-
290
- it "handles image with no read permission" do
291
- get :read, params: { id: "mao2" }
292
- assert_response 403, "denies html card view"
293
- get :read, params: { id: "mao2", format: "jpg" }
294
- assert_response 403, "denies simple file view"
295
- end
296
-
297
- it "handles image with read permission" do
298
- login_as "joe_admin"
299
- get :read, params: { id: "mao2" }
300
- assert_response 200
301
- get :read, params: { id: "mao2", format: "jpg" }
302
- assert_response 200
303
- end
304
- end
305
- end
306
-
307
- describe "#asset" do
308
- it "serves file" do
309
- filename = "asset-test.txt"
310
- args = { id: filename, format: "txt", explicit_file: true }
311
- path =
312
- File.join(Decko::Engine.paths["gem-assets"].existent.first, filename)
313
- File.open(path, "w") { |f| f.puts "test" }
314
- args = { filename: filename.to_s }
315
- visit "/assets/#{filename}"
316
- expect(page.body).to eq "test\n"
317
- FileUtils.rm path
318
- end
319
-
320
- it "denies access to other directories" do
321
- get :asset, params: { filename: "/../../Gemfile" }
322
- expect(response.status).to eq(404)
323
- end
324
- end
325
-
326
- describe "unit tests" do
327
- before do
328
- @simple_card = Card["Sample Basic"]
329
- login_as "joe_user"
330
- end
331
-
332
- describe "#update" do
333
- it "works" do
334
- post :update, xhr: true, params: { id: "~#{@simple_card.id}",
335
- card: { content: "brand new content" } }
336
- assert_response :success, "edited card"
337
- assert_equal "brand new content", Card["Sample Basic"].content,
338
- "content was updated"
339
- end
340
-
341
- it "rename without update references should work" do
342
- f = Card.create! type: "Cardtype", name: "Apple"
343
- post :update, xhr: true,
344
- params: {
345
- id: "~#{f.id}",
346
- card: { name: "Newt", update_referers: "false" }
347
- }
348
- expect(assigns["card"].errors.empty?).not_to be_nil
349
- assert_response :success
350
- expect(Card["Newt"]).not_to be_nil
351
- end
352
-
353
- it "update type_code" do
354
- post :update, xhr: true,
355
- params: {
356
- id: "~#{@simple_card.id}",
357
- card: { type: "Date" }
358
- }
359
- assert_response :success, "changed card type"
360
- expect(Card["Sample Basic"].type_code).to eq(:date)
361
- end
362
- end
363
-
364
- describe "delete" do
365
- it "works" do
366
- c = Card.create(name: "Boo", content: "booya")
367
- post :delete, params: { id: "~#{c.id}" }
368
- assert_response :redirect
369
- expect(Card["Boo"]).to eq(nil)
370
- end
371
-
372
- # FIXME: this should probably be files in the spot for a delete test
373
- it "returns to previous undeleted card after deletion" do
374
- t1 = t2 = nil
375
- Card::Auth.as_bot do
376
- t1 = Card.create! name: "Testable1", content: "hello"
377
- t2 = Card.create! name: "Testable1+bandana", content: "world"
378
- end
379
-
380
- get :read, params: { id: t1.key }
381
- get :read, params: { id: t2.key }
382
-
383
- post :delete, params: { id: "~" + t2.id.to_s }
384
- assert_nil Card[t2.name]
385
- assert_redirected_to "/#{t1.name}"
386
-
387
- post :delete, params: { id: "~" + t1.id.to_s }
388
- assert_redirected_to "/"
389
- assert_nil Card[t1.name]
390
- end
391
- end
392
-
393
- it "comments" do
394
- Card::Auth.as_bot do
395
- Card.create name: "basicname+*self+*comment",
396
- content: "[[Anyone Signed In]]"
397
- end
398
- post :update, params: {
399
- id: "basicname",
400
- card: { comment: " and more\n \nsome lines\n\n" }
401
- }
402
- cont = Card["basicname"].content
403
- expect(cont).to match(/basiccontent/)
404
- expect(cont).to match(/some lines/)
405
- end
406
- end
407
- end
@@ -1,25 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
-
3
- # FIXME: - this shouldn't really be with the controller specs
4
-
5
- describe CardController, "location test from old integration" do
6
- routes { Decko::Engine.routes }
7
-
8
- before do
9
- login_as "joe_user"
10
- end
11
-
12
- describe "previous location" do
13
- it "gets updated after viewing" do
14
- get :read, params: { id: "Joe_User" }
15
- assert_equal "/Joe_User", Card::Env.previous_location
16
- end
17
-
18
- it "doesn't link to nonexistent cards" do
19
- get :read, params: { id: "Joe_User" }
20
- get :read, params: { id: "Not_Me" }
21
- get :read, params: { id: "*previous" }
22
- assert_redirected_to "/Joe_User"
23
- end
24
- end
25
- end
File without changes
@@ -1,812 +0,0 @@
1
- /*!
2
- Jasmine-jQuery: a set of jQuery helpers for Jasmine tests.
3
-
4
- Version 2.1.0
5
-
6
- https://github.com/velesin/jasmine-jquery
7
-
8
- Copyright (c) 2010-2014 Wojciech Zawistowski, Travis Jeffery
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining
11
- a copy of this software and associated documentation files (the
12
- "Software"), to deal in the Software without restriction, including
13
- without limitation the rights to use, copy, modify, merge, publish,
14
- distribute, sublicense, and/or sell copies of the Software, and to
15
- permit persons to whom the Software is furnished to do so, subject to
16
- the following conditions:
17
-
18
- The above copyright notice and this permission notice shall be
19
- included in all copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
- */
29
-
30
- +function (window, jasmine, $) { "use strict";
31
-
32
- jasmine.spiedEventsKey = function (selector, eventName) {
33
- return [$(selector).selector, eventName].toString()
34
- }
35
-
36
- jasmine.getFixtures = function () {
37
- return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures()
38
- }
39
-
40
- jasmine.getStyleFixtures = function () {
41
- return jasmine.currentStyleFixtures_ = jasmine.currentStyleFixtures_ || new jasmine.StyleFixtures()
42
- }
43
-
44
- jasmine.Fixtures = function () {
45
- this.containerId = 'jasmine-fixtures'
46
- this.fixturesCache_ = {}
47
- this.fixturesPath = 'spec/javascripts/fixtures'
48
- }
49
-
50
- jasmine.Fixtures.prototype.set = function (html) {
51
- this.cleanUp()
52
- return this.createContainer_(html)
53
- }
54
-
55
- jasmine.Fixtures.prototype.appendSet= function (html) {
56
- this.addToContainer_(html)
57
- }
58
-
59
- jasmine.Fixtures.prototype.preload = function () {
60
- this.read.apply(this, arguments)
61
- }
62
-
63
- jasmine.Fixtures.prototype.load = function () {
64
- this.cleanUp()
65
- this.createContainer_(this.read.apply(this, arguments))
66
- }
67
-
68
- jasmine.Fixtures.prototype.appendLoad = function () {
69
- this.addToContainer_(this.read.apply(this, arguments))
70
- }
71
-
72
- jasmine.Fixtures.prototype.read = function () {
73
- var htmlChunks = []
74
- , fixtureUrls = arguments
75
-
76
- for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
77
- htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]))
78
- }
79
-
80
- return htmlChunks.join('')
81
- }
82
-
83
- jasmine.Fixtures.prototype.clearCache = function () {
84
- this.fixturesCache_ = {}
85
- }
86
-
87
- jasmine.Fixtures.prototype.cleanUp = function () {
88
- $('#' + this.containerId).remove()
89
- }
90
-
91
- jasmine.Fixtures.prototype.sandbox = function (attributes) {
92
- var attributesToSet = attributes || {}
93
- return $('<div id="sandbox" />').attr(attributesToSet)
94
- }
95
-
96
- jasmine.Fixtures.prototype.createContainer_ = function (html) {
97
- var container = $('<div>')
98
- .attr('id', this.containerId)
99
- .html(html)
100
-
101
- $(document.body).append(container)
102
- return container
103
- }
104
-
105
- jasmine.Fixtures.prototype.addToContainer_ = function (html){
106
- var container = $(document.body).find('#'+this.containerId).append(html)
107
-
108
- if (!container.length) {
109
- this.createContainer_(html)
110
- }
111
- }
112
-
113
- jasmine.Fixtures.prototype.getFixtureHtml_ = function (url) {
114
- if (typeof this.fixturesCache_[url] === 'undefined') {
115
- this.loadFixtureIntoCache_(url)
116
- }
117
- return this.fixturesCache_[url]
118
- }
119
-
120
- jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
121
- var self = this
122
- , url = this.makeFixtureUrl_(relativeUrl)
123
- , htmlText = ''
124
- , request = $.ajax({
125
- async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
126
- cache: false,
127
- url: url,
128
- success: function (data, status, $xhr) {
129
- htmlText = $xhr.responseText
130
- }
131
- }).fail(function ($xhr, status, err) {
132
- throw new Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
133
- })
134
-
135
- var scripts = $($.parseHTML(htmlText, true)).find('script[src]') || [];
136
-
137
- scripts.each(function(){
138
- $.ajax({
139
- async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
140
- cache: false,
141
- dataType: 'script',
142
- url: $(this).attr('src'),
143
- success: function (data, status, $xhr) {
144
- htmlText += '<script>' + $xhr.responseText + '</script>'
145
- },
146
- error: function ($xhr, status, err) {
147
- throw new Error('Script could not be loaded: ' + scriptSrc + ' (status: ' + status + ', message: ' + err.message + ')')
148
- }
149
- });
150
- })
151
-
152
- self.fixturesCache_[relativeUrl] = htmlText;
153
- }
154
-
155
- jasmine.Fixtures.prototype.makeFixtureUrl_ = function (relativeUrl){
156
- return this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
157
- }
158
-
159
- jasmine.Fixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) {
160
- return this[methodName].apply(this, passedArguments)
161
- }
162
-
163
-
164
- jasmine.StyleFixtures = function () {
165
- this.fixturesCache_ = {}
166
- this.fixturesNodes_ = []
167
- this.fixturesPath = 'spec/javascripts/fixtures'
168
- }
169
-
170
- jasmine.StyleFixtures.prototype.set = function (css) {
171
- this.cleanUp()
172
- this.createStyle_(css)
173
- }
174
-
175
- jasmine.StyleFixtures.prototype.appendSet = function (css) {
176
- this.createStyle_(css)
177
- }
178
-
179
- jasmine.StyleFixtures.prototype.preload = function () {
180
- this.read_.apply(this, arguments)
181
- }
182
-
183
- jasmine.StyleFixtures.prototype.load = function () {
184
- this.cleanUp()
185
- this.createStyle_(this.read_.apply(this, arguments))
186
- }
187
-
188
- jasmine.StyleFixtures.prototype.appendLoad = function () {
189
- this.createStyle_(this.read_.apply(this, arguments))
190
- }
191
-
192
- jasmine.StyleFixtures.prototype.cleanUp = function () {
193
- while(this.fixturesNodes_.length) {
194
- this.fixturesNodes_.pop().remove()
195
- }
196
- }
197
-
198
- jasmine.StyleFixtures.prototype.createStyle_ = function (html) {
199
- var styleText = $('<div></div>').html(html).text()
200
- , style = $('<style>' + styleText + '</style>')
201
-
202
- this.fixturesNodes_.push(style)
203
- $('head').append(style)
204
- }
205
-
206
- jasmine.StyleFixtures.prototype.clearCache = jasmine.Fixtures.prototype.clearCache
207
- jasmine.StyleFixtures.prototype.read_ = jasmine.Fixtures.prototype.read
208
- jasmine.StyleFixtures.prototype.getFixtureHtml_ = jasmine.Fixtures.prototype.getFixtureHtml_
209
- jasmine.StyleFixtures.prototype.loadFixtureIntoCache_ = jasmine.Fixtures.prototype.loadFixtureIntoCache_
210
- jasmine.StyleFixtures.prototype.makeFixtureUrl_ = jasmine.Fixtures.prototype.makeFixtureUrl_
211
- jasmine.StyleFixtures.prototype.proxyCallTo_ = jasmine.Fixtures.prototype.proxyCallTo_
212
-
213
- jasmine.getJSONFixtures = function () {
214
- return jasmine.currentJSONFixtures_ = jasmine.currentJSONFixtures_ || new jasmine.JSONFixtures()
215
- }
216
-
217
- jasmine.JSONFixtures = function () {
218
- this.fixturesCache_ = {}
219
- this.fixturesPath = 'spec/javascripts/fixtures/json'
220
- }
221
-
222
- jasmine.JSONFixtures.prototype.load = function () {
223
- this.read.apply(this, arguments)
224
- return this.fixturesCache_
225
- }
226
-
227
- jasmine.JSONFixtures.prototype.read = function () {
228
- var fixtureUrls = arguments
229
-
230
- for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
231
- this.getFixtureData_(fixtureUrls[urlIndex])
232
- }
233
-
234
- return this.fixturesCache_
235
- }
236
-
237
- jasmine.JSONFixtures.prototype.clearCache = function () {
238
- this.fixturesCache_ = {}
239
- }
240
-
241
- jasmine.JSONFixtures.prototype.getFixtureData_ = function (url) {
242
- if (!this.fixturesCache_[url]) this.loadFixtureIntoCache_(url)
243
- return this.fixturesCache_[url]
244
- }
245
-
246
- jasmine.JSONFixtures.prototype.loadFixtureIntoCache_ = function (relativeUrl) {
247
- var self = this
248
- , url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl
249
-
250
- $.ajax({
251
- async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
252
- cache: false,
253
- dataType: 'json',
254
- url: url,
255
- success: function (data) {
256
- self.fixturesCache_[relativeUrl] = data
257
- },
258
- error: function ($xhr, status, err) {
259
- throw new Error('JSONFixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + err.message + ')')
260
- }
261
- })
262
- }
263
-
264
- jasmine.JSONFixtures.prototype.proxyCallTo_ = function (methodName, passedArguments) {
265
- return this[methodName].apply(this, passedArguments)
266
- }
267
-
268
- jasmine.jQuery = function () {}
269
-
270
- jasmine.jQuery.browserTagCaseIndependentHtml = function (html) {
271
- return $('<div/>').append(html).html()
272
- }
273
-
274
- jasmine.jQuery.elementToString = function (element) {
275
- return $(element).map(function () { return this.outerHTML; }).toArray().join(', ')
276
- }
277
-
278
- var data = {
279
- spiedEvents: {}
280
- , handlers: []
281
- }
282
-
283
- jasmine.jQuery.events = {
284
- spyOn: function (selector, eventName) {
285
- var handler = function (e) {
286
- data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)] = jasmine.util.argsToArray(arguments)
287
- }
288
-
289
- $(selector).on(eventName, handler)
290
- data.handlers.push(handler)
291
-
292
- return {
293
- selector: selector,
294
- eventName: eventName,
295
- handler: handler,
296
- reset: function (){
297
- delete data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
298
- }
299
- }
300
- },
301
-
302
- args: function (selector, eventName) {
303
- var actualArgs = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
304
-
305
- if (!actualArgs) {
306
- throw "There is no spy for " + eventName + " on " + selector.toString() + ". Make sure to create a spy using spyOnEvent."
307
- }
308
-
309
- return actualArgs
310
- },
311
-
312
- wasTriggered: function (selector, eventName) {
313
- return !!(data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)])
314
- },
315
-
316
- wasTriggeredWith: function (selector, eventName, expectedArgs, util, customEqualityTesters) {
317
- var actualArgs = jasmine.jQuery.events.args(selector, eventName).slice(1)
318
-
319
- if (Object.prototype.toString.call(expectedArgs) !== '[object Array]')
320
- actualArgs = actualArgs[0]
321
-
322
- return util.equals(expectedArgs, actualArgs, customEqualityTesters)
323
- },
324
-
325
- wasPrevented: function (selector, eventName) {
326
- var args = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
327
- , e = args ? args[0] : undefined
328
-
329
- return e && e.isDefaultPrevented()
330
- },
331
-
332
- wasStopped: function (selector, eventName) {
333
- var args = data.spiedEvents[jasmine.spiedEventsKey(selector, eventName)]
334
- , e = args ? args[0] : undefined
335
- return e && e.isPropagationStopped()
336
- },
337
-
338
- cleanUp: function () {
339
- data.spiedEvents = {}
340
- data.handlers = []
341
- }
342
- }
343
-
344
- var hasProperty = function (actualValue, expectedValue) {
345
- if (expectedValue === undefined)
346
- return actualValue !== undefined
347
-
348
- return actualValue === expectedValue
349
- }
350
-
351
- beforeEach(function () {
352
- jasmine.addMatchers({
353
- toHaveClass: function () {
354
- return {
355
- compare: function (actual, className) {
356
- return { pass: $(actual).hasClass(className) }
357
- }
358
- }
359
- },
360
-
361
- toHaveCss: function () {
362
- return {
363
- compare: function (actual, css) {
364
- for (var prop in css){
365
- var value = css[prop]
366
- // see issue #147 on gh
367
- ;if (value === 'auto' && $(actual).get(0).style[prop] === 'auto') continue
368
- if ($(actual).css(prop) !== value) return { pass: false }
369
- }
370
- return { pass: true }
371
- }
372
- }
373
- },
374
-
375
- toBeVisible: function () {
376
- return {
377
- compare: function (actual) {
378
- return { pass: $(actual).is(':visible') }
379
- }
380
- }
381
- },
382
-
383
- toBeHidden: function () {
384
- return {
385
- compare: function (actual) {
386
- return { pass: $(actual).is(':hidden') }
387
- }
388
- }
389
- },
390
-
391
- toBeSelected: function () {
392
- return {
393
- compare: function (actual) {
394
- return { pass: $(actual).is(':selected') }
395
- }
396
- }
397
- },
398
-
399
- toBeChecked: function () {
400
- return {
401
- compare: function (actual) {
402
- return { pass: $(actual).is(':checked') }
403
- }
404
- }
405
- },
406
-
407
- toBeEmpty: function () {
408
- return {
409
- compare: function (actual) {
410
- return { pass: $(actual).is(':empty') }
411
- }
412
- }
413
- },
414
-
415
- toBeInDOM: function () {
416
- return {
417
- compare: function (actual) {
418
- return { pass: $.contains(document.documentElement, $(actual)[0]) }
419
- }
420
- }
421
- },
422
-
423
- toExist: function () {
424
- return {
425
- compare: function (actual) {
426
- return { pass: $(actual).length }
427
- }
428
- }
429
- },
430
-
431
- toHaveLength: function () {
432
- return {
433
- compare: function (actual, length) {
434
- return { pass: $(actual).length === length }
435
- }
436
- }
437
- },
438
-
439
- toHaveAttr: function () {
440
- return {
441
- compare: function (actual, attributeName, expectedAttributeValue) {
442
- return { pass: hasProperty($(actual).attr(attributeName), expectedAttributeValue) }
443
- }
444
- }
445
- },
446
-
447
- toHaveProp: function () {
448
- return {
449
- compare: function (actual, propertyName, expectedPropertyValue) {
450
- return { pass: hasProperty($(actual).prop(propertyName), expectedPropertyValue) }
451
- }
452
- }
453
- },
454
-
455
- toHaveId: function () {
456
- return {
457
- compare: function (actual, id) {
458
- return { pass: $(actual).attr('id') == id }
459
- }
460
- }
461
- },
462
-
463
- toHaveHtml: function () {
464
- return {
465
- compare: function (actual, html) {
466
- return { pass: $(actual).html() == jasmine.jQuery.browserTagCaseIndependentHtml(html) }
467
- }
468
- }
469
- },
470
-
471
- toContainHtml: function () {
472
- return {
473
- compare: function (actual, html) {
474
- var actualHtml = $(actual).html()
475
- , expectedHtml = jasmine.jQuery.browserTagCaseIndependentHtml(html)
476
-
477
- return { pass: (actualHtml.indexOf(expectedHtml) >= 0) }
478
- }
479
- }
480
- },
481
-
482
- toHaveText: function () {
483
- return {
484
- compare: function (actual, text) {
485
- var trimmedText = $.trim($(actual).text())
486
-
487
- if (text && $.isFunction(text.test)) {
488
- return { pass: text.test(trimmedText) }
489
- } else {
490
- return { pass: trimmedText == text }
491
- }
492
- }
493
- }
494
- },
495
-
496
- toContainText: function () {
497
- return {
498
- compare: function (actual, text) {
499
- var trimmedText = $.trim($(actual).text())
500
-
501
- if (text && $.isFunction(text.test)) {
502
- return { pass: text.test(trimmedText) }
503
- } else {
504
- return { pass: trimmedText.indexOf(text) != -1 }
505
- }
506
- }
507
- }
508
- },
509
-
510
- toHaveValue: function () {
511
- return {
512
- compare: function (actual, value) {
513
- return { pass: $(actual).val() === value }
514
- }
515
- }
516
- },
517
-
518
- toHaveData: function () {
519
- return {
520
- compare: function (actual, key, expectedValue) {
521
- return { pass: hasProperty($(actual).data(key), expectedValue) }
522
- }
523
- }
524
- },
525
-
526
- toContainElement: function () {
527
- return {
528
- compare: function (actual, selector) {
529
- if (window.debug) debugger
530
- return { pass: $(actual).find(selector).length }
531
- }
532
- }
533
- },
534
-
535
- toBeMatchedBy: function () {
536
- return {
537
- compare: function (actual, selector) {
538
- return { pass: $(actual).filter(selector).length }
539
- }
540
- }
541
- },
542
-
543
- toBeDisabled: function () {
544
- return {
545
- compare: function (actual, selector) {
546
- return { pass: $(actual).is(':disabled') }
547
- }
548
- }
549
- },
550
-
551
- toBeFocused: function (selector) {
552
- return {
553
- compare: function (actual, selector) {
554
- return { pass: $(actual)[0] === $(actual)[0].ownerDocument.activeElement }
555
- }
556
- }
557
- },
558
-
559
- toHandle: function () {
560
- return {
561
- compare: function (actual, event) {
562
- var events = $._data($(actual).get(0), "events")
563
-
564
- if (!events || !event || typeof event !== "string") {
565
- return { pass: false }
566
- }
567
-
568
- var namespaces = event.split(".")
569
- , eventType = namespaces.shift()
570
- , sortedNamespaces = namespaces.slice(0).sort()
571
- , namespaceRegExp = new RegExp("(^|\\.)" + sortedNamespaces.join("\\.(?:.*\\.)?") + "(\\.|$)")
572
-
573
- if (events[eventType] && namespaces.length) {
574
- for (var i = 0; i < events[eventType].length; i++) {
575
- var namespace = events[eventType][i].namespace
576
-
577
- if (namespaceRegExp.test(namespace))
578
- return { pass: true }
579
- }
580
- } else {
581
- return { pass: (events[eventType] && events[eventType].length > 0) }
582
- }
583
-
584
- return { pass: false }
585
- }
586
- }
587
- },
588
-
589
- toHandleWith: function () {
590
- return {
591
- compare: function (actual, eventName, eventHandler) {
592
- var normalizedEventName = eventName.split('.')[0]
593
- , stack = $._data($(actual).get(0), "events")[normalizedEventName]
594
-
595
- for (var i = 0; i < stack.length; i++) {
596
- if (stack[i].handler == eventHandler) return { pass: true }
597
- }
598
-
599
- return { pass: false }
600
- }
601
- }
602
- },
603
-
604
- toHaveBeenTriggeredOn: function () {
605
- return {
606
- compare: function (actual, selector) {
607
- var result = { pass: jasmine.jQuery.events.wasTriggered(selector, actual) }
608
-
609
- result.message = result.pass ?
610
- "Expected event " + $(actual) + " not to have been triggered on " + selector :
611
- "Expected event " + $(actual) + " to have been triggered on " + selector
612
-
613
- return result;
614
- }
615
- }
616
- },
617
-
618
- toHaveBeenTriggered: function (){
619
- return {
620
- compare: function (actual) {
621
- var eventName = actual.eventName
622
- , selector = actual.selector
623
- , result = { pass: jasmine.jQuery.events.wasTriggered(selector, eventName) }
624
-
625
- result.message = result.pass ?
626
- "Expected event " + eventName + " not to have been triggered on " + selector :
627
- "Expected event " + eventName + " to have been triggered on " + selector
628
-
629
- return result
630
- }
631
- }
632
- },
633
-
634
- toHaveBeenTriggeredOnAndWith: function (j$, customEqualityTesters) {
635
- return {
636
- compare: function (actual, selector, expectedArgs) {
637
- var wasTriggered = jasmine.jQuery.events.wasTriggered(selector, actual)
638
- , result = { pass: wasTriggered && jasmine.jQuery.events.wasTriggeredWith(selector, actual, expectedArgs, j$, customEqualityTesters) }
639
-
640
- if (wasTriggered) {
641
- var actualArgs = jasmine.jQuery.events.args(selector, actual, expectedArgs)[1]
642
- result.message = result.pass ?
643
- "Expected event " + actual + " not to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs) :
644
- "Expected event " + actual + " to have been triggered with " + jasmine.pp(expectedArgs) + " but it was triggered with " + jasmine.pp(actualArgs)
645
-
646
- } else {
647
- // todo check on this
648
- result.message = result.pass ?
649
- "Expected event " + actual + " not to have been triggered on " + selector :
650
- "Expected event " + actual + " to have been triggered on " + selector
651
- }
652
-
653
- return result
654
- }
655
- }
656
- },
657
-
658
- toHaveBeenPreventedOn: function () {
659
- return {
660
- compare: function (actual, selector) {
661
- var result = { pass: jasmine.jQuery.events.wasPrevented(selector, actual) }
662
-
663
- result.message = result.pass ?
664
- "Expected event " + actual + " not to have been prevented on " + selector :
665
- "Expected event " + actual + " to have been prevented on " + selector
666
-
667
- return result
668
- }
669
- }
670
- },
671
-
672
- toHaveBeenPrevented: function () {
673
- return {
674
- compare: function (actual) {
675
- var eventName = actual.eventName
676
- , selector = actual.selector
677
- , result = { pass: jasmine.jQuery.events.wasPrevented(selector, eventName) }
678
-
679
- result.message = result.pass ?
680
- "Expected event " + eventName + " not to have been prevented on " + selector :
681
- "Expected event " + eventName + " to have been prevented on " + selector
682
-
683
- return result
684
- }
685
- }
686
- },
687
-
688
- toHaveBeenStoppedOn: function () {
689
- return {
690
- compare: function (actual, selector) {
691
- var result = { pass: jasmine.jQuery.events.wasStopped(selector, actual) }
692
-
693
- result.message = result.pass ?
694
- "Expected event " + actual + " not to have been stopped on " + selector :
695
- "Expected event " + actual + " to have been stopped on " + selector
696
-
697
- return result;
698
- }
699
- }
700
- },
701
-
702
- toHaveBeenStopped: function () {
703
- return {
704
- compare: function (actual) {
705
- var eventName = actual.eventName
706
- , selector = actual.selector
707
- , result = { pass: jasmine.jQuery.events.wasStopped(selector, eventName) }
708
-
709
- result.message = result.pass ?
710
- "Expected event " + eventName + " not to have been stopped on " + selector :
711
- "Expected event " + eventName + " to have been stopped on " + selector
712
-
713
- return result
714
- }
715
- }
716
- }
717
- })
718
-
719
- jasmine.getEnv().addCustomEqualityTester(function(a, b) {
720
- if (a && b) {
721
- if (a instanceof $ || jasmine.isDomNode(a)) {
722
- var $a = $(a)
723
-
724
- if (b instanceof $)
725
- return $a.length == b.length && a.is(b)
726
-
727
- return $a.is(b);
728
- }
729
-
730
- if (b instanceof $ || jasmine.isDomNode(b)) {
731
- var $b = $(b)
732
-
733
- if (a instanceof jQuery)
734
- return a.length == $b.length && $b.is(a)
735
-
736
- return $(b).is(a);
737
- }
738
- }
739
- })
740
-
741
- jasmine.getEnv().addCustomEqualityTester(function (a, b) {
742
- if (a instanceof jQuery && b instanceof jQuery && a.size() == b.size())
743
- return a.is(b)
744
- })
745
- })
746
-
747
- afterEach(function () {
748
- jasmine.getFixtures().cleanUp()
749
- jasmine.getStyleFixtures().cleanUp()
750
- jasmine.jQuery.events.cleanUp()
751
- })
752
-
753
- window.readFixtures = function () {
754
- return jasmine.getFixtures().proxyCallTo_('read', arguments)
755
- }
756
-
757
- window.preloadFixtures = function () {
758
- jasmine.getFixtures().proxyCallTo_('preload', arguments)
759
- }
760
-
761
- window.loadFixtures = function () {
762
- jasmine.getFixtures().proxyCallTo_('load', arguments)
763
- }
764
-
765
- window.appendLoadFixtures = function () {
766
- jasmine.getFixtures().proxyCallTo_('appendLoad', arguments)
767
- }
768
-
769
- window.setFixtures = function (html) {
770
- return jasmine.getFixtures().proxyCallTo_('set', arguments)
771
- }
772
-
773
- window.appendSetFixtures = function () {
774
- jasmine.getFixtures().proxyCallTo_('appendSet', arguments)
775
- }
776
-
777
- window.sandbox = function (attributes) {
778
- return jasmine.getFixtures().sandbox(attributes)
779
- }
780
-
781
- window.spyOnEvent = function (selector, eventName) {
782
- return jasmine.jQuery.events.spyOn(selector, eventName)
783
- }
784
-
785
- window.preloadStyleFixtures = function () {
786
- jasmine.getStyleFixtures().proxyCallTo_('preload', arguments)
787
- }
788
-
789
- window.loadStyleFixtures = function () {
790
- jasmine.getStyleFixtures().proxyCallTo_('load', arguments)
791
- }
792
-
793
- window.appendLoadStyleFixtures = function () {
794
- jasmine.getStyleFixtures().proxyCallTo_('appendLoad', arguments)
795
- }
796
-
797
- window.setStyleFixtures = function (html) {
798
- jasmine.getStyleFixtures().proxyCallTo_('set', arguments)
799
- }
800
-
801
- window.appendSetStyleFixtures = function (html) {
802
- jasmine.getStyleFixtures().proxyCallTo_('appendSet', arguments)
803
- }
804
-
805
- window.loadJSONFixtures = function () {
806
- return jasmine.getJSONFixtures().proxyCallTo_('load', arguments)
807
- }
808
-
809
- window.getJSONFixture = function (url) {
810
- return jasmine.getJSONFixtures().proxyCallTo_('read', arguments)[url]
811
- }
812
- }(window, window.jasmine, window.jQuery);