magic_lamp 0.9.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +286 -59
  3. data/app/assets/javascripts/magic_lamp/genie.js +32 -7
  4. data/app/assets/javascripts/magic_lamp/magic_lamp.js +4 -0
  5. data/app/controllers/magic_lamp/fixtures_controller.rb +2 -2
  6. data/lib/magic_lamp.rb +59 -14
  7. data/lib/magic_lamp/callbacks.rb +24 -0
  8. data/lib/magic_lamp/configuration.rb +26 -0
  9. data/lib/magic_lamp/fixture_creator.rb +6 -5
  10. data/lib/magic_lamp/render_catcher.rb +17 -10
  11. data/lib/magic_lamp/version.rb +1 -1
  12. data/lib/tasks/fixture_names_task.rb +7 -0
  13. data/lib/tasks/lint_task.rb +8 -0
  14. data/spec/controllers/magic_lamp/fixtures_controller_spec.rb +2 -2
  15. data/spec/dummy/log/development.log +74880 -0
  16. data/spec/dummy/log/test.log +223258 -0
  17. data/spec/dummy/persisted_specs/magic_lamp.rb +5 -0
  18. data/spec/dummy/persisted_specs/magic_lamp_config.rb +14 -0
  19. data/spec/dummy/spec/magical/a_lamp_file_with_a_different_name_lamp.rb +7 -0
  20. data/spec/dummy/spec/magical/magic_lamp.rb +1 -1
  21. data/spec/dummy/spec/magical/magic_lamp_config.rb +1 -0
  22. data/spec/dummy/tmp/cache/assets/development/sprockets/020414588350dc7f6c910d23b47b2eac +0 -0
  23. data/spec/dummy/tmp/cache/assets/development/sprockets/04a1e26a9e3fde1f448cb2a9d382fbbc +0 -0
  24. data/spec/dummy/tmp/cache/assets/development/sprockets/09bc89d8ac4ccacfcf2f4db466e7735f +0 -0
  25. data/spec/dummy/tmp/cache/assets/development/sprockets/0b3144442052dbb8af7f57ca27cd7a15 +0 -0
  26. data/spec/dummy/tmp/cache/assets/development/sprockets/18650d8ff9b0a83b32e55b58917ec791 +0 -0
  27. data/spec/dummy/tmp/cache/assets/development/sprockets/1b2519cef64d534f944996a2326823f6 +0 -0
  28. data/spec/dummy/tmp/cache/assets/development/sprockets/1e42928536d86174d2365d82a034082b +0 -0
  29. data/spec/dummy/tmp/cache/assets/development/sprockets/292405ba7ff52dbb279572aee49ba174 +0 -0
  30. data/spec/dummy/tmp/cache/assets/development/sprockets/2c66f0d7ef22d32ab110fc31a55fe828 +0 -0
  31. data/spec/dummy/tmp/cache/assets/development/sprockets/2ccef21649a61deac2c84f622753b77b +0 -0
  32. data/spec/dummy/tmp/cache/assets/development/sprockets/32b0c6aea545968d6da4939bcbab9b5e +0 -0
  33. data/spec/dummy/tmp/cache/assets/development/sprockets/32d3add1308f63f1ce5eacde1eba7752 +0 -0
  34. data/spec/dummy/tmp/cache/assets/development/sprockets/3823434d99b44359ee75dffba2817055 +0 -0
  35. data/spec/dummy/tmp/cache/assets/development/sprockets/3a2dd1069a3d0cd57769e33920561e09 +0 -0
  36. data/spec/dummy/tmp/cache/assets/development/sprockets/3c8cdd0e5d5eee39df490048c656a2c5 +0 -0
  37. data/spec/dummy/tmp/cache/assets/development/sprockets/40f78fd7fa893a3ba0bb52949d4d6e21 +0 -0
  38. data/spec/dummy/tmp/cache/assets/development/sprockets/4878804f69b49fa9eb8a9c0af84ba31a +0 -0
  39. data/spec/dummy/tmp/cache/assets/development/sprockets/4af6cefe350f9be6f923a3d72edf1813 +0 -0
  40. data/spec/dummy/tmp/cache/assets/development/sprockets/51333e0ed6511483c511470803d3803a +0 -0
  41. data/spec/dummy/tmp/cache/assets/development/sprockets/5723ed075d2604a5ae91531445b2a613 +0 -0
  42. data/spec/dummy/tmp/cache/assets/development/sprockets/58367e9b5bd6d94235a07214faacf926 +0 -0
  43. data/spec/dummy/tmp/cache/assets/development/sprockets/5b03eeac2e4ecbaaf227c5aa35808fee +0 -0
  44. data/spec/dummy/tmp/cache/assets/development/sprockets/5bbf09297502a156801e9c65f4bd3db7 +0 -0
  45. data/spec/dummy/tmp/cache/assets/development/sprockets/5c9e5cf4ec642fa40af2267ef88f3095 +0 -0
  46. data/spec/dummy/tmp/cache/assets/development/sprockets/5ce07b63a8c04b5207f4ce3e753f5cee +0 -0
  47. data/spec/dummy/tmp/cache/assets/development/sprockets/62b7a364ac8780cbc8d56c1c6434a0a4 +0 -0
  48. data/spec/dummy/tmp/cache/assets/development/sprockets/6f968441247482ba7e1ac7ce9f34dfdb +0 -0
  49. data/spec/dummy/tmp/cache/assets/development/sprockets/759e97d6d411bc4cef7055a778e1bef3 +0 -0
  50. data/spec/dummy/tmp/cache/assets/development/sprockets/7f5b2f45d9f12db1fb26a605759b360a +0 -0
  51. data/spec/dummy/tmp/cache/assets/development/sprockets/7f7dcf7837dbb7f150b7364ad7920712 +0 -0
  52. data/spec/dummy/tmp/cache/assets/development/sprockets/80a68d71946643e61d91cc216f7aa32f +0 -0
  53. data/spec/dummy/tmp/cache/assets/development/sprockets/86023efec2465a88617e5a47a38f1f55 +0 -0
  54. data/spec/dummy/tmp/cache/assets/development/sprockets/87c6d9a5c985ccb321255862fd8c2f48 +0 -0
  55. data/spec/dummy/tmp/cache/assets/development/sprockets/88fe64427f1fff8e41ca8ad0170da88a +0 -0
  56. data/spec/dummy/tmp/cache/assets/development/sprockets/8a0862dca044d19cadb655c53acb20ab +0 -0
  57. data/spec/dummy/tmp/cache/assets/development/sprockets/8c4d5b82ba38d47cebae9c56db8fc883 +0 -0
  58. data/spec/dummy/tmp/cache/assets/development/sprockets/8dc2cb33d4af3c73661b4b84b4a95947 +0 -0
  59. data/spec/dummy/tmp/cache/assets/development/sprockets/8e2a04fd6b5a2e086e5d604cb8224809 +0 -0
  60. data/spec/dummy/tmp/cache/assets/development/sprockets/8ed4b4f20fb65446181984e6df7d7c9b +0 -0
  61. data/spec/dummy/tmp/cache/assets/development/sprockets/8f4a370f455559b7a209ecd758a3bb3d +0 -0
  62. data/spec/dummy/tmp/cache/assets/development/sprockets/96210dc070e479fcee862294afe5efc1 +0 -0
  63. data/spec/dummy/tmp/cache/assets/development/sprockets/972b6b0bb1fc0b1123077b4b2f4394bd +0 -0
  64. data/spec/dummy/tmp/cache/assets/development/sprockets/9825272284630c2926f661645205382a +0 -0
  65. data/spec/dummy/tmp/cache/assets/development/sprockets/9d676cb2f7cb26509cfcd0bce3f08fee +0 -0
  66. data/spec/dummy/tmp/cache/assets/development/sprockets/acbd4771ecb2a173a35382fbff9317cf +0 -0
  67. data/spec/dummy/tmp/cache/assets/development/sprockets/b226a96bfa85a5a853dd6566d1706231 +0 -0
  68. data/spec/dummy/tmp/cache/assets/development/sprockets/b29390c73fea05dd0073f043c17a9986 +0 -0
  69. data/spec/dummy/tmp/cache/assets/development/sprockets/b2a142b210c2cbfe4a58040684b3c33c +0 -0
  70. data/spec/dummy/tmp/cache/assets/development/sprockets/bb57f340ac9df9041014540af079a7f3 +0 -0
  71. data/spec/dummy/tmp/cache/assets/development/sprockets/bfa154e8a12acdbc85028ad8130d9043 +0 -0
  72. data/spec/dummy/tmp/cache/assets/development/sprockets/c84af5f8f55b15818667b16b15416431 +0 -0
  73. data/spec/dummy/tmp/cache/assets/development/sprockets/cf573b52d944e8aea7f1dc03f9be9b2c +0 -0
  74. data/spec/dummy/tmp/cache/assets/development/sprockets/d53d8d895a44b860d5e1399e1a9a7b69 +0 -0
  75. data/spec/dummy/tmp/cache/assets/development/sprockets/d5b28f340e57aab871a83d30b1294b62 +0 -0
  76. data/spec/dummy/tmp/cache/assets/development/sprockets/d98de652252dc6ae11b5b6db5588705b +0 -0
  77. data/spec/dummy/tmp/cache/assets/development/sprockets/e52d001ef73b04129baa586e2822018e +0 -0
  78. data/spec/dummy/tmp/cache/assets/development/sprockets/f0aa53eb377a5d7cc83657ef33b02d25 +0 -0
  79. data/spec/dummy/tmp/cache/assets/development/sprockets/f12e838fbbcc1647156ec47ebbeaac9a +0 -0
  80. data/spec/dummy/tmp/cache/assets/development/sprockets/f3018c23e25ab4b02fc51d6302f79a0a +0 -0
  81. data/spec/dummy/tmp/cache/assets/development/sprockets/f30abc368796858ff89a5ff6daf33e6a +0 -0
  82. data/spec/dummy/tmp/cache/assets/development/sprockets/f5d1b7d2ec1c89dc32cc982b43502dc8 +0 -0
  83. data/spec/dummy/tmp/cache/assets/development/sprockets/f5e8036e8de24870e4db21ccb209e272 +0 -0
  84. data/spec/dummy/tmp/cache/assets/development/sprockets/f6256b2e4e609981d9eb420aae5bef46 +0 -0
  85. data/spec/dummy/tmp/cache/assets/development/sprockets/f62fb3331d14ad448ad997f1fbdb7e23 +0 -0
  86. data/spec/dummy/tmp/cache/assets/development/sprockets/fd203e335fb22b3109d0354b99f45c6e +0 -0
  87. data/spec/dummy/tmp/cache/assets/development/sprockets/fdc3718e0a84d340a897f87179d95c84 +0 -0
  88. data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  89. data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  90. data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  91. data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  92. data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  93. data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  94. data/spec/javascripts/genie_spec.js +97 -28
  95. data/spec/javascripts/magic_lamp_spec.js +50 -17
  96. data/spec/javascripts/spec_helper.js +5 -4
  97. data/spec/javascripts/support/chai-fuzzy.js +110 -0
  98. data/spec/lib/callbacks_spec.rb +58 -0
  99. data/spec/lib/configuration_spec.rb +48 -0
  100. data/spec/lib/fixture_creator_spec.rb +17 -14
  101. data/spec/lib/magic_lamp_spec.rb +97 -26
  102. data/spec/lib/render_catcher_spec.rb +18 -4
  103. data/spec/rails_helper.rb +2 -0
  104. data/spec/spec_helper.rb +5 -0
  105. data/spec/tasks/fixture_names_task_spec.rb +23 -0
  106. data/spec/tasks/lint_task_spec.rb +17 -0
  107. data/spec/teaspoon_env.rb +33 -34
  108. metadata +146 -9
  109. data/lib/tasks/magic_lamp_tasks.rake +0 -4
  110. data/spec/dummy/tmp/pids/server.pid +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34dc16bf3efdeacd3b5b274d3aae3397b92c9245
4
- data.tar.gz: bdf8b8529ece4f4148d3ed6f0ddb32f6dca4c9be
3
+ metadata.gz: b2f6a80fc4bb9835603fed87f0d08b6fad8e6564
4
+ data.tar.gz: 6b90fee38734efbb331d547e3514edb9ff200d8a
5
5
  SHA512:
6
- metadata.gz: 849734d6efead9d19a73bb6e08b41437de7c13d93da14e348e74296f3695f7c8a2a93e9eafdddfc496e991378ee6a999825c5368ab0b60455b9dc3880cb3c892
7
- data.tar.gz: 712c6fd03a75c35f9b74ac746d96f15734437fdda425dd33921590a70a0ee43e30d82f359735f66f68f9c35678e60040e87dbc5b7bab9fbc7188bcc267ad5b69
6
+ metadata.gz: 46143b9947260d1da0c7e45a9cd26c16aa569e682cd1be085b91a4fcbf1714225b0232b1fbf5aa077fdbc17c0379e1c95caa12bbb68e57ffb10385077dca2719
7
+ data.tar.gz: a0fbd5f0fe9c80ddfb99ff86f90133a2c4faadd30ac6ae45ccf2bb44228dd592f047e3b34615b7b96d0c5af8b8a974cd735e669304ba1a12186ef6a3547474ae
data/README.md CHANGED
@@ -1,23 +1,40 @@
1
- # MagicLamp
1
+ Magic Lamp
2
+ =========
3
+ Magic Lamp helps you get your Rails templates into your JavaScript tests. This means that way your JavaScript tests break
4
+ if you change your templates _and_ you don't have to create so many fixtures. Plus, it lets you test your views in JavaScript.
5
+ All you have to do is set up your data just like you would in a controller.
2
6
 
3
- MagicLamp makes sure that your JavaScript tests break when you change a template your code depends on.
7
+ It's not required that you use [Teaspoon](https://github.com/modeset/teaspoon) as your JavaScript test runner, but you should.
4
8
 
5
- ## Installation
9
+ Table of Contents
10
+ -----------------
11
+ 1. [Installation](#installation)
12
+ 2. [Basic Usage](#basic-usage)
13
+ 3. [Where the files go](#where-the-files-go)
14
+ 4. [Tasks](#tasks)
15
+ 5. [Ruby API](#ruby-api)
16
+ 6. [JavaScript API](#javascript-api)
17
+ 7. [Errors](#errors)
18
+ 8. [Sweet Aliases](#sweet-aliases)
19
+ 9. [Contributing](#contributing)
6
20
 
7
- Add this line to your application's Gemfile:
8
-
9
- gem "magic_lamp"
21
+ Installation
22
+ ------------
10
23
 
24
+ Add this line to your application's `Gemfile`:
25
+ ```ruby
26
+ gem "magic_lamp"
27
+ ```
11
28
  And then execute:
12
29
 
13
- $ bundle
30
+ $ bundle install
14
31
 
15
- Or install it yourself as:
32
+ Or install it yourself with:
16
33
 
17
34
  $ gem install magic_lamp
18
- ## Setup
19
- ### Ruby side
20
- Fixtures can be registered in any file that ends with `_lamp.rb` anywhere in your `spec` or `test` directory. You'll also need to mount MagicLamp in your `config/routes.rb` like so:
35
+
36
+ Then paste `mount MagicLamp::Genie, at: "/magic_lamp" if defined?(MagicLamp)` into your `config/routes.rb`
37
+ like so:
21
38
  ```ruby
22
39
  Rails.application.routes.draw do
23
40
  # ...
@@ -25,84 +42,294 @@ Rails.application.routes.draw do
25
42
  # ...
26
43
  end
27
44
  ```
28
- ### JavaScript side
29
- You can use any rails JavaScript spec runner that runs your application's server. If you're using [Teaspoon](https://github.com/modeset/teaspoon), simply add `//= require magic_lamp` to your `spec_helper.js`.
45
+ This mounts the Magic Lamp engine in your app.
46
+
47
+ Then drop this:
48
+ ```js
49
+ //= require magic_lamp
50
+ ```
51
+ at the top of your `spec_helper.js` (assuming your using [Teaspoon](https://github.com/modeset/teaspoon) or another JavaScript spec runner for Rails that
52
+ allows for the use of Sprockets directives).
53
+
54
+ Now you've got the basic setup.
30
55
 
31
- ## Usage
32
- A fixture can be registered like so:
56
+ In case you need it, [here's an example app](https://github.com/crismali/magic_lamp/tree/master/example).
57
+
58
+ Note: I highly recommend that you use [Teaspoon](https://github.com/modeset/teaspoon) as your JavaScript spec runner.
59
+
60
+ ### With Database Cleaner
61
+
62
+ You don't need [Database Cleaner](https://github.com/DatabaseCleaner/database_cleaner) to use this gem, but this is probably the setup most people want.
63
+
64
+ First make sure you have Database Cleaner installed, then you'll want to do something like this:
65
+ ```ruby
66
+ require "database_cleaner"
67
+
68
+ MagicLamp.configure do |config|
69
+
70
+ DatabaseCleaner.strategy = :transaction
71
+
72
+ config.before_each do
73
+ DatabaseCleaner.start
74
+ end
75
+
76
+ config.after_each do
77
+ DatabaseCleaner.clean
78
+ end
79
+ end
80
+ ```
81
+ in a file called `magic_lamp_config.rb` which you can place anywhere in your `spec` or `test` directories. You could
82
+ configure Magic Lamp in your `teaspoon_env.rb` file as well.
83
+
84
+ This way you can take advantage of `after_create` callbacks for your fixture setup without polluting
85
+ your database every time you run your JavaScript specs.
86
+
87
+ Basic Usage
88
+ -----------
89
+ Magic Lamp will load all files in your `spec` or `test` directory that end with `_lamp.rb` (your app's
90
+ "lamp files). I'd recommend starting with a single `magic_lamp.rb` file and breaking it into smaller
91
+ files once it gets unwieldy (one for each controller would be a good approach).
92
+
93
+ In your lamp files you just call [`MagicLamp.register_fixture`](#register_fixture) like so:
33
94
  ```ruby
34
95
  MagicLamp.register_fixture do
35
96
  @order = Order.new
36
- render "orders/new"
97
+ render partial: "orders/form"
37
98
  end
38
99
  ```
39
- Then in your JavaScript specs you can do this:
100
+ Inside the block you pass to `register_fixture` you're in the scope of a controller so you
101
+ can set up any instance variables your templates depend on. In this case we're using the
102
+ default controller which is your `ApplicationController`. We're also using the default
103
+ name for the fixture which is whatever `render` receives to identify the template (ie
104
+ the symbol or string argument to `render` or whatever is at the `:template` or `:partial`
105
+ key in the argument hash).
106
+
107
+ `render` here also works normally except that it won't render the layout by default.
108
+
109
+ Then in your JavaScript you can call [`load`](#load):
40
110
  ```js
41
- MagicLamp.load('orders/new');
111
+ beforeEach(function() {
112
+ MagicLamp.load("orders/form");
113
+ });
42
114
  ```
43
- which will load the `"orders/new"` template into a `div` with an id of `magic-lamp`.
115
+ which will put the `orders/form` partial in a div with a class of `magic-lamp`. Then you
116
+ can go nuts testing your JavaScript against your actual template. If you'd like to only make
117
+ one request for your templates, simply call [`MagicLamp.preload();`](#preload) in your `spec_helper.js` to
118
+ populate Magic Lamp's cache.
44
119
 
45
- ### `MagicLamp#register_fixture`
120
+ ### A few more examples
121
+ Here we're specifying which controller should render the template via the arguments hash
122
+ to `register_fixture`. This gives us access to helper methods in the `register_fixture` block
123
+ and in the template. It also means we don't need a fully qualified path to the rendered template
124
+ or partial.
46
125
 
47
- `MagicLamp#register_fixture` requires a block. In this block you are scoped to a controller instance, so you have access to private and public controller methods and that any instance variables set in this block will be available
48
- to the rendered template.
126
+ Since we didn't specify the name of our fixture and we're not using the `ApplicationController`
127
+ to render the template the fixture will be named "orders/order".
49
128
 
50
- Optionally, `register_fixture` accepts a controller class and the name of the fixture. By default the controller class is `ApplicationController` and the name is what is passed to `render` (either the string, symbol passed in, or the value of the `partial` or `template` key if it's a hash). Here's a more explicit version of the example above:
129
+ We're also taking advantage of `render`'s `:collection` option.
51
130
  ```ruby
52
- MagicLamp.register_fixture(ApplicationController, "orders/new") do
53
- @orders = [Order.new, Order.new, Order.new]
54
- render "orders/new"
131
+ MagicLamp.register_fixture(controller: OrdersController) do
132
+ orders = 3.times.map { Order.new }
133
+ render partial: "order", collection: orders
55
134
  end
56
135
  ```
57
- Specifying the controller class gives you access to private methods in the block and helper methods in the template as well as not having to provide the full path to the template or partial.
136
+
137
+ Here we're specifying a name with the `:name` option that's passed to `register_fixture`.
138
+ This way we can load the fixture in our JavaScript with `MagicLamp.load("custom/name")` instead
139
+ of the default `MagicLamp.load("orders/foo")`. Custom names for fixtures must be url safe strings.
58
140
  ```ruby
59
- MagicLamp.register_fixture(OrdersController) do
60
- @order = some_private_method(Order.new)
61
- render :index # index contains some special helper method
141
+ MagicLamp.register_fixture(name: "custom/name") do
142
+ render "orders/foo"
62
143
  end
63
144
  ```
64
- In this example, the template will be registered as `"orders/index"`. The default name for a fixture is the controller's name followed by the template (unless it's the `ApplicationController`). If you have name collisions (or if you just want a more informative fixture name), simply specify the name as the second
65
- argument to `register_fixture`.
145
+
146
+ Here we're specifying both a controller and custom name. We're also setting the `params[:foo]`
147
+ mostly to demonstrate that we have access to all of the usual controller methods.
148
+ ```ruby
149
+ MagicLamp.register_fixture(controller: OrdersController, name: "other_custom_name") do
150
+ params[:foo] = "test"
151
+ render :foo
152
+ end
153
+ ```
154
+ If you're interested, [here's an example app](https://github.com/crismali/magic_lamp/tree/master/example).
155
+ Where the files go
156
+ ------------------------
157
+ ### Config File
158
+ Magic Lamp first loads the `magic_lamp_config.rb` file. It can be anywhere in your `spec` or `test`
159
+ directory but it's not required.
160
+ ### Lamp files
161
+ Magic Lamp will load any files in your `spec` or `test` directory that end with `_lamp.rb`.
162
+
163
+ Tasks
164
+ -----
165
+ ### fixture_names
166
+ Call `rake magic_lamp:fixture_names` to see a list of all of your app's fixture names.
167
+ ### lint
168
+ Call `rake magic_lamp:lint` to see if there are any errors when registering or rendering your fixtures.
169
+
170
+ Ruby API
171
+ --------
172
+ ### register_fixture
173
+ It requires a block that invokes `render` which is invoked in the context of a controller.
174
+ It also takes an optional hash of arguments. The arguments hash recognizes:
175
+ * `:controller`
176
+ * specifies any controller class that you'd like to have render the template or partial.
177
+ * if specified it removes the need to pass fully qualified paths to templates to `render`
178
+ * `:name`
179
+ * whatever you'd like name the fixture.
180
+ * Specifying this option also prevents the block from being executed twice which could be a performance win. See [configure](#configure) for more.
181
+ Also note that only symbol keys are recognized.
182
+
183
+ `register_fixture` will also execute any callbacks you've specified. See [configure](#configure) for more.
184
+
185
+ Example:
66
186
  ```ruby
67
- MagicLamp.register_fixture(ApplicationController, "orders/new/with/errors") do
187
+ MagicLamp.register_fixture(name: "foo", controller: OrdersController) do
68
188
  @order = Order.new
69
- @errors = true
70
- render :new
189
+ render partial: :form
71
190
  end
72
191
  ```
73
- Note: Only name your fixtures with characters that are the same in the url bar of a browser as they are everywhere else.
192
+ ### configure
193
+ It requires a block to which it yields the configuration object. Here you can set:
194
+ * `before_each`
195
+ * takes a block
196
+ * defaults to `nil`
197
+ * called before each block you pass to `register_fixture` is executed
198
+ * note: if you call it a second time with a second block, only the second block will be executed
199
+ * `after_each`
200
+ * takes a block
201
+ * defaults to `nil`
202
+ * called after each block you pass to `register_fixture` is executed
203
+ * note: if you call it a second time with a second block, only the second block will be executed
204
+ * `infer_names`
205
+ * defaults to `true`
206
+ * if set to true, Magic Lamp will try to infer the name of the fixture when not provided with a name parameter.
207
+ * if set to false, the name parameter becomes required for `MagicLamp.register_fixture` (this can be done to improve performance or force your team to be more explicit)
74
208
 
75
- Also note: blocks using the default name will be executed twice (that's part of the magic required to get sweet defaults). If you don't want that to happen, just name your fixture.
209
+ Example:
76
210
 
77
- ### controller#render
78
- Everything in the block you pass to `register_fixture` is scoped to an instance of the specified controller or the `ApplicationController`. `render` behaves normally for the most part. The only magic here is to set the `layout` option to default to `false`. Aside from that though, it's normal:
79
211
  ```ruby
80
- MagicLamp.register_fixture(OrdersController) do
81
- render partial: "order",
82
- locals: { foo: "bar" },
83
- collection: [Order.new, Order.new, Order.new]
84
- # etc.
212
+ MagicLamp.configure do |config|
213
+
214
+ # if you want to require the name parameter for `MagicLamp.register_fixture`
215
+ config.infer_names = false
216
+
217
+ config.before_each do
218
+ puts "I appear before the block passed to register fixture executes!"
219
+ end
220
+
221
+ config.after_each do
222
+ puts "I appear after the block passed to register fixture executes!"
223
+ end
85
224
  end
86
225
  ```
87
- ### MagicLamp JS
88
- To load a fixture simply call `MagicLamp.load('fixture/name');`. To clear out the fixture `div`, call `MagicLamp.clean();`. If you call `MagicLamp.globalize();`, you be able to call `load` and `clean` right on `window`. If you'd like to preload all of your fixtures so you can stub network requests or something, just call `MagicLamp.preload();`.
89
226
 
90
- The `id` of the `div` MagicLamp creates to hold the fixtures can be specified by setting `MagicLamp.id`.
227
+ JavaScript API
228
+ --------------
229
+ ### clean
230
+ Calling `MagicLamp.clean()` will remove the Magic Lamp fixture container from the page.
231
+
232
+ If you don't want any dom elements from a fixture hanging around between specs, throw it
233
+ in a global `afterEach` block. Calling it with nothing to clean won't result in an error.
234
+
235
+ Example:
236
+ ```js
237
+ afterEach(function() {
238
+ MagicLamp.clean();
239
+ });
240
+ ```
241
+ ### load
242
+ Call `MagicLamp.load` to load a fixture. It requires the name of the fixture and the fixture
243
+ will be loaded into a `div` with a class of `magic-lamp`. It will destroy the previous fixture
244
+ container if present so you never end up with duplicate fixture containers or end up with
245
+ dom elements from previous loads. It will hit the network only on the first request for a given
246
+ fixture. If you never want `load` to hit the network, call `MagicLamp.preload()` before your specs.
247
+
248
+ Example:
249
+ ```js
250
+ beforeEach(function() {
251
+ MagicLamp.load("orders/foo");
252
+ });
253
+ ```
254
+ ### preload
255
+ Call `MagicLamp.preload` to load all of your templates into MagicLamp's cache. This means you'll
256
+ only hit the network once, so the rest of your specs will be quicker and you can go wild stubbing the
257
+ network.
91
258
 
92
- ### Errors
93
- If there are any errors rendering your templates, MagicLamp will log them to the server log and throw an error in JavaScript. If the error in the JavaScript doesn't make the source of the problem clear, please check the server log. If that doesn't help, open up a `rails console` and enter `MagicLamp.load_lamp_files` and see if there are any errors. If not, try calling `MagicLamp.generate_all_fixtures` and seeing if the error shows up then.
259
+ Example:
260
+ ```js
261
+ // Probably should be in your `spec_helper.js`
262
+ MagicLamp.preload();
263
+ ```
264
+ ### fixtureNames
265
+ `MagicLamp.fixtureNames()` will return an array of all of the fixture names available in the cache
266
+ (which is all of them if you've called [`preload`](#preload)). It will also `console.log` them out.
94
267
 
95
- ### Sweet aliases
96
- `MagicLamp#register_fixture` is aliased as `rub` and `wish`. On the JavaScript side of things, `load` is `rub` and `wish`. `preload` is `massage` and `wishForMoreWishes`. `clean` is `polish`.
268
+ Example
269
+ ```js
270
+ MagicLamp.preload();
271
+ MagicLamp.fixtureNames(); // => ['orders/foo', 'orders/bar', 'orders/baz']
272
+ // logs 'orders/foo'
273
+ // logs 'orders/bar'
274
+ // logs 'orders/baz'
275
+ ```
97
276
 
98
- ## Contributing
277
+ ### globalize
278
+ `MagicLamp.globalize()` will put `MagicLamp.clean` and `MagicLamp.load` onto `window` for convenience.
279
+
280
+ Example:
281
+ ```js
282
+ MagicLamp.globalize();
283
+
284
+ describe("Foo", function() {
285
+ beforeEach(function() {
286
+ load("orders/foo");
287
+ });
288
+
289
+ afterEach(function() {
290
+ clean();
291
+ });
292
+
293
+ // ...
294
+ });
295
+ ```
296
+ Errors
297
+ ------
298
+ If there are errors rendering any of your templates, Magic Lamp will often throw a JavaScript
299
+ error. Errors will also appear in your server log (if you're running the in-browser specs).
300
+
301
+ To see errors outside of the server log (which may be noisy), you can run [`rake magic_lamp:lint`](#tasks)
302
+ which will attempt to render all of your templates. If there are any errors they'll show up there in a
303
+ somewhat less noisy environment.
304
+
305
+ If you get an `ActionView::MissingTemplate` error, try specifying the controller. This error is caused by a template that renders a partial
306
+ without using the fully qualified path to the partial. Specifying the controller should help Rails find the template.
307
+
308
+ Sweet aliases
309
+ -------------
310
+ ### Ruby
311
+
312
+ ```ruby
313
+ MagicLamp.rub => register_fixture
314
+ MagicLamp.wish => register_fixture
315
+ ```
316
+
317
+ ### JavaScript
318
+ ```js
319
+ MagicLamp.rub => load
320
+ MagicLamp.wish => load
321
+ MagicLamp.massage => preload
322
+ MagicLamp.wishForMoreWishes => preload
323
+ MagicLamp.polish => clean
324
+ ```
99
325
 
326
+ Contributing
327
+ ------------
100
328
  1. Fork it
101
329
  2. Clone it locally
102
- 3. `bundle install`
103
- 4. Run the `./bootstrap` script
104
- 5. Run the specs with `rake`
105
- 6. Create your feature branch (`git checkout -b my-new-feature`)
106
- 7. Commit your changes (`git commit -am 'Add some feature'`)
107
- 8. Push to the branch (`git push origin my-new-feature`)
108
- 9. Create new Pull Request
330
+ 3. Run the `./bootstrap` script
331
+ 4. Run the specs with `rake`
332
+ 5. Create your feature branch (`git checkout -b my-new-feature`)
333
+ 6. Commit your changes (`git commit -am 'Add some feature'`)
334
+ 7. Push to the branch (`git push origin my-new-feature`)
335
+ 8. Create new Pull Request
@@ -9,11 +9,12 @@
9
9
  Genie.prototype = {
10
10
 
11
11
  load: function(path) {
12
+ this.removeFixtureContainer();
12
13
  var fixture = this.cache[path];
13
14
  this.createFixtureContainer();
14
15
 
15
16
  if (!fixture && this.cacheOnly) {
16
- throw new Error('The fixture "' + path + '" was not preloaded. Is the fixture registered? Such a bummer.');
17
+ throw new Error('The fixture "' + path + '" was not preloaded. Is the fixture registered? Call `MagicLamp.fixtureNames()` to see what is registered.');
17
18
  } else if (!fixture) {
18
19
  var xhr = this.xhrRequest(getPath() + '/' + path);
19
20
  this.cache[path] = fixture = xhr.responseText;
@@ -24,15 +25,30 @@
24
25
  },
25
26
 
26
27
  preload: function() {
27
- this.cacheOnly = true;
28
28
  var xhr = this.xhrRequest(getPath());
29
29
  var json = JSON.parse(xhr.responseText);
30
30
  this.cache = json;
31
+ this.cacheOnly = true;
32
+ },
33
+
34
+ fixtureNames: function() {
35
+ var names = [];
36
+ for (fixtureName in this.cache) {
37
+ if (this.cache.hasOwnProperty(fixtureName)) {
38
+ names.push(fixtureName);
39
+ }
40
+ }
41
+ var sortedNames = names.sort();
42
+ for (var i = 0; i < sortedNames.length; i++) {
43
+ console.log(sortedNames[i]);
44
+ };
45
+
46
+ return sortedNames;
31
47
  },
32
48
 
33
49
  createFixtureContainer: function() {
34
50
  var div = document.createElement('div');
35
- div.setAttribute('id', this.namespace.id || 'magic-lamp');
51
+ div.setAttribute('class', this.namespace.class || 'magic-lamp');
36
52
  this.fixtureContainer = div;
37
53
  },
38
54
 
@@ -41,8 +57,10 @@
41
57
  },
42
58
 
43
59
  removeFixtureContainer: function() {
44
- remove(this.fixtureContainer);
45
- this.fixtureContainer = undefined;
60
+ if (this.fixtureContainer) {
61
+ remove(this.fixtureContainer);
62
+ this.fixtureContainer = undefined;
63
+ }
46
64
  },
47
65
 
48
66
  handleError: function(errorMessage) {
@@ -55,10 +73,16 @@
55
73
  xhr.open('GET', path, false);
56
74
  xhr.send();
57
75
 
58
- if (xhr.status !== 200) {
76
+ if (this.xhrStatus(xhr) === 400) {
59
77
  this.handleError(xhr.responseText);
78
+ } else if (this.xhrStatus(xhr) === 500) {
79
+ this.handleError('Something went wrong while generating the fixture, please check the server log or run `rake magic_lamp:lint` for more information');
60
80
  }
61
81
  return xhr;
82
+ },
83
+
84
+ xhrStatus: function(xhr) {
85
+ return xhr.status;
62
86
  }
63
87
  };
64
88
 
@@ -69,7 +93,8 @@
69
93
  }
70
94
 
71
95
  function remove(node) {
72
- node.parentNode.removeChild(node);
96
+ var parentNode = node.parentNode;
97
+ parentNode && parentNode.removeChild(node);
73
98
  }
74
99
 
75
100
  function newXhr() {