reactive-ruby 0.7.28 → 0.7.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +6 -0
  3. data/Gemfile.lock +4 -1
  4. data/README.md +132 -68
  5. data/Rakefile +5 -2
  6. data/example/examples/Gemfile +0 -2
  7. data/example/rails-tutorial/Gemfile +3 -2
  8. data/lib/generators/reactive_ruby/test_app/templates/application.rb +11 -0
  9. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/application.rb +2 -0
  10. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +3 -0
  11. data/lib/generators/reactive_ruby/test_app/templates/boot.rb +6 -0
  12. data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
  13. data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
  14. data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
  15. data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +105 -0
  16. data/lib/rails-helpers/top_level_rails_component.rb +9 -16
  17. data/lib/{reactive-ruby → react}/api.rb +8 -65
  18. data/lib/{reactive-ruby → react}/callbacks.rb +0 -0
  19. data/lib/react/component.rb +266 -0
  20. data/lib/react/component/api.rb +48 -0
  21. data/lib/react/component/class_methods.rb +183 -0
  22. data/lib/{reactive-ruby → react}/element.rb +10 -11
  23. data/lib/{reactive-ruby → react}/event.rb +0 -0
  24. data/lib/{reactive-ruby → react}/ext/hash.rb +0 -0
  25. data/lib/{reactive-ruby → react}/ext/string.rb +0 -0
  26. data/lib/react/native_library.rb +57 -0
  27. data/lib/{reactive-ruby → react}/observable.rb +0 -4
  28. data/lib/{reactive-ruby → react}/rendering_context.rb +0 -6
  29. data/lib/{reactive-ruby → react}/state.rb +3 -6
  30. data/lib/{reactive-ruby → react}/top_level.rb +2 -3
  31. data/lib/react/validator.rb +127 -0
  32. data/lib/reactive-ruby.rb +20 -20
  33. data/lib/reactive-ruby/version.rb +1 -1
  34. data/{opal-spec/reactjs → spec}/index.html.erb +1 -1
  35. data/{opal-spec → spec/react}/callbacks_spec.rb +8 -9
  36. data/{opal-spec → spec/react}/component_spec.rb +170 -120
  37. data/spec/react/dsl_spec.rb +16 -0
  38. data/{opal-spec → spec/react}/element_spec.rb +7 -20
  39. data/{opal-spec → spec/react}/event_spec.rb +3 -1
  40. data/spec/react/native_library_spec.rb +10 -0
  41. data/spec/react/param_declaration_spec.rb +18 -0
  42. data/{opal-spec → spec/react}/react_spec.rb +3 -2
  43. data/spec/react/react_state_spec.rb +22 -0
  44. data/spec/react/top_level_component_spec.rb +68 -0
  45. data/{opal-spec → spec/react}/tutorial/tutorial_spec.rb +11 -13
  46. data/{opal-spec → spec/react}/validator_spec.rb +50 -4
  47. data/spec/reactive-ruby/isomorphic_helpers_spec.rb +22 -4
  48. data/spec/spec_helper.rb +51 -0
  49. data/spec/support/react/spec_helpers.rb +57 -0
  50. data/spec/vendor/es5-shim.min.js +6 -0
  51. metadata +56 -24
  52. data/lib/reactive-ruby/component.rb +0 -502
  53. data/lib/reactive-ruby/validator.rb +0 -99
  54. data/old-readme +0 -220
  55. data/opal-spec/spec_helper.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b3ccefdd8c89194824329a42a3f700461a3349c
4
- data.tar.gz: 8f93442f60fa15f99bc7545e125f11ac9fc5b11e
3
+ metadata.gz: 527fdef11e277159a4a1d5ad88da39bfbd35e62a
4
+ data.tar.gz: 9e6fde62b7bebb1e8aaec07afcc403e0a0392d2b
5
5
  SHA512:
6
- metadata.gz: f49d3a2e156abbf32602e494a0c7fb356f090526ea8a19a3fc53d65e4d02be16dc84b79119cefcbc46ba25f280fe8f57085491a5780084db8453acce12b3da78
7
- data.tar.gz: 7828530b6d13396f33d8a91bd1fd6c02b80d8ccb3a1209af0dc5001b49b43fc8668b77a5c8a5f8b2802d4fff05e13354a583ea5766285a1843422a7a6d94578a
6
+ metadata.gz: dc02bce0e1e5517ae2f8c1dffbce49369185caa17d643d33adbebd7c543adc67687953e26dcd99f74ca1da907a7858224541b250fd68c75db797bcdcad282765
7
+ data.tar.gz: de428600bfbd14dda2ab4afddc171607de11a6c12dc4306c7cdc833e1c3d7a8ba4c196e7487e0e08ef93b1132b495757f0107cdb1d61417e736b83cd0562ff28
data/.codeclimate.yml ADDED
@@ -0,0 +1,6 @@
1
+ languages:
2
+ Ruby: true
3
+ JavaScript: false
4
+ exclude_paths:
5
+ - example/**/*
6
+ - lib/sources/**/*
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reactive-ruby (0.7.27)
4
+ reactive-ruby (0.7.28)
5
5
  opal
6
6
  opal-activesupport (>= 0.2.0)
7
7
  opal-browser
@@ -188,3 +188,6 @@ DEPENDENCIES
188
188
  sqlite3
189
189
  therubyracer
190
190
  timecop
191
+
192
+ BUNDLED WITH
193
+ 1.10.6
data/README.md CHANGED
@@ -1,151 +1,212 @@
1
- # Reactive-Ruby
1
+ # React.rb / Reactive-Ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/zetachang/react.rb.svg?branch=reactive-ruby)](https://travis-ci.org/zetachang/react.rb)
3
+ [![Join the chat at https://gitter.im/zetachang/react.rb](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/zetachang/react.rb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+ [![Build Status](https://travis-ci.org/zetachang/react.rb.svg)](https://travis-ci.org/zetachang/react.rb)
5
+ [![Code Climate](https://codeclimate.com/github/zetachang/react.rb/badges/gpa.svg)](https://codeclimate.com/github/zetachang/react.rb)
4
6
 
5
- **Reactive-Ruby is an [Opal Ruby](http://opalrb.org) wrapper of [React.js library](http://facebook.github.io/react/)**.
7
+ **React.rb is an [Opal Ruby](http://opalrb.org) wrapper of
8
+ [React.js library](http://facebook.github.io/react/)**.
6
9
 
7
- It lets you write reactive UI components, with Ruby's elegance using the tried and true React.js engine. :heart:
10
+ It lets you write reactive UI components, with Ruby's elegance using the tried
11
+ and true React.js engine. :heart:
8
12
 
9
- This fork of the original react.rb gem is a work in progress. Currently it is being used in a large rails app. However the gem itself has no dependency on rails, and there are people using the gem in other environments.
13
+ ### What's this Reactive Ruby?
10
14
 
11
- ## Quick Overview
15
+ Reactive Ruby started as a fork of the original react.rb gem, and has since been
16
+ merged back into react.rb's master branch. It aims to take react.rb a few steps
17
+ further by embracing it's 'Ruby-ness'.
12
18
 
13
- A react app is built from one or more trees of components. React components can live side by side with other non-react html and javascript. A react component is just like a rails view or a partial. Reactive-Ruby takes advantage of these features by letting you add Reactive-Ruby components as views, and call them directly from your controller like any other view.
19
+ Reactive-Ruby is maturing, but is still a work in progress. Currently it is
20
+ being used in a large rails app. However the gem itself has no dependency on
21
+ rails, and there are people using the gem in other environments.
14
22
 
15
- By design Reactive-Ruby allows reactive components to be easily added to existing Rails projects, as well in new development.
23
+ Stable react.rb can be found in the
24
+ [0-3-stable](https://github.com/zetachang/react.rb/tree/0-3-stable) branch.
16
25
 
17
- Components are first rendered to HTML on the server (called pre-rendering) this is no different from what happens when your ERB or HAML templates are translated to HTML.
26
+ ## Quick Overview
18
27
 
19
- A copy of the react engine, and your components follows the rendered HTML to the browser, and then when a user interacts with the page, it is updated on the client.
28
+ A react app is built from one or more trees of components. React components can
29
+ live side by side with other non-react html and javascript. A react component is
30
+ just like a rails view or a partial. Reactive-Ruby takes advantage of these
31
+ features by letting you add Reactive-Ruby components as views, and call them
32
+ directly from your controller like any other view.
20
33
 
21
- The beauty is you now have one markup description, written in the same language as your server code, that works both as the HTML template and as an interactive component.
34
+ By design Reactive-Ruby allows reactive components to be easily added to
35
+ existing Rails projects, as well in new development.
22
36
 
23
- ## Installation and Setup with Rails
37
+ Components are first rendered to HTML on the server (called pre-rendering) this
38
+ is no different from what happens when your ERB or HAML templates are translated
39
+ to HTML.
24
40
 
25
- In your gem file:
41
+ A copy of the react engine, and your components follows the rendered HTML to the
42
+ browser, and then when a user interacts with the page, it is updated on the
43
+ client.
26
44
 
27
- ```ruby
28
- gem 'reactive-ruby'
45
+ The beauty is you now have one markup description, written in the same language
46
+ as your server code, that works both as the HTML template and as an interactive
47
+ component.
29
48
 
30
- # the next three gems are for integration with rails (TODO - package these up as a reactive-rails gem)
49
+ See the [wiki](https://github.com/zetachang/react.rb/wiki) for more details.
31
50
 
32
- gem 'therubyracer', platforms: :ruby # you need this for prerendering to work
33
- gem 'react-rails', git: "https://github.com/catprintlabs/react-rails.git", :branch => 'isomorphic-methods-support'
34
- gem 'opal-rails'
51
+ ## Using React.rb with Rails
35
52
 
36
- # if you are planning on using jQuery don't forget to include it
53
+ ### Installation
37
54
 
38
- gem 'jquery-rails'
55
+ In your Gemfile:
56
+
57
+ ```ruby
58
+ gem 'reactive-ruby'
59
+ gem 'react-rails'
60
+ gem 'opal-rails'
61
+ gem 'therubyracer', platforms: :ruby # Required for prerendering
39
62
  ```
40
63
 
41
- Your react components will go into the `app/views/components/` directory of your rails app.
64
+ Run `bundle install` and restart your rails server.
42
65
 
43
- In addition within your views directory you need a `components.rb` manifest file like this:
66
+ ### Both Client & Server Side Assets (Components)
67
+
68
+ Your react components will go into the `app/views/components/` directory of your
69
+ rails app.
70
+
71
+ Within your `app/views` directory you need to create a `components.rb` manifest.
72
+ Files required in `app/views/components.rb` will be made available to the server
73
+ side rendering system as well as the browser.
44
74
 
45
75
  ```
46
76
  # app/views/components.rb
47
77
  require 'opal'
48
78
  require 'reactive-ruby'
49
79
  require_tree './components'
50
- ```
80
+ ```
51
81
 
52
- This pulls in the files that will be used both for server side and browser rendering.
82
+ ### Client Side Assets
53
83
 
54
- Then your `assets/javascript/application.rb` file looks like this:
84
+ In `assets/javascript/application.rb` require your components manifest as well
85
+ as any additional browser only assets.
55
86
 
56
87
  ```
57
- #assets/javascript/application.rb
88
+ # assets/javascript/application.rb
89
+ # Require files that are browser side only.
58
90
 
59
- # only put files that are browser side only.
91
+ # Make components available by requiring your components.rb manifest.
92
+ require 'components'
60
93
 
61
- require 'components' # this pulls in your components from the components.rb manifest file
62
- require 'react_ujs' # this is required on the client side only and is part of the prerendering system
94
+ # 'react_ujs' tells react in the browser to mount rendered components.
95
+ require 'react_ujs'
63
96
 
64
- # require any thing else that is browser side only, typically these 4 are all you need. If you
65
- # have client only sections of code that that do not contain requires wrap them in
66
- # if React::IsomorphicHelpers.on_opal_client? blocks.
67
-
68
- require 'jquery' # you need both these files to access jQuery from Opal
69
- require 'opal-jquery' # they must be in this order, and after the components require
70
- require 'browser/interval' # for #every, and #after methods
97
+ # Finally, require your other javascript assets. jQuery for example...
98
+ require 'jquery' # You need both these files to access jQuery from Opal.
99
+ require 'opal-jquery' # They must be in this order.
71
100
  ```
72
101
 
73
- Okay that is your setup.
102
+ ### Rendering Components
74
103
 
75
- Now for a simple component. We are going to render this from the `show` method of the home controller. We want to use convention over configuration by default. So the component will be the "Show" class, of the "Home" module,
76
- of the Components module.
104
+ Components may be rendered directly from a controller action by simply following
105
+ a naming convention. To render a component from the `home#show` action, create
106
+ component class `Components::Home::Show`:
77
107
 
78
108
  ```ruby
79
109
  # app/views/components/home/show.rb
80
-
81
110
  module Components
82
-
83
111
  module Home
84
-
85
112
  class Show
113
+ include React::Component # will create a new component named Show
86
114
 
87
- include React::Component # will create a new component named Show
88
-
89
115
  optional_param :say_hello_to
90
116
 
91
- def render
117
+ def render
92
118
  puts "Rendering my first component!"
93
- "hello #{'there '+say_hello_to if say_hello_to}" # render "hello" with optional 'there ...'
94
- end
95
119
 
120
+ # render "hello" with optional 'say_hello_to' param
121
+ "hello #{say_hello_to if say_hello_to}"
122
+ end
96
123
  end
97
-
98
124
  end
99
-
100
125
  end
101
126
  ```
102
127
 
103
- Components work just like views so put this in your home controller
128
+ Call `render_component` in the controller action passing in any params (React
129
+ props), to render the component:
130
+
104
131
  ```ruby
105
132
  # controllers/home_controller.rb
106
133
  class HomeController < ApplicationController
107
134
  def show
108
- render_component say_hello_to: params[:say_hello_to] # by default render_component will use the controller name to find the appropriate component
135
+ # render_component uses the controller name to find the 'show' component.
136
+ render_component say_hello_to: params[:say_hello_to]
109
137
  end
110
138
  end
111
139
  ```
112
140
 
113
- Make sure your routes file has a route to your home#show method, and you have done a bundle install. Fire up your development server and you should see "hello world" displayed.
141
+ Make sure your routes file has a route to your home#show action. Visit that
142
+ route in your browser and you should see 'Hello' rendered.
114
143
 
115
- Open up the js console in the browser and you will see a log showing what went on during the rendering.
144
+ Open up the js console in the browser and you will see a log showing what went
145
+ on during rendering.
116
146
 
117
- Have a look at the sources in the console, and notice your ruby code is there, and you can set break points etc.
147
+ Have a look at the sources in the console, and notice your ruby code is there,
148
+ and you can set break points etc.
118
149
 
119
150
  ### Changing the top level component name and search path
120
151
 
121
- You can control the top level component name and search path.
152
+ You can control the top level component name and search path.
122
153
 
123
- You can specify the component name explicitly in the `render_component` method. `render_component "Blatz` will search the for a component class named
124
- `Blatz` regardless of the controller method.
154
+ You can specify the component name explicitly in the `render_component` method.
155
+ `render_component "Blatz` will search the for a component class named `Blatz`
156
+ regardless of the controller method.
125
157
 
126
- Searching for components normally works like this: Given a controller named "Foo" then the component should be either in the `Components::Foo` module, the
127
- `Components` module (no controller - useful if you have just a couple of shared components) or just the outer scope (i.e. `Module`) which is useful for small apps.
158
+ Searching for components normally works like this: Given a controller named
159
+ "Foo" then the component should be either in the `Components::Foo` module, the
160
+ `Components` module (no controller - useful if you have just a couple of shared
161
+ components) or just the outer scope (i.e. `Module`) which is useful for small
162
+ apps.
128
163
 
129
- Saying `render_component "::Blatz"` will only search the outer scope, while `"::Foo::Blatz"` will look only in the module `Foo` for a class named `Blatz`.
164
+ Saying `render_component "::Blatz"` will only search the outer scope, while
165
+ `"::Foo::Blatz"` will look only in the module `Foo` for a class named `Blatz`.
130
166
 
131
167
 
132
168
  ## Integration with Sinatra
133
169
 
134
- See the sinatra-tutorial folder
170
+ See the [sinatra example](https://github.com/zetachang/react.rb/tree/master/example/sinatra-tutorial).
171
+
172
+ ## Contextual Code
173
+
174
+ Sometimes it may be necessary to run code only on the server or only in the
175
+ browser. To execute code only during server side rendering:
176
+
177
+ ```ruby
178
+ if React::IsomorphicHelpers.on_opal_server?
179
+ puts 'Hello from the server'
180
+ end
181
+ ```
182
+
183
+ To execute code only in the browser:
184
+
185
+ ```ruby
186
+ if React::IsomorphicHelpers.on_opal_client?
187
+ puts 'Hello from the browser'
188
+ end
189
+ ```
135
190
 
136
191
  ## Typical Problems
137
192
 
138
- `Uncaught TypeError: Cannot read property 'toUpperCase' of undefined` This means the thing you are trying to render is not actually a react component. Often is because the top level component name is wrong. For example if you are in controller Foo and the method is `bar`, but you have named the component Foo::Bars then you would see this message.
193
+ `Uncaught TypeError: Cannot read property 'toUpperCase' of undefined` This
194
+ means the thing you are trying to render is not actually a react component.
195
+ Often is because the top level component name is wrong. For example if you are
196
+ in controller Foo and the method is `bar`, but you have named the component
197
+ Foo::Bars then you would see this message.
139
198
 
140
199
  ## Turning off Prerendering
141
200
 
142
- Sometimes its handy to switch off prerendering. Add `?no_prerender=1` ... to your url.
201
+ Sometimes its handy to switch off prerendering. Add `?no_prerender=1` ... to
202
+ your url.
143
203
 
144
204
 
145
205
  ## TODOS / Work arounds / Issues
146
206
 
147
207
  * Documentation
148
- * Should load the RubyRacer, or at least report an error if the RubyRacer is not present
208
+ * Should load the RubyRacer, or at least report an error if the RubyRacer is not
209
+ present
149
210
  * Get everything to autoload what it needs (i.e. much less config setup)
150
211
 
151
212
  ## Developing
@@ -165,8 +226,10 @@ To run the above examples project yourself:
165
226
 
166
227
  ## Contributions
167
228
 
168
- This project is still in early stage, so discussion, bug report and PR are really welcome :wink:.
169
- We check in often at https://gitter.im/zetachang/react.rb ask for @catmando as David is on leave right now.
229
+ This project is still in early stage, so discussion, bug report and PR are
230
+ really welcome :wink:. We check in often at
231
+ https://gitter.im/zetachang/react.rb ask for @catmando as David is on leave
232
+ right now.
170
233
 
171
234
  ## Contact
172
235
 
@@ -174,4 +237,5 @@ We check in often at https://gitter.im/zetachang/react.rb ask for @catmando.
174
237
 
175
238
  ## License
176
239
 
177
- In short, React.rb is available under the MIT license. See the LICENSE file for more info.
240
+ In short, React.rb is available under the MIT license. See the LICENSE file for
241
+ more info.
data/Rakefile CHANGED
@@ -7,11 +7,14 @@ require 'rspec/core/rake_task'
7
7
  require 'opal/rspec/rake_task'
8
8
 
9
9
  RSpec::Core::RakeTask.new('ruby:rspec')
10
- Opal::RSpec::RakeTask.new('opal:rspec')
10
+ Opal::RSpec::RakeTask.new('opal:rspec') do |s|
11
+ s.append_path 'spec/vendor'
12
+ s.index_path = 'spec/index.html.erb'
13
+ end
11
14
 
12
15
  task :test do
13
16
  Rake::Task['ruby:rspec'].invoke
14
- # Rake::Task['opal:rspec'].invoke
17
+ Rake::Task['opal:rspec'].invoke
15
18
  end
16
19
 
17
20
  require 'generators/reactive_ruby/test_app/test_app_generator'
@@ -1,9 +1,7 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- #gem 'opal'
4
3
  gem 'reactive-ruby', :path => '../..'
5
4
  gem 'sinatra'
6
5
  gem 'opal-jquery'
7
- #gem 'react-source'
8
6
  gem 'reactive-router'
9
7
  gem 'opal-rails'
@@ -1,9 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem 'therubyracer', platforms: :ruby
4
- gem 'react-rails' #, git: "https://github.com/catprintlabs/react-rails.git", :branch => 'isomorphic-methods-support' # you need this branch of react-rails
4
+ gem 'react-rails'
5
5
  gem 'opal-rails'
6
- # integrates opal with sprockets etc
6
+
7
+ # integrates opal with sprockets etc
7
8
  gem 'reactive-ruby', path: "../.."
8
9
 
9
10
  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
@@ -0,0 +1,11 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ # Require the gems listed in Gemfile, including any gems
6
+ # you've limited to :test, :development, or :production.
7
+ Bundler.require(*Rails.groups(assets: %w(development test)))
8
+
9
+ require 'reactive-ruby'
10
+
11
+ <%= application_definition %>
@@ -0,0 +1,2 @@
1
+ require 'components'
2
+ require 'react_ujs'
@@ -0,0 +1,3 @@
1
+ require 'opal'
2
+ require 'reactive-ruby'
3
+ require_tree './components'
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path("<%= gemfile_path %>", __FILE__)
3
+
4
+ ENV['BUNDLE_GEMFILE'] = gemfile
5
+ require 'bundler'
6
+ Bundler.setup
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
4
+ require File.expand_path('../../config/boot', __FILE__)
5
+ require 'rails/commands'
@@ -0,0 +1,11 @@
1
+ module Components
2
+ class HelloWorld
3
+ include React::Component
4
+
5
+ def render
6
+ div do
7
+ "Hello, World!".span
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module Components
2
+ class Todo
3
+ include React::Component
4
+ export_component
5
+
6
+ params do
7
+ requires :todo
8
+ end
9
+
10
+ def render
11
+ li { "#{params[:todo]}" }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,105 @@
1
+ require 'rails/generators/rails/app/app_generator'
2
+
3
+ module ReactiveRuby
4
+ class TestAppGenerator < ::Rails::Generators::Base
5
+ def self.source_paths
6
+ paths = self.superclass.source_paths
7
+ paths << File.expand_path('../templates', __FILE__)
8
+ paths.flatten
9
+ end
10
+
11
+ def remove_existing_app
12
+ remove_dir(test_app_path) if File.directory?(test_app_path)
13
+ end
14
+
15
+ def generate_test_app
16
+ opts = options.dup
17
+ opts[:database] = 'sqlite3' if opts[:database].blank?
18
+ opts[:force] = true
19
+ opts[:skip_bundle] = true
20
+
21
+ puts "Generating Test Rails Application..."
22
+ invoke ::Rails::Generators::AppGenerator,
23
+ [ File.expand_path(test_app_path, destination_root) ], opts
24
+ end
25
+
26
+ def configure_test_app
27
+ template 'boot.rb', "#{test_app_path}/config/boot.rb", force: true
28
+ template 'application.rb', "#{test_app_path}/config/application.rb", force: true
29
+ template 'assets/javascripts/application.rb',
30
+ "#{test_app_path}/app/assets/javascripts/application.rb", force: true
31
+ template 'assets/javascripts/components.rb',
32
+ "#{test_app_path}/app/views/components.rb", force: true
33
+ template 'views/components/hello_world.rb',
34
+ "#{test_app_path}/app/views/components/hello_world.rb", force: true
35
+ template 'views/components/todo.rb',
36
+ "#{test_app_path}/app/views/components/todo.rb", force: true
37
+ end
38
+
39
+ def clean_superfluous_files
40
+ inside test_app_path do
41
+ remove_file '.gitignore'
42
+ remove_file 'doc'
43
+ remove_file 'Gemfile'
44
+ remove_file 'lib/tasks'
45
+ remove_file 'app/assets/images/rails.png'
46
+ remove_file 'app/assets/javascripts/application.js'
47
+ remove_file 'public/index.html'
48
+ remove_file 'public/robots.txt'
49
+ remove_file 'README.rdoc'
50
+ remove_file 'test'
51
+ remove_file 'vendor'
52
+ remove_file 'spec'
53
+ end
54
+ end
55
+
56
+ def configure_opal_rspec
57
+ inject_into_file "#{test_app_path}/config/application.rb",
58
+ after: /class Application < Rails::Application/, verbose: true do
59
+ %Q[
60
+ config.opal.method_missing = true
61
+ config.opal.optimized_operators = true
62
+ config.opal.arity_check = false
63
+ config.opal.const_missing = true
64
+ config.opal.dynamic_require_severity = :ignore
65
+ config.opal.enable_specs = true
66
+ config.opal.spec_location = 'spec-opal'
67
+ ]
68
+ end
69
+ end
70
+
71
+ protected
72
+
73
+ def application_definition
74
+ @application_definition ||= begin
75
+ test_application_contents
76
+ end
77
+ end
78
+ alias :store_application_definition! :application_definition
79
+
80
+ private
81
+
82
+ def test_app_path
83
+ 'spec/test_app'
84
+ end
85
+
86
+ def test_application_path
87
+ File.expand_path("#{test_app_path}/config/application.rb",
88
+ destination_root)
89
+ end
90
+
91
+ def test_application_contents
92
+ return unless File.exists?(test_application_path) && !options[:pretend]
93
+ contents = File.read(test_application_path)
94
+ contents[(contents.index("module #{module_name}"))..-1]
95
+ end
96
+
97
+ def module_name
98
+ 'TestApp'
99
+ end
100
+
101
+ def gemfile_path
102
+ '../../../../Gemfile'
103
+ end
104
+ end
105
+ end