magic_lamp 0.9.0 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +79 -75
- data/app/assets/javascripts/magic_lamp.js +2 -0
- data/app/assets/javascripts/magic_lamp/application.js +14 -0
- data/app/assets/javascripts/magic_lamp/boot.js +1 -0
- data/app/assets/javascripts/magic_lamp/genie.js +97 -0
- data/app/assets/javascripts/magic_lamp/magic_lamp.js +35 -0
- data/app/assets/stylesheets/magic_lamp/application.css +15 -0
- data/app/controllers/magic_lamp/application_controller.rb +4 -0
- data/app/controllers/magic_lamp/fixtures_controller.rb +35 -0
- data/app/helpers/magic_lamp/application_helper.rb +4 -0
- data/app/views/layouts/magic_lamp/application.html.erb +14 -0
- data/config/routes.rb +4 -0
- data/lib/magic_lamp.rb +83 -20
- data/lib/magic_lamp/engine.rb +9 -0
- data/lib/magic_lamp/fixture_creator.rb +2 -10
- data/lib/magic_lamp/render_catcher.rb +15 -0
- data/lib/magic_lamp/version.rb +1 -1
- data/lib/tasks/magic_lamp_tasks.rake +4 -0
- data/spec/controllers/magic_lamp/fixtures_controller_spec.rb +73 -0
- data/spec/dummy/app/views/orders/bar.html.erb +1 -0
- data/spec/dummy/config/application.rb +7 -1
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/production.rb +1 -2
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/routes.rb +2 -54
- data/spec/dummy/config/secrets.yml +2 -2
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/{20140623002513_create_orders.rb → 20140801133550_create_orders.rb} +0 -0
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +61270 -0
- data/spec/dummy/log/test.log +25531 -13475
- data/spec/dummy/spec/magical/magic_lamp.rb +12 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/05ecd34d23e110728a2f04ad35ec8834 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/09bc89d8ac4ccacfcf2f4db466e7735f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0dc7d2551b4cf3f654b16902e208703c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/18650d8ff9b0a83b32e55b58917ec791 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/18a0c4b365b6a030c56ac85e8aa6bd6e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/199574de4a8028cea9307b5e55d8f8be +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1a894d48e2e8089537ae95e3798d49a2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/24591221375d773f23385966709a900b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2bd1588b3767c789462d94a5fd27df88 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2ccef21649a61deac2c84f622753b77b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/38b32c335f7377670791219def8ce6d7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/38d787c2adf281dccb80274318dcf538 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3929ae7429411cd81cad5d5ed72b4912 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3c20b64b10f3325ed7f3b6695648fd8d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/480053cec74750ba76acfd86f7ff1051 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5bbf09297502a156801e9c65f4bd3db7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5ced43e55c875dddf3aca75fa148ca3e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6284ee4c2b5be7652a79edb6d4705cee +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/68b6ad376fe519ddaf9b84e87c2b077c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/69080d1368510f3bcff08c323a5913a7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6c1f143bdf6ffea1fb2fa7b967f9a437 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/759e97d6d411bc4cef7055a778e1bef3 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7f7dcf7837dbb7f150b7364ad7920712 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/86023efec2465a88617e5a47a38f1f55 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/87e991f1f72e200b4bded1eb8871ee31 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/88fe64427f1fff8e41ca8ad0170da88a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8d1d9aa6d95fc9c10dfc6e6d49778b2f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8ed4b4f20fb65446181984e6df7d7c9b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8f4a370f455559b7a209ecd758a3bb3d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/96210dc070e479fcee862294afe5efc1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/972b6b0bb1fc0b1123077b4b2f4394bd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/9825272284630c2926f661645205382a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/9fdefd8efa47bbe9a18f1faff6252e95 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b212d365916d6c2f783d5d73ae451562 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b2a142b210c2cbfe4a58040684b3c33c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b458300066aff956f7af9a6d2ae99abc +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b98b0da97c57b492a76eeb1d0faf80d7 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bceac3272b3e329aba55cb672fa18719 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/bfa154e8a12acdbc85028ad8130d9043 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c5ff389414942659c1c69d2f4f32978c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cf573b52d944e8aea7f1dc03f9be9b2c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d42871ab2eba219379cd7aa9f993c575 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d98de652252dc6ae11b5b6db5588705b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/db0cbe7314816ff20016f88d20dc5569 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ed02174e8f8230d1ff62c67e51f01576 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f0aa53eb377a5d7cc83657ef33b02d25 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f1ffba5065c7038b154a287981b34743 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f5d1b7d2ec1c89dc32cc982b43502dc8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f6256b2e4e609981d9eb420aae5bef46 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/fd3d67db3401095777d74ebf3cb94a01 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/fdc3718e0a84d340a897f87179d95c84 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2fdee9aa34e89b0182a7523c4484e5f6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/36a1fb9df9acb7490c5ac1284b2de56b +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/371bf96e99717688ed7313a0c53f4212 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/6fc757c2c8329244ca95d6909865bbc2 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/b78b6f63e1fe791ab77083cd45eb5105 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e4468469b981ba614a29626880137332 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/javascripts/genie_spec.js +210 -0
- data/spec/javascripts/magic_lamp_spec.js +185 -0
- data/spec/javascripts/spec_helper.js +109 -0
- data/spec/javascripts/support/sinon-chai.js +126 -0
- data/spec/javascripts/support/underscore-1.6.js +1343 -0
- data/spec/lib/fixture_creator_spec.rb +6 -17
- data/spec/lib/magic_lamp_spec.rb +143 -56
- data/spec/lib/render_catcher_spec.rb +35 -0
- data/spec/rails_helper.rb +3 -13
- data/spec/spec_helper.rb +2 -3
- data/spec/teaspoon_env.rb +186 -0
- metadata +206 -15
- data/lib/tasks/magic_lamp_tasks.rb +0 -44
- data/spec/dummy/spec/magic_lamp.rb +0 -4
- data/spec/dummy/spec/magic_lamp/foo/foo_lamp.rb +0 -1
- data/spec/dummy/spec/magic_lamp/rake/rake_lamp.rb +0 -3
- data/spec/integration/integration_spec.rb +0 -21
- data/spec/tasks/magic_lamp_tasks_spec.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34dc16bf3efdeacd3b5b274d3aae3397b92c9245
|
4
|
+
data.tar.gz: bdf8b8529ece4f4148d3ed6f0ddb32f6dca4c9be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 849734d6efead9d19a73bb6e08b41437de7c13d93da14e348e74296f3695f7c8a2a93e9eafdddfc496e991378ee6a999825c5368ab0b60455b9dc3880cb3c892
|
7
|
+
data.tar.gz: 712c6fd03a75c35f9b74ac746d96f15734437fdda425dd33921590a70a0ee43e30d82f359735f66f68f9c35678e60040e87dbc5b7bab9fbc7188bcc267ad5b69
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# MagicLamp
|
2
2
|
|
3
|
-
MagicLamp
|
4
|
-
your tests will break. This is accomplished by generating fixture files from your actual templates just before running your JavaScript specs.
|
3
|
+
MagicLamp makes sure that your JavaScript tests break when you change a template your code depends on.
|
5
4
|
|
6
5
|
## Installation
|
7
6
|
|
@@ -16,89 +15,94 @@ And then execute:
|
|
16
15
|
Or install it yourself as:
|
17
16
|
|
18
17
|
$ 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:
|
21
|
+
```ruby
|
22
|
+
Rails.application.routes.draw do
|
23
|
+
# ...
|
24
|
+
mount MagicLamp::Genie, at: "/magic_lamp" if defined?(MagicLamp)
|
25
|
+
# ...
|
26
|
+
end
|
27
|
+
```
|
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`.
|
30
|
+
|
19
31
|
## Usage
|
20
|
-
|
21
|
-
In any file that ends in `_lamp.rb` in your `spec` or `test` directory:
|
32
|
+
A fixture can be registered like so:
|
22
33
|
```ruby
|
23
|
-
MagicLamp.
|
24
|
-
|
25
|
-
|
26
|
-
# instance variables set in this block will be available to
|
27
|
-
# the template you render. You also have access to the usual
|
28
|
-
# controller methods and helpers here
|
29
|
-
params[:foo] = "some param that's rendered for some reason"
|
30
|
-
|
31
|
-
render :template_to_be_rendered
|
32
|
-
# or
|
33
|
-
# render partial: :partial_to_be_rendered
|
34
|
-
# or
|
35
|
-
# render partial: :foo, collection: [Foo.new, Foo.new, Foo.new]
|
36
|
-
# or
|
37
|
-
# pretty much anything you can normall do with render
|
34
|
+
MagicLamp.register_fixture do
|
35
|
+
@order = Order.new
|
36
|
+
render "orders/new"
|
38
37
|
end
|
39
38
|
```
|
40
|
-
Then
|
41
|
-
|
42
|
-
|
43
|
-
There would be a file called `fixture_name.html` containing the rendered template in `tmp/magic_lamp`.
|
44
|
-
A more in depth example can be found below.
|
45
|
-
|
46
|
-
### Rake tasks
|
47
|
-
The basic tasks are:
|
48
|
-
* `rake magic_lamp:create_fixtures` - generates fixtures from `_lamp` files
|
49
|
-
* `rake magic_lamp:clean` - deletes fixtures (by removing `tmp/magic_lamp`)
|
50
|
-
* `rake magic_lamp` - alias for `rake magic_lamp:create_fixtures`
|
51
|
-
|
52
|
-
Since you'll probably always want to run the create fixtures task before you run your JavaScript specs, MagicLamp comes with some convenience tasks that create your fixtures and then immediately run your JavaScript specs:
|
53
|
-
* `rake magic_lamp:evergreen` - [Evergreen](https://github.com/abepetrillo/evergreen) integration (you'll need `gem "evergreen", require: "evergreen/rails"` for this to work)
|
54
|
-
* `rake magic_lamp:jasmine` - [Jasmine Gem](https://github.com/pivotal/jasmine-gem) integration
|
55
|
-
* `rake magic_lamp:jasmine_rails` - [JasmineRails](https://github.com/searls/jasmine-rails) integration
|
56
|
-
* `rake magic_lamp:konacha` - [Konacha](https://github.com/jfirebaugh/konacha) integration
|
57
|
-
* `rake magic_lamp:teaspoon` - [Teaspoon](https://github.com/modeset/teaspoon) integration
|
58
|
-
|
59
|
-
### In depth example
|
60
|
-
Let"s assume we have `Order` model and `OrdersController` and that we want to test our JavaScript against the `views/orders/index.html.erb` that looks like this:
|
61
|
-
```html
|
62
|
-
<ul class="orders">
|
63
|
-
<% @orders.each do |order| %>
|
64
|
-
<li>
|
65
|
-
<%= order_name(order) %>
|
66
|
-
</li>
|
67
|
-
<% end %>
|
68
|
-
</ul>
|
39
|
+
Then in your JavaScript specs you can do this:
|
40
|
+
```js
|
41
|
+
MagicLamp.load('orders/new');
|
69
42
|
```
|
70
|
-
|
43
|
+
which will load the `"orders/new"` template into a `div` with an id of `magic-lamp`.
|
44
|
+
|
45
|
+
### `MagicLamp#register_fixture`
|
71
46
|
|
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.
|
49
|
+
|
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:
|
51
|
+
```ruby
|
52
|
+
MagicLamp.register_fixture(ApplicationController, "orders/new") do
|
53
|
+
@orders = [Order.new, Order.new, Order.new]
|
54
|
+
render "orders/new"
|
55
|
+
end
|
56
|
+
```
|
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.
|
58
|
+
```ruby
|
59
|
+
MagicLamp.register_fixture(OrdersController) do
|
60
|
+
@order = some_private_method(Order.new)
|
61
|
+
render :index # index contains some special helper method
|
62
|
+
end
|
63
|
+
```
|
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`.
|
72
66
|
```ruby
|
73
|
-
MagicLamp.
|
74
|
-
@
|
75
|
-
|
76
|
-
|
77
|
-
Order.new(name: "baz", id: 3)
|
78
|
-
]
|
79
|
-
render :index
|
67
|
+
MagicLamp.register_fixture(ApplicationController, "orders/new/with/errors") do
|
68
|
+
@order = Order.new
|
69
|
+
@errors = true
|
70
|
+
render :new
|
80
71
|
end
|
81
72
|
```
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
</li>
|
96
|
-
</ul>
|
73
|
+
Note: Only name your fixtures with characters that are the same in the url bar of a browser as they are everywhere else.
|
74
|
+
|
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.
|
76
|
+
|
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
|
+
```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.
|
85
|
+
end
|
97
86
|
```
|
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
|
+
|
90
|
+
The `id` of the `div` MagicLamp creates to hold the fixtures can be specified by setting `MagicLamp.id`.
|
91
|
+
|
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.
|
94
|
+
|
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`.
|
97
|
+
|
98
98
|
## Contributing
|
99
99
|
|
100
100
|
1. Fork it
|
101
|
-
2.
|
102
|
-
3.
|
103
|
-
4.
|
104
|
-
5.
|
101
|
+
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
|
@@ -0,0 +1,14 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require magic_lamp/magic_lamp
|
14
|
+
//= require magic_lamp/genie
|
@@ -0,0 +1 @@
|
|
1
|
+
MagicLamp.initialize();
|
@@ -0,0 +1,97 @@
|
|
1
|
+
(function(global) {
|
2
|
+
|
3
|
+
function Genie() {
|
4
|
+
this.cache = {};
|
5
|
+
this.cacheOnly = false;
|
6
|
+
this.namespace = MagicLamp;
|
7
|
+
}
|
8
|
+
|
9
|
+
Genie.prototype = {
|
10
|
+
|
11
|
+
load: function(path) {
|
12
|
+
var fixture = this.cache[path];
|
13
|
+
this.createFixtureContainer();
|
14
|
+
|
15
|
+
if (!fixture && this.cacheOnly) {
|
16
|
+
throw new Error('The fixture "' + path + '" was not preloaded. Is the fixture registered? Such a bummer.');
|
17
|
+
} else if (!fixture) {
|
18
|
+
var xhr = this.xhrRequest(getPath() + '/' + path);
|
19
|
+
this.cache[path] = fixture = xhr.responseText;
|
20
|
+
}
|
21
|
+
|
22
|
+
this.fixtureContainer.innerHTML = fixture;
|
23
|
+
this.appendFixtureContainer();
|
24
|
+
},
|
25
|
+
|
26
|
+
preload: function() {
|
27
|
+
this.cacheOnly = true;
|
28
|
+
var xhr = this.xhrRequest(getPath());
|
29
|
+
var json = JSON.parse(xhr.responseText);
|
30
|
+
this.cache = json;
|
31
|
+
},
|
32
|
+
|
33
|
+
createFixtureContainer: function() {
|
34
|
+
var div = document.createElement('div');
|
35
|
+
div.setAttribute('id', this.namespace.id || 'magic-lamp');
|
36
|
+
this.fixtureContainer = div;
|
37
|
+
},
|
38
|
+
|
39
|
+
appendFixtureContainer: function() {
|
40
|
+
document.body.appendChild(this.fixtureContainer);
|
41
|
+
},
|
42
|
+
|
43
|
+
removeFixtureContainer: function() {
|
44
|
+
remove(this.fixtureContainer);
|
45
|
+
this.fixtureContainer = undefined;
|
46
|
+
},
|
47
|
+
|
48
|
+
handleError: function(errorMessage) {
|
49
|
+
throw new Error(errorMessage);
|
50
|
+
},
|
51
|
+
|
52
|
+
xhrRequest: function(path) {
|
53
|
+
var xhr = newXhr();
|
54
|
+
|
55
|
+
xhr.open('GET', path, false);
|
56
|
+
xhr.send();
|
57
|
+
|
58
|
+
if (xhr.status !== 200) {
|
59
|
+
this.handleError(xhr.responseText);
|
60
|
+
}
|
61
|
+
return xhr;
|
62
|
+
}
|
63
|
+
};
|
64
|
+
|
65
|
+
// private
|
66
|
+
|
67
|
+
function getPath() {
|
68
|
+
return MagicLamp.path || '/magic_lamp';
|
69
|
+
}
|
70
|
+
|
71
|
+
function remove(node) {
|
72
|
+
node.parentNode.removeChild(node);
|
73
|
+
}
|
74
|
+
|
75
|
+
function newXhr() {
|
76
|
+
var xhr;
|
77
|
+
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
|
78
|
+
xhr = new XMLHttpRequest();
|
79
|
+
} else if (window.ActiveXObject) { // IE
|
80
|
+
try {
|
81
|
+
xhr = new ActiveXObject('Msxml2.XMLHTTP');
|
82
|
+
} catch (error) {
|
83
|
+
try {
|
84
|
+
xhr = new ActiveXObject('Microsoft.XMLHTTP');
|
85
|
+
} catch (e) {
|
86
|
+
// let it go
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
if (!xhr) {
|
91
|
+
throw('Unable to make request');
|
92
|
+
}
|
93
|
+
return xhr;
|
94
|
+
}
|
95
|
+
|
96
|
+
MagicLamp.Genie = Genie;
|
97
|
+
})(this);
|
@@ -0,0 +1,35 @@
|
|
1
|
+
var MagicLamp = {
|
2
|
+
|
3
|
+
initialize: function() {
|
4
|
+
this.genie = new this.Genie();
|
5
|
+
},
|
6
|
+
|
7
|
+
globalize: function() {
|
8
|
+
var context = this;
|
9
|
+
window.load = function(path) {
|
10
|
+
context.load(path);
|
11
|
+
};
|
12
|
+
window.clean = function() {
|
13
|
+
context.clean();
|
14
|
+
};
|
15
|
+
},
|
16
|
+
|
17
|
+
load: function() {
|
18
|
+
this.genie.load.apply(this.genie, arguments);
|
19
|
+
},
|
20
|
+
|
21
|
+
preload: function() {
|
22
|
+
this.genie.preload.apply(this.genie, arguments);
|
23
|
+
},
|
24
|
+
|
25
|
+
clean: function() {
|
26
|
+
this.genie.removeFixtureContainer();
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
// aliases
|
31
|
+
MagicLamp.rub = MagicLamp.load;
|
32
|
+
MagicLamp.wish = MagicLamp.load;
|
33
|
+
MagicLamp.massage = MagicLamp.preload;
|
34
|
+
MagicLamp.wishForMoreWishes = MagicLamp.preload;
|
35
|
+
MagicLamp.polish = MagicLamp.clean;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module MagicLamp
|
2
|
+
class FixturesController < ApplicationController
|
3
|
+
ERRORS = [
|
4
|
+
"ArgumentError",
|
5
|
+
"MagicLamp::AlreadyRegisteredFixtureError",
|
6
|
+
"MagicLamp::AmbiguousFixtureNameError",
|
7
|
+
"MagicLamp::UnregisteredFixtureError"
|
8
|
+
]
|
9
|
+
|
10
|
+
rescue_from(*ERRORS) do |exception, message = exception.message|
|
11
|
+
error_message_with_bactrace = parse_error(exception, message)
|
12
|
+
logger.error(error_message_with_bactrace)
|
13
|
+
render text: message, status: 500
|
14
|
+
end
|
15
|
+
|
16
|
+
def show
|
17
|
+
namespace.load_lamp_files
|
18
|
+
render text: namespace.generate_fixture(params[:name])
|
19
|
+
end
|
20
|
+
|
21
|
+
def index
|
22
|
+
render json: namespace.generate_all_fixtures
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_error(exception, message)
|
28
|
+
([message] + exception.backtrace).join("\n\s\s\s\s")
|
29
|
+
end
|
30
|
+
|
31
|
+
def namespace
|
32
|
+
MagicLamp
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>MagicLamp</title>
|
5
|
+
<%= stylesheet_link_tag "magic_lamp/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "magic_lamp/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
data/lib/magic_lamp.rb
CHANGED
@@ -1,50 +1,113 @@
|
|
1
|
+
require "magic_lamp/fixture_creator"
|
2
|
+
require "magic_lamp/render_catcher"
|
3
|
+
require "magic_lamp/engine"
|
4
|
+
|
1
5
|
module MagicLamp
|
2
6
|
LAMP = "_lamp"
|
3
|
-
MAGIC_LAMP = "magic#{LAMP}"
|
4
7
|
SPEC = "spec"
|
5
8
|
STARS = "**"
|
6
9
|
TEST = "test"
|
7
|
-
|
8
|
-
|
10
|
+
Genie = Engine
|
11
|
+
|
12
|
+
class AmbiguousFixtureNameError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
class UnregisteredFixtureError < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
class AlreadyRegisteredFixtureError < StandardError
|
19
|
+
end
|
9
20
|
|
10
21
|
class << self
|
22
|
+
attr_accessor :registered_fixtures
|
23
|
+
|
11
24
|
def path
|
12
25
|
Rails.root.join(directory_path)
|
13
26
|
end
|
14
27
|
|
15
|
-
def
|
16
|
-
|
28
|
+
def register_fixture(controller_class = ::ApplicationController, fixture_name = nil, &block)
|
29
|
+
if block.nil?
|
30
|
+
raise ArgumentError, "MagicLamp#register_fixture requires a block"
|
31
|
+
end
|
32
|
+
|
33
|
+
if fixture_name.nil?
|
34
|
+
fixture_name = default_fixture_name(controller_class, fixture_name, block)
|
35
|
+
end
|
36
|
+
|
37
|
+
if registered?(fixture_name)
|
38
|
+
raise AlreadyRegisteredFixtureError, "a fixture called '#{fixture_name}' has already been registered"
|
39
|
+
end
|
40
|
+
|
41
|
+
registered_fixtures[fixture_name] = [controller_class, block]
|
17
42
|
end
|
18
43
|
|
19
|
-
|
20
|
-
|
21
|
-
|
44
|
+
alias_method :rub, :register_fixture
|
45
|
+
alias_method :wish, :register_fixture
|
46
|
+
|
47
|
+
def registered?(fixture_name)
|
48
|
+
registered_fixtures.key?(fixture_name)
|
22
49
|
end
|
23
50
|
|
24
|
-
def
|
25
|
-
|
51
|
+
def load_lamp_files
|
52
|
+
self.registered_fixtures = {}
|
53
|
+
load_all(Dir[path.join(STARS, "*#{LAMP}.rb")])
|
26
54
|
end
|
27
55
|
|
28
|
-
def
|
29
|
-
|
56
|
+
def generate_fixture(fixture_name)
|
57
|
+
unless registered?(fixture_name)
|
58
|
+
raise UnregisteredFixtureError, "'#{fixture_name}' is not a registered fixture"
|
59
|
+
end
|
60
|
+
controller_class, block = registered_fixtures[fixture_name]
|
61
|
+
FixtureCreator.new.generate_template(controller_class, &block)
|
30
62
|
end
|
31
63
|
|
32
|
-
def
|
33
|
-
|
64
|
+
def generate_all_fixtures
|
65
|
+
load_lamp_files
|
66
|
+
registered_fixtures.keys.each_with_object({}) do |fixture_name, fixtures|
|
67
|
+
fixtures[fixture_name] = generate_fixture(fixture_name)
|
68
|
+
end
|
34
69
|
end
|
35
70
|
|
36
71
|
private
|
37
72
|
|
73
|
+
def default_fixture_name(controller_class, fixture_name, block)
|
74
|
+
first_arg = first_render_arg(block)
|
75
|
+
fixture_name = template_name(first_arg).to_s
|
76
|
+
if fixture_name.blank?
|
77
|
+
raise AmbiguousFixtureNameError, "Unable to infer fixture name"
|
78
|
+
end
|
79
|
+
fixture_name = prepend_controller_name(fixture_name, controller_class)
|
80
|
+
fixture_name
|
81
|
+
end
|
82
|
+
|
83
|
+
def first_render_arg(block)
|
84
|
+
render_catcher = RenderCatcher.new
|
85
|
+
render_catcher.first_render_argument(&block)
|
86
|
+
end
|
87
|
+
|
88
|
+
def template_name(render_arg)
|
89
|
+
if render_arg.is_a?(Hash)
|
90
|
+
render_arg[:template] || render_arg[:partial]
|
91
|
+
else
|
92
|
+
render_arg
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def prepend_controller_name(fixture_name, controller_class)
|
97
|
+
controller_name = controller_class.controller_name
|
98
|
+
if controller_name == "application"
|
99
|
+
fixture_name
|
100
|
+
else
|
101
|
+
"#{controller_name}/#{fixture_name}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
38
105
|
def directory_path
|
39
106
|
Dir.exist?(Rails.root.join(SPEC)) ? SPEC : TEST
|
40
107
|
end
|
41
108
|
|
42
|
-
def
|
43
|
-
files.each { |file|
|
109
|
+
def load_all(files)
|
110
|
+
files.each { |file| load file }
|
44
111
|
end
|
45
112
|
end
|
46
113
|
end
|
47
|
-
|
48
|
-
require "fileutils"
|
49
|
-
require "magic_lamp/fixture_creator"
|
50
|
-
require "tasks/magic_lamp_tasks"
|