hyper-spec 1.0.alpha1.5 → 1.0.0.lap28

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c17257af4d7b13916648e6ba8a495f1ca0b2f5a300e8ea96e7490c47cd696691
4
- data.tar.gz: 6a823c91fd6d46c1c086296316af229b993761bee436e4b3940371b0ae4ecd03
3
+ metadata.gz: 1b567b6e5e1eb4555bcf41ada038f247a2f83c346be6d21593f9777f9b73dfb8
4
+ data.tar.gz: c1691e64e39fad1442c94782f6e3094460b635bce026767b3ece63d757d0a24d
5
5
  SHA512:
6
- metadata.gz: b7eb46d260a9025424755c1248500f8ab7b79956385149507b7518a40d1e38848dfdfac9eb19fd8661b6022d37aa6d627d21483e90251d52044cadad07b5533a
7
- data.tar.gz: 20b3e256b12ad4c3ef08b0ac371b2bb8ce3b6dc4a7498e4a249e15e32243f339780eaaabf5e952c6c5b64180846bf2eea71a93c98d6ea599c1f64b447d0da1c0
6
+ metadata.gz: eeaa28e71f46802e74d4d2ecaf6405f8a9518e030d371c7397ede62976c66fe309be3a8f3a5b1434c5e56765ad73117e9660618bcc158830d9eb485a7fc157ea
7
+ data.tar.gz: 93fb42f8f0212cd415dddfd17e7d7ee235f1c2fb470edb1957bd8d8c4bf3b04a50f7290c450374fd5edd5c915a3e16848b314e79df13f4945d1a44801c3256a3
data/.gitignore CHANGED
@@ -13,6 +13,7 @@ capybara-*.html
13
13
  **.orig
14
14
  rerun.txt
15
15
  pickle-email-*.html
16
+ Gemfile.lock
16
17
 
17
18
  # TODO Comment out these rules if you are OK with secrets being uploaded to the repo
18
19
  config/initializers/secret_token.rb
@@ -52,7 +53,3 @@ bower.json
52
53
 
53
54
  # ignore Idea files
54
55
  .idea
55
-
56
- # ignore Gemfile.locks https://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
57
- /spec/test_app/Gemfile.lock
58
- /Gemfile.lock
@@ -0,0 +1,107 @@
1
+ Style/BlockDelimiters:
2
+ EnforcedStyle: line_count_based
3
+ SupportedStyles:
4
+ # The `line_count_based` style enforces braces around single line blocks and
5
+ # do..end around multi-line blocks.
6
+ - line_count_based
7
+ # The `semantic` style enforces braces around functional blocks, where the
8
+ # primary purpose of the block is to return a value and do..end for
9
+ # procedural blocks, where the primary purpose of the block is its
10
+ # side-effects.
11
+ #
12
+ # This looks at the usage of a block's method to determine its type (e.g. is
13
+ # the result of a `map` assigned to a variable or passed to another
14
+ # method) but exceptions are permitted in the `ProceduralMethods`,
15
+ # `FunctionalMethods` and `IgnoredMethods` sections below.
16
+ - semantic
17
+ # The `braces_for_chaining` style enforces braces around single line blocks
18
+ # and do..end around multi-line blocks, except for multi-line blocks whose
19
+ # return value is being chained with another method (in which case braces
20
+ # are enforced).
21
+ - braces_for_chaining
22
+ ProceduralMethods:
23
+ # Methods that are known to be procedural in nature but look functional from
24
+ # their usage, e.g.
25
+ #
26
+ # time = Benchmark.realtime do
27
+ # foo.bar
28
+ # end
29
+ #
30
+ # Here, the return value of the block is discarded but the return value of
31
+ # `Benchmark.realtime` is used.
32
+ - benchmark
33
+ - bm
34
+ - bmbm
35
+ - create
36
+ - each_with_object
37
+ - measure
38
+ - new
39
+ - realtime
40
+ - tap
41
+ - with_object
42
+ FunctionalMethods:
43
+ # Methods that are known to be functional in nature but look procedural from
44
+ # their usage, e.g.
45
+ #
46
+ # let(:foo) { Foo.new }
47
+ #
48
+ # Here, the return value of `Foo.new` is used to define a `foo` helper but
49
+ # doesn't appear to be used from the return value of `let`.
50
+ - let
51
+ - let!
52
+ - subject
53
+ - watch
54
+ IgnoredMethods:
55
+ # Methods that can be either procedural or functional and cannot be
56
+ # categorised from their usage alone, e.g.
57
+ #
58
+ # foo = lambda do |x|
59
+ # puts "Hello, #{x}"
60
+ # end
61
+ #
62
+ # foo = lambda do |x|
63
+ # x * 100
64
+ # end
65
+ #
66
+ # Here, it is impossible to tell from the return value of `lambda` whether
67
+ # the inner block's return value is significant.
68
+ - lambda
69
+ - proc
70
+ - it
71
+
72
+ Style/Documentation:
73
+ Description: 'Document classes and non-namespace modules.'
74
+ Enabled: false
75
+ Exclude:
76
+ - 'spec/**/*'
77
+ - 'test/**/*'
78
+
79
+ # Multi-line method chaining should be done with trailing dots.
80
+ Style/DotPosition:
81
+ EnforcedStyle: leading
82
+ SupportedStyles:
83
+ - leading
84
+ - trailing
85
+
86
+ Style/FrozenStringLiteralComment:
87
+ Description: >-
88
+ Add the frozen_string_literal comment to the top of files
89
+ to help transition from Ruby 2.3.0 to Ruby 3.0.
90
+ Enabled: false
91
+
92
+ Style/MultilineBlockChain:
93
+ Description: 'Avoid multi-line chains of blocks.'
94
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks'
95
+ Enabled: false
96
+
97
+ Style/MutableConstant:
98
+ Description: 'Do not assign mutable objects to constants.'
99
+ Enabled: false
100
+
101
+ Metrics/AbcSize:
102
+ # The ABC size is a calculated magnitude, so this number can be a Fixnum or
103
+ # a Float.
104
+ Max: 20
105
+
106
+ Metrics/LineLength:
107
+ Max: 100
@@ -1,26 +1,21 @@
1
- dist: trusty
2
1
  language: ruby
3
- cache: bundler
4
2
  rvm:
5
- - 2.4.4
6
- - 2.5.1
7
- - ruby-head
3
+ - ruby
8
4
  env:
9
- - DRIVER=google-chrome TZ=Europe/Berlin
10
- matrix:
11
- fast_finish: true
12
- allow_failures:
13
- - rvm: ruby-head
5
+ - DRIVER=travis HYPER_DEV_GEM_SOURCE="https://gems.ruby-hyperloop.org" TZ=Europe/Berlin
14
6
  before_install:
15
- - if [[ "$DRIVER" == "google-chrome" ]]; then wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -; fi
16
- - if [[ "$DRIVER" == "google-chrome" ]]; then echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list; fi
17
- - if [[ "$DRIVER" == "google-chrome" ]]; then sudo apt-get update -qq && sudo apt-get install -qq -y google-chrome-stable; fi
7
+ - sudo apt-get install -y fonts-liberation
8
+ - wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
9
+ - sudo dpkg -i google-chrome*.deb
18
10
  - gem install bundler
19
11
  before_script:
20
- - bundle install --jobs=3 --retry=3
21
- - if [[ "$DRIVER" == "google-chrome" ]]; then bundle exec chromedriver-update; fi
22
- - if [[ "$DRIVER" == "google-chrome" ]]; then ls -lR ~/.chromedriver-helper/; fi
23
- - if [[ "$DRIVER" == "google-chrome" ]]; then bundle exec chromedriver --version; fi
24
- - if [[ "$DRIVER" == "google-chrome" ]]; then google-chrome --version; fi
25
- - if [[ "$DRIVER" == "google-chrome" ]]; then which google-chrome; fi
26
- script: bundle exec rspec
12
+ - cd spec/test_app
13
+ - bundle update
14
+ - cd ../../
15
+ - chromedriver-update
16
+ - ls -lR ~/.chromedriver-helper/
17
+ script:
18
+ - bundle exec rake spec
19
+ gemfile:
20
+ - gemfiles/opal_0_11_react-rails_2_4.gemfile
21
+
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at mitch@catprint.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile CHANGED
@@ -1,7 +1,3 @@
1
1
  source 'https://rubygems.org'
2
- gem 'hyper-component', path: '../hyper-component'
3
- gem 'hyper-store', path: '../hyper-store'
4
- gem 'hyper-state', path: '../hyper-state'
5
- gem 'hyperstack-config', path: '../hyperstack-config'
6
- #gem 'unparser', path: '../../../unparser'
2
+ gem "opal-jquery", git: "https://github.com/opal/opal-jquery.git", branch: "master"
7
3
  gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 catmando
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,380 @@
1
+ # HyperSpec
2
+
3
+ [![Build Status](https://travis-ci.org/ruby-hyperloop/hyper-spec.svg?branch=master)](https://travis-ci.org/ruby-hyperloop/hyper-spec)
4
+
5
+ With HyperSpec you can run *isomorphic* specs for all your Hyperloop code using RSpec. Everything runs as standard RSpec test specs.
6
+
7
+ For example if you have a component like this:
8
+
9
+ ```ruby
10
+ class SayHello < React::Component::Base
11
+ param :name
12
+ render(DIV) do
13
+ "Hello there #{params.name}"
14
+ end
15
+ end
16
+ ```
17
+
18
+ Your test spec would look like this:
19
+
20
+ ```ruby
21
+ describe 'SayHello', js: true do
22
+ it 'has the correct content' do
23
+ mount "SayHello", name: 'Fred'
24
+ expect(page).to have_content('Hello there Fred')
25
+ end
26
+ end
27
+ ```
28
+
29
+ The `mount` method will setup a blank client window, and *mount* the named component in the window, passing any parameters.
30
+
31
+ Notice that the spec will need a client environment so we must set `js: true`.
32
+
33
+ The `mount` method can also take a block which will be recompiled and set to the client before mounting the component. You can place any client side code in the mount block including the definition of components.
34
+
35
+ ```ruby
36
+ describe "the mount's code block", js: true do
37
+ it 'will be recompiled on the client' do
38
+ mount 'ShowOff' do
39
+ class ShowOff < React::Component::Base
40
+ render(DIV) { 'Now how cool is that???' }
41
+ end
42
+ end
43
+ expect(page).to have_content('Now how cool is that???' )
44
+ end
45
+ end
46
+ ```
47
+
48
+ ## Why?
49
+
50
+ Hyperloop wants to make the server-client divide as transparent to the developer as practical. Given this, it makes sense that the testing should also be done with as little concern for client versus server.
51
+
52
+ HyperSpec allows you to directly use tools like FactoryBot (or Hyperloop Operations) to setup some test data, then run a spec to make sure that a component correctly displays, or modifies that data. You can use Timecop to manipulate time and keep in sync between the server and client. This makes testing easier and more realistic without writing a lot of redundant code.
53
+
54
+
55
+ ## Installation
56
+
57
+ Add this line to your application's Gemfile in the test section:
58
+
59
+ ```ruby
60
+ gem 'hyper-spec'
61
+ ```
62
+
63
+ Execute:
64
+
65
+ $ bundle install
66
+
67
+ and then in your spec_helper.rb file
68
+
69
+ ```ruby
70
+ require 'hyper-spec'
71
+ ```
72
+
73
+ You will also need to install selenium, poltergeist and firefox version **46.0.1** (ff latest still does not play well with selenium).
74
+
75
+ Sadly at this time the selenium chrome driver does not play nicely with Opal, so you can't use Chrome. We are working on getting rid of the whole selenium business. Stay tuned.
76
+
77
+ ## Environment Variables
78
+
79
+ You can set `DRIVER` to `ff` to run the client in Firefox and see what is going on. By default tests will run in poltergeist which is quicker, but harder to debug problems.
80
+
81
+ ```
82
+ DRIVER=ff bundle exec rspec
83
+ ```
84
+
85
+ ## Spec Helpers
86
+
87
+ HyperSpec adds the following spec helpers to your test environment
88
+
89
+ + `mount`
90
+ + `client_option` and `client_options`
91
+ + `on_client`
92
+ + `isomorphic`
93
+ + `evaluate_ruby`
94
+ + `expect_evaluate_ruby`
95
+ + `expect_promise`
96
+ + call back and event history methods
97
+ + `pause`
98
+ + `attributes_on_client`
99
+ + `size_window`
100
+ + `add_class`
101
+
102
+ #### The `mount` Method
103
+
104
+ `mount` takes the name of a component, prepares an empty test window, and mounts the named component in the window.
105
+ You may give a block to `mount` which will be recompiled on the client, and run *before* mounting. This means that the component
106
+ mounted may be actually defined in the block, which is useful for setting up top level wrapper components, which will invoke your component under test. You can also modify existing components for white box testing, or local fixture data, constants, etc.
107
+
108
+ `mount` may also be given a hash of the parameters to be passed to the component.
109
+
110
+ ```ruby
111
+ mount 'Display', test: 123 do
112
+ class Display < React::Component::Base
113
+ param :test
114
+ render(DIV) { params.test.to_s }
115
+ end
116
+ end
117
+ ```
118
+
119
+ #### The `client_option` Method
120
+
121
+ There are several options that control the mounting process. Use `client_option` (or `client_options`) before accessing any client side to set any of these options:
122
+
123
+ + `render_on`: `:server_only`, `:client_only`, or `:both`, default is client_only.
124
+ + `layout`: specify the layout to be used. Default is :none.
125
+ + `style_sheet`: specify the name of the style sheet to be loaded. Defaults to the application stylesheet.
126
+ + `javascript`: specify the name of the javascript asset file to be loaded. Defaults to the application js file.
127
+
128
+ For example:
129
+
130
+ ```ruby
131
+ it "can be rendered server side only" do
132
+ client_option render_on: :server_only
133
+ mount 'SayHello', name: 'George'
134
+ expect(page).to have_content('Hello there George')
135
+ # Server only means no code is downloaded to the client
136
+ expect(evaluate_script('typeof React')).to eq('undefined')
137
+ end
138
+ ```
139
+
140
+ If you need to pull in alternative style sheets and javascript files, the recommended way to do this is to
141
+
142
+ 1. Add them to a `specs/assets/stylesheets` and `specs/assets/javascripts` directory and
143
+ 2. Add the following line to your `config/environment/test.rb` file:
144
+ ```ruby
145
+ config.assets.paths << ::Rails.root.join('spec', 'assets', 'stylesheets').to_s
146
+ config.assets.paths << ::Rails.root.join('spec', 'assets', 'javascripts').to_s
147
+ ```
148
+
149
+ This way you will not pollute your application with these 'test only' files.
150
+
151
+ *The javascript spec asset files can be `.rb` files and contain ruby code as well. See the specs for examples!*
152
+
153
+ #### The `on_client` Method
154
+
155
+ `on_client` takes a block and compiles and runs it on the client. This is useful in setting up test constants and client only fixtures.
156
+
157
+ Note that `on_client` needs to *proceed* any calls to `mount`, `evaluate_ruby`, `expect_evaluate_ruby` or `expect_promise` as these methods will initiate the client load process.
158
+
159
+ #### The `isomorphic` Method
160
+
161
+ Similar to `on_client` but the block is *also* run on the server. This is useful for setting constants shared by both client and server, and modifying behavior of isomorphic classes such as ActiveRecord models, and HyperOperations.
162
+
163
+ ```ruby
164
+ isomorphic do
165
+ class SomeModel < ActiveRecord::Base
166
+ def fake_attribute
167
+ 12
168
+ end
169
+ end
170
+ end
171
+ ```
172
+
173
+ #### The `evaluate_ruby` Method
174
+
175
+ Takes either a string or a block, dynamically compiles it, downloads it to the client and runs it.
176
+
177
+ ```ruby
178
+ evaluate_ruby do
179
+ i = 12
180
+ i * 2
181
+ end
182
+ # returns 24
183
+
184
+ isomorphic do
185
+ def factorial(n)
186
+ n == 1 ? 1 : n * factorial(n-1)
187
+ end
188
+ end
189
+
190
+ expect(evaluate_ruby("factorial(5)")).to eq(factorial(5))
191
+ ```
192
+
193
+ `evaluate_ruby` can also be very useful for debug. Set a breakpoint in your test, then use `evaluate_ruby` to interrogate the state of the client.
194
+
195
+ #### The `expect_evaluate_ruby` Method
196
+
197
+ Combines expect and evaluate methods:
198
+
199
+ ```ruby
200
+ expect_evaluate_ruby do
201
+ i = 1
202
+ 5.times { |n| i = i*n }
203
+ i
204
+ end.to eq(120)
205
+ ```
206
+
207
+ #### The `expect_promise` Method
208
+
209
+ Works like `expect_evaluate_ruby` but is used with promises. `expect_promise` will hang until the promise resolves and then return to the results.
210
+
211
+ ```ruby
212
+ expect_promise do
213
+ Promise.new.tap do |p|
214
+ after(2) { p.resolve('hello') }
215
+ end
216
+ end.to eq('hello')
217
+ ```
218
+
219
+ #### Call Back and Event History Methods
220
+
221
+ HyperReact components can *generate* events and perform callbacks. HyperSpec provides methods to test if an event or callback was made.
222
+
223
+ ```ruby
224
+ mount 'CallBackOnEveryThirdClick' do
225
+ class CallBackOnEveryThirdClick < React::Component::Base
226
+ param :click3, type: Proc
227
+ def increment_click
228
+ @clicks ||= 0
229
+ @clicks = (@clicks + 1)
230
+ params.click3(@clicks) if @clicks % 3 == 0
231
+ end
232
+ render do
233
+ DIV(class: :tp_clicker) { "click me" }
234
+ .on(:click) { increment_click }
235
+ end
236
+ end
237
+ end
238
+
239
+ 7.times { page.click('#tp_clicker') }
240
+ expect(callback_history_for(:click3)).to eq([[3], [6]])
241
+ ```
242
+
243
+ Note that for things to work, the param must be declared as a `type: Proc`.
244
+
245
+ + `callback_history_for`: the entire history given as an array of arrays
246
+ + `last_callback_for`: same as `callback_history_for(xxx).last`
247
+ + `clear_callback_history_for`: clears the array (userful for repeating test variations without remounting)
248
+ + `event_history_for, last_event_for, clear_event_history_for`: same but for events.
249
+
250
+ #### The `pause` Method
251
+
252
+ For debugging. Everything stops, until you type `go()` in the client console. Running binding.pry also has this effect, and is often sufficient, however it will also block the server from responding unless you have a multithreaded server.
253
+
254
+ #### The `attributes_on_client` Method
255
+
256
+ *This feature is currently untested - use at your own risk.*
257
+
258
+ This reads the value of active record model attributes on the client.
259
+
260
+ In other words the method `attributes_on_client` is added to all ActiveRecord models. You then take a model you have instance of on the server, and by passing the Capybara page object, you get back the attributes for that same model instance, currently on the client.
261
+
262
+ ```ruby
263
+ expect(some_record_on_server.attributes_on_client(page)[:fred]).to eq(12)
264
+ ```
265
+
266
+ Note that after persisting a record the client and server will be synced so this is mainly useful for debug or in rare cases where it is important to interrogate the value on the client before its persisted.
267
+
268
+ #### The `size_window` Method
269
+
270
+ Sets the size of the test window. You can say:
271
+ `size_window(width, height)` or pass one of the following standard sizes: to one of the following standard sizes:
272
+
273
+ + small: 480 X 320
274
+ + mobile: 640 X 480
275
+ + tablet: 960 X 640
276
+ + large: 1920 X 6000
277
+ + default: 1024 X 768
278
+
279
+ example: `size_window(:mobile)`
280
+
281
+ You can also modify the standard sizes with `:portrait`
282
+
283
+ example: `size_window(:table, :portrait)`
284
+
285
+ You can also specify the size by providing the width and height.
286
+
287
+ example: `size_window(600, 600)`
288
+
289
+ size_window with no parameters is the same as `size_window(:default)`
290
+
291
+ Typically you will use this in a `before(:each)` or `before(:step)` block
292
+
293
+ #### The `add_class` Method
294
+
295
+ Sometimes it's useful to change styles during testing (mainly for debug so that changes on screen are visible.)
296
+
297
+ The `add_class` method takes a class name (as a symbol or string), and hash representing the style.
298
+
299
+ ```ruby
300
+ it "can add classes during testing" do
301
+ add_class :some_class, borderStyle: :solid
302
+ mount 'StyledDiv' do
303
+ class StyledDiv < React::Component::Base
304
+ render(DIV, id: 'hello', class: 'some_class') do
305
+ 'Hello!'
306
+ end
307
+ end
308
+ end
309
+ expect(page.find('#hello').native.css_value('border-right-style')).to eq('solid')
310
+ end
311
+ ```
312
+
313
+ ## Integration with the Steps gem
314
+
315
+ The [rspec-steps gem](https://github.com/LRDesign/rspec-steps) can be useful in doing client side testing. Without rspec-steps, each test spec will cause a reload of the browser window. While this insures that each test runs in a clean environment, it is typically not necessary and can really slow down testing.
316
+
317
+ The rspec-steps gem will run each test without reloading the window, which is usually fine.
318
+
319
+ Checkout the rspec-steps example in the `hyper_spec.rb` file for an example.
320
+
321
+ *Note that hopefully in the near future we are going to build a custom capybara driver that will just directly talk to Hyperloop on the client side. Once this is in place these troubles should go away! - Volunteers welcome to help!*
322
+
323
+ ## Timecop Integration
324
+
325
+ HyperSpec is integrated with [Timecop](https://github.com/travisjeffery/timecop) to freeze, move and speed up time. The client and server times will be kept in sync when you use any these Timecop methods:
326
+
327
+ + `freeze`: Freezes time at the specified point in time (default is Time.now)
328
+ + `travel`: Time runs normally forward from the point specified.
329
+ + `scale`: Like travel but times runs faster.
330
+ + `return`: Return to normal system time.
331
+
332
+ For example:
333
+ ```ruby
334
+ Timecop.freeze # freeze time at current time
335
+ # ... test some stuff
336
+ Timecop.freeze Time.now+10.minutes # move time forward 10 minutes
337
+ # ... check to see if expected events happened etc
338
+ Timecop.return
339
+ ```
340
+
341
+ ```ruby
342
+ Timecop.scale 60, Time.now-1.year do
343
+ # Time will begin 1 year ago but advance 60 times faster than normal
344
+ sleep 10
345
+ # still sleeps for 10 seconds YOUR time, but server and client will
346
+ # think 10 minutes have passed
347
+ end
348
+ # no need for Timecop.return if using the block style
349
+ ```
350
+
351
+ See the Timecop [README](https://github.com/travisjeffery/timecop/blob/master/README.markdown) for more details.
352
+
353
+ There is one confusing thing to note: On the server if you `sleep` then you will sleep for the specified number of seconds when viewed *outside* of the test. However inside the test environment if you look at Time.now, you will see it advancing according to the scale factor. Likewise if you have a `after` or `every` block on the client, you will wait according to *simulated* time.
354
+
355
+ ## Common Problems
356
+
357
+ If you are getting failures on Poltergeist but not Firefox, make sure you are not requiring `browser` in your components.rb.
358
+ Requiring `browser/interval` or `browser/delay` is okay.
359
+
360
+ ## Development
361
+
362
+ After checking out the repo, run bundle install and you should be good to go.
363
+
364
+ Tests are run either by running `rake` or for more control:
365
+
366
+ ```
367
+ DRIVER=ff bundle exec rspec spec/hyper_spec.rb
368
+ ```
369
+
370
+ where DRIVER can be either `ff` (firefox) or `pg` (poltergeist - default).
371
+
372
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
373
+
374
+ ## Contributing
375
+
376
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/hyper-spec. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
377
+
378
+ ## License
379
+
380
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -5,6 +5,8 @@ RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  namespace :spec do
7
7
  task :prepare do
8
+ sh %{bundle update}
9
+ sh %{cd spec/test_app; bundle update}
8
10
  end
9
11
  end
10
12
 
@@ -0,0 +1,3 @@
1
+ [dciy.commands]
2
+ prepare = ["rake spec:prepare"]
3
+ cibuild = ["bundle exec rake"]
@@ -25,10 +25,8 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
25
25
  spec.require_paths = ['lib']
26
26
 
27
27
  spec.add_dependency 'capybara'
28
- spec.add_dependency 'chromedriver-helper', '1.2.0'
29
- spec.add_dependency 'libv8', '~> 6.7.0'
28
+ spec.add_dependency 'chromedriver-helper'
30
29
  spec.add_dependency 'method_source'
31
- spec.add_dependency 'mini_racer', '~> 0.2.4'
32
30
  spec.add_dependency 'opal', '>= 0.11.0', '< 0.12.0'
33
31
  spec.add_dependency 'parser', '>= 2.3.3.1'
34
32
  spec.add_dependency 'pry'
@@ -36,17 +34,18 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
36
34
  spec.add_dependency 'selenium-webdriver'
37
35
  spec.add_dependency 'timecop', '~> 0.8.1'
38
36
  spec.add_dependency 'uglifier'
39
- spec.add_dependency 'unparser', '>= 0.4.2' # 0.4 is incompatible
37
+ spec.add_dependency 'unparser'
40
38
  spec.add_dependency 'webdrivers'
41
39
 
42
- spec.add_development_dependency 'bundler', ['>= 1.17.3', '< 2.1']
43
- spec.add_development_dependency 'hyper-component', HyperSpec::VERSION
40
+ spec.add_development_dependency 'bundler'
41
+ spec.add_development_dependency 'hyper-react', HyperSpec::VERSION
42
+ spec.add_development_dependency 'mini_racer', '~> 0.1.15'
44
43
  spec.add_development_dependency 'opal-browser', '~> 0.2.0'
45
44
  spec.add_development_dependency 'opal-rails', '~> 0.9.4'
46
- spec.add_development_dependency 'pry-rescue'
47
45
  spec.add_development_dependency 'puma'
48
46
  spec.add_development_dependency 'rails', '>= 4.0.0'
49
47
  spec.add_development_dependency 'rake'
48
+ spec.add_development_dependency 'pry-rescue'
50
49
  spec.add_development_dependency 'react-rails', '>= 2.3.0', '< 2.5.0'
51
50
  spec.add_development_dependency 'rspec-collection_matchers'
52
51
  spec.add_development_dependency 'rspec-expectations'
@@ -17,11 +17,11 @@ RSpec.configure do |config|
17
17
  config.add_setting :debugger_width, default: nil
18
18
 
19
19
  config.before(:each) do
20
- Hyperstack.class_eval do
20
+ Hyperloop.class_eval do
21
21
  def self.on_server?
22
22
  true
23
23
  end
24
- end if defined?(Hyperstack)
24
+ end if defined?(Hyperloop)
25
25
  # for compatibility with HyperMesh
26
26
  HyperMesh.class_eval do
27
27
  def self.on_server?
@@ -62,14 +62,6 @@ RSpec.configure do |_config|
62
62
  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
63
63
  end
64
64
 
65
- Capybara.register_driver :chrome_headless_docker_travis do |app|
66
- options = ::Selenium::WebDriver::Chrome::Options.new
67
- options.add_argument('--headless')
68
- options.add_argument('--no-sandbox')
69
- options.add_argument('--disable-dev-shm-usage')
70
- Capybara::Selenium::Driver.new(app, browser: :chrome, :driver_path => "/usr/lib/chromium-browser/chromedriver", options: options)
71
- end
72
-
73
65
  Capybara.register_driver :firefox do |app|
74
66
  Capybara::Selenium::Driver.new(app, browser: :firefox)
75
67
  end
@@ -100,7 +92,6 @@ RSpec.configure do |_config|
100
92
  when 'firefox' then :firefox
101
93
  when 'headless' then :selenium_chrome_headless
102
94
  when 'safari' then :safari
103
- when 'travis' then :chrome_headless_docker_travis
104
95
  else :selenium_chrome_headless
105
96
  end
106
97
 
@@ -1,16 +1,13 @@
1
1
  # see component_test_helpers_spec.rb for examples
2
2
  require 'parser/current'
3
3
  require 'unparser'
4
- require 'hyper-spec/unparser_patch'
5
4
  require 'method_source'
6
5
  require_relative '../../lib/hyper-spec/time_cop.rb'
7
6
 
8
- Parser::Builders::Default.emit_procarg0 = true
9
-
10
7
  module HyperSpec
11
8
  module ComponentTestHelpers
12
9
  TOP_LEVEL_COMPONENT_PATCH =
13
- Opal.compile(File.read(File.expand_path('../../sources/top_level_rails_component.rb', __FILE__)))
10
+ Opal.compile(File.read(File.expand_path('../../react/top_level_rails_component.rb', __FILE__)))
14
11
  TIME_COP_CLIENT_PATCH =
15
12
  Opal.compile(File.read(File.expand_path('../../hyper-spec/time_cop.rb', __FILE__))) +
16
13
  "\n#{File.read(File.expand_path('../../sources/lolex.js', __FILE__))}"
@@ -27,11 +24,11 @@ module HyperSpec
27
24
 
28
25
  def build_test_url_for(controller)
29
26
  unless controller
30
- unless defined?(::HyperstackTestController)
31
- Object.const_set('HyperstackTestController', Class.new(::ActionController::Base))
27
+ unless defined?(::ReactTestController)
28
+ Object.const_set('ReactTestController', Class.new(::ActionController::Base))
32
29
  end
33
30
 
34
- controller = ::HyperstackTestController
31
+ controller = ::ReactTestController
35
32
  end
36
33
 
37
34
  route_root = controller.name.gsub(/Controller$/, '').underscore
@@ -111,8 +108,7 @@ module HyperSpec
111
108
  if block
112
109
  str = "#{str}\n#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.last}"
113
110
  end
114
- js = Opal.compile(str).gsub("// Prepare super implicit arguments\n", "")
115
- .delete("\n").gsub('(Opal);', '(Opal)')
111
+ js = Opal.compile(str).delete("\n").gsub('(Opal);', '(Opal)')
116
112
  # workaround for firefox 58 and geckodriver 0.19.1, because firefox is unable to find .$to_json:
117
113
  # JSON.parse(evaluate_script("(function(){var a=Opal.Array.$new(); a[0]=#{js}; return a.$to_json();})();"), opts).first
118
114
  JSON.parse(evaluate_script("[#{js}].$to_json()"), opts).first
@@ -220,9 +216,8 @@ module HyperSpec
220
216
  }
221
217
  end
222
218
  end
223
- class Hyperstack::Internal::Component::TestDummy
224
- include Hyperstack::Component
225
- render {}
219
+ class React::Component::HyperTestDummy < React::Component::Base
220
+ def render; end
226
221
  end
227
222
  #{@client_code}
228
223
  #{Unparser.unparse(Parser::CurrentRuby.parse(block.source).children.last) if block}
@@ -230,7 +225,7 @@ module HyperSpec
230
225
  opts[:code] = Opal.compile(block_with_helpers)
231
226
  end
232
227
 
233
- component_name ||= 'Hyperstack::Internal::Component::TestDummy'
228
+ component_name ||= 'React::Component::HyperTestDummy'
234
229
  ::Rails.cache.write(test_url, [component_name, params, opts])
235
230
  test_code_key = "hyper_spec_prerender_test_code.js"
236
231
  @@original_server_render_files ||= ::Rails.configuration.react.server_renderer_options[:files]
@@ -245,16 +240,16 @@ module HyperSpec
245
240
  ::React::ServerRendering.reset_pool # make sure contexts are reloaded so they dont use code from cache, as the rails filewatcher doesnt look for cache changes
246
241
  end
247
242
  end
243
+ Lolex.init(self, client_options[:time_zone], client_options[:clock_resolution])
248
244
  visit test_url
249
245
  wait_for_ajax unless opts[:no_wait]
250
246
  page.instance_variable_set('@hyper_spec_mounted', true)
251
- Lolex.init(self, client_options[:time_zone], client_options[:clock_resolution])
252
247
  end
253
248
 
254
249
  [:callback_history_for, :last_callback_for, :clear_callback_history_for,
255
250
  :event_history_for, :last_event_for, :clear_event_history_for].each do |method|
256
251
  define_method(method) do |event_name|
257
- evaluate_ruby("Hyperstack::Internal::Component::TopLevelRailsComponent.#{method}('#{event_name}')")
252
+ evaluate_ruby("React::TopLevelRailsComponent.#{method}('#{event_name}')")
258
253
  end
259
254
  end
260
255
 
@@ -282,11 +277,11 @@ module HyperSpec
282
277
  def pause(message = nil)
283
278
  if message
284
279
  puts message
285
- page.evaluate_script "console.log('#{message} (type go() to continue)')"
280
+ page.evaluate_ruby "puts #{message.inspect}.to_s + ' (type go() to continue)'"
286
281
  end
287
282
 
288
283
  page.evaluate_script('window.hyper_spec_waiting_for_go = true')
289
- page.evaluate_script('go = function() {window.hyper_spec_waiting_for_go = false}')
284
+
290
285
  loop do
291
286
  sleep 0.25
292
287
  break unless page.evaluate_script('window.hyper_spec_waiting_for_go')
@@ -1,3 +1,3 @@
1
1
  module HyperSpec
2
- VERSION = '1.0.alpha1.5'
2
+ VERSION = '1.0.0.lap28'
3
3
  end
@@ -12,9 +12,9 @@ module HyperSpec
12
12
  def running?
13
13
  jscode = <<-CODE
14
14
  (function() {
15
- if (typeof Opal !== "undefined" && Opal.Hyperstack !== undefined) {
15
+ if (typeof Opal !== "undefined" && Opal.Hyperloop !== undefined) {
16
16
  try {
17
- return Opal.Hyperstack.$const_get("HTTP")["$active?"]();
17
+ return Opal.Hyperloop.$const_get("HTTP")["$active?"]();
18
18
  } catch(err) {
19
19
  if (typeof jQuery !== "undefined" && jQuery.active !== undefined) {
20
20
  return (jQuery.active > 0);
@@ -39,7 +39,7 @@ module HyperSpec
39
39
  rescue Capybara::NotSupportedByDriverError
40
40
  true
41
41
  rescue Exception => e
42
- e.message == 'either jQuery or Hyperstack::HTTP is not defined'
42
+ e.message == 'either jQuery or Hyperloop::HTTP is not defined'
43
43
  end
44
44
  end
45
45
  end
@@ -0,0 +1,94 @@
1
+ module React
2
+ class TopLevelRailsComponent
3
+ class << self
4
+ attr_accessor :event_history
5
+
6
+ def callback_history_for(proc_name)
7
+ event_history[proc_name]
8
+ end
9
+
10
+ def last_callback_for(proc_name)
11
+ event_history[proc_name].last
12
+ end
13
+
14
+ def clear_callback_history_for(proc_name)
15
+ event_history[proc_name] = []
16
+ end
17
+
18
+ def event_history_for(event_name)
19
+ event_history["_on#{event_name.event_camelize}"]
20
+ end
21
+
22
+ def last_event_for(event_name)
23
+ event_history["_on#{event_name.event_camelize}"].last
24
+ end
25
+
26
+ def clear_event_history_for(event_name)
27
+ event_history["_on#{event_name.event_camelize}"] = []
28
+ end
29
+ end
30
+
31
+ def component
32
+ return @component if @component
33
+ paths_searched = []
34
+ component = nil
35
+ if params.component_name.start_with?('::')
36
+ # if absolute path of component is given, look it up and fail if not found
37
+ paths_searched << params.component_name
38
+ component = begin
39
+ Object.const_get(params.component_name)
40
+ rescue NameError
41
+ nil
42
+ end
43
+ else
44
+ # if relative path is given, look it up like this
45
+ # 1) we check each path + controller-name + component-name
46
+ # 2) if we can't find it there we check each path + component-name
47
+ # if we can't find it we just try const_get
48
+ # so (assuming controller name is Home)
49
+ # ::Foo::Bar will only resolve to some component named ::Foo::Bar
50
+ # but Foo::Bar will check (in this order) ::Home::Foo::Bar, ::Components::Home::Foo::Bar, ::Foo::Bar, ::Components::Foo::Bar
51
+ self.class.search_path.each do |scope|
52
+ paths_searched << "#{scope.name}::#{params.controller}::#{params.component_name}"
53
+ component = begin
54
+ scope.const_get(params.controller, false).const_get(params.component_name, false)
55
+ rescue NameError
56
+ nil
57
+ end
58
+ break if component != nil
59
+ end
60
+ unless component
61
+ self.class.search_path.each do |scope|
62
+ paths_searched << "#{scope.name}::#{params.component_name}"
63
+ component = begin
64
+ scope.const_get(params.component_name, false)
65
+ rescue NameError
66
+ nil
67
+ end
68
+ break if component != nil
69
+ end
70
+ end
71
+ end
72
+ @component = component
73
+ return @component if @component && @component.method_defined?(:render)
74
+ raise "Could not find component class '#{params.component_name}' for params.controller '#{params.controller}' in any component directory. Tried [#{paths_searched.join(", ")}]"
75
+ end
76
+
77
+ before_mount do
78
+ TopLevelRailsComponent.event_history = Hash.new { |h, k| h[k] = [] }
79
+ @render_params = params.render_params
80
+ component.validator.rules.each do |name, rules|
81
+ next unless rules[:type] == Proc
82
+
83
+ TopLevelRailsComponent.event_history[name] = []
84
+ @render_params[name] = lambda do |*args|
85
+ TopLevelRailsComponent.event_history[name] << args
86
+ end
87
+ end
88
+ end
89
+
90
+ def render
91
+ React::RenderingContext.render(component, @render_params)
92
+ end
93
+ end
94
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyper-spec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.alpha1.5
4
+ version: 1.0.0.lap28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mitch VanDuyn
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-06-19 00:00:00.000000000 Z
13
+ date: 2018-05-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: capybara
@@ -30,30 +30,16 @@ dependencies:
30
30
  name: chromedriver-helper
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - '='
34
- - !ruby/object:Gem::Version
35
- version: 1.2.0
36
- type: :runtime
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - '='
41
- - !ruby/object:Gem::Version
42
- version: 1.2.0
43
- - !ruby/object:Gem::Dependency
44
- name: libv8
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
33
+ - - ">="
48
34
  - !ruby/object:Gem::Version
49
- version: 6.7.0
35
+ version: '0'
50
36
  type: :runtime
51
37
  prerelease: false
52
38
  version_requirements: !ruby/object:Gem::Requirement
53
39
  requirements:
54
- - - "~>"
40
+ - - ">="
55
41
  - !ruby/object:Gem::Version
56
- version: 6.7.0
42
+ version: '0'
57
43
  - !ruby/object:Gem::Dependency
58
44
  name: method_source
59
45
  requirement: !ruby/object:Gem::Requirement
@@ -68,20 +54,6 @@ dependencies:
68
54
  - - ">="
69
55
  - !ruby/object:Gem::Version
70
56
  version: '0'
71
- - !ruby/object:Gem::Dependency
72
- name: mini_racer
73
- requirement: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - "~>"
76
- - !ruby/object:Gem::Version
77
- version: 0.2.4
78
- type: :runtime
79
- prerelease: false
80
- version_requirements: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - "~>"
83
- - !ruby/object:Gem::Version
84
- version: 0.2.4
85
57
  - !ruby/object:Gem::Dependency
86
58
  name: opal
87
59
  requirement: !ruby/object:Gem::Requirement
@@ -192,14 +164,14 @@ dependencies:
192
164
  requirements:
193
165
  - - ">="
194
166
  - !ruby/object:Gem::Version
195
- version: 0.4.2
167
+ version: '0'
196
168
  type: :runtime
197
169
  prerelease: false
198
170
  version_requirements: !ruby/object:Gem::Requirement
199
171
  requirements:
200
172
  - - ">="
201
173
  - !ruby/object:Gem::Version
202
- version: 0.4.2
174
+ version: '0'
203
175
  - !ruby/object:Gem::Dependency
204
176
  name: webdrivers
205
177
  requirement: !ruby/object:Gem::Requirement
@@ -220,34 +192,42 @@ dependencies:
220
192
  requirements:
221
193
  - - ">="
222
194
  - !ruby/object:Gem::Version
223
- version: 1.17.3
224
- - - "<"
225
- - !ruby/object:Gem::Version
226
- version: '2.1'
195
+ version: '0'
227
196
  type: :development
228
197
  prerelease: false
229
198
  version_requirements: !ruby/object:Gem::Requirement
230
199
  requirements:
231
200
  - - ">="
232
201
  - !ruby/object:Gem::Version
233
- version: 1.17.3
234
- - - "<"
235
- - !ruby/object:Gem::Version
236
- version: '2.1'
202
+ version: '0'
237
203
  - !ruby/object:Gem::Dependency
238
- name: hyper-component
204
+ name: hyper-react
239
205
  requirement: !ruby/object:Gem::Requirement
240
206
  requirements:
241
207
  - - '='
242
208
  - !ruby/object:Gem::Version
243
- version: 1.0.alpha1.5
209
+ version: 1.0.0.lap28
244
210
  type: :development
245
211
  prerelease: false
246
212
  version_requirements: !ruby/object:Gem::Requirement
247
213
  requirements:
248
214
  - - '='
249
215
  - !ruby/object:Gem::Version
250
- version: 1.0.alpha1.5
216
+ version: 1.0.0.lap28
217
+ - !ruby/object:Gem::Dependency
218
+ name: mini_racer
219
+ requirement: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - "~>"
222
+ - !ruby/object:Gem::Version
223
+ version: 0.1.15
224
+ type: :development
225
+ prerelease: false
226
+ version_requirements: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - "~>"
229
+ - !ruby/object:Gem::Version
230
+ version: 0.1.15
251
231
  - !ruby/object:Gem::Dependency
252
232
  name: opal-browser
253
233
  requirement: !ruby/object:Gem::Requirement
@@ -277,7 +257,7 @@ dependencies:
277
257
  - !ruby/object:Gem::Version
278
258
  version: 0.9.4
279
259
  - !ruby/object:Gem::Dependency
280
- name: pry-rescue
260
+ name: puma
281
261
  requirement: !ruby/object:Gem::Requirement
282
262
  requirements:
283
263
  - - ">="
@@ -291,35 +271,35 @@ dependencies:
291
271
  - !ruby/object:Gem::Version
292
272
  version: '0'
293
273
  - !ruby/object:Gem::Dependency
294
- name: puma
274
+ name: rails
295
275
  requirement: !ruby/object:Gem::Requirement
296
276
  requirements:
297
277
  - - ">="
298
278
  - !ruby/object:Gem::Version
299
- version: '0'
279
+ version: 4.0.0
300
280
  type: :development
301
281
  prerelease: false
302
282
  version_requirements: !ruby/object:Gem::Requirement
303
283
  requirements:
304
284
  - - ">="
305
285
  - !ruby/object:Gem::Version
306
- version: '0'
286
+ version: 4.0.0
307
287
  - !ruby/object:Gem::Dependency
308
- name: rails
288
+ name: rake
309
289
  requirement: !ruby/object:Gem::Requirement
310
290
  requirements:
311
291
  - - ">="
312
292
  - !ruby/object:Gem::Version
313
- version: 4.0.0
293
+ version: '0'
314
294
  type: :development
315
295
  prerelease: false
316
296
  version_requirements: !ruby/object:Gem::Requirement
317
297
  requirements:
318
298
  - - ">="
319
299
  - !ruby/object:Gem::Version
320
- version: 4.0.0
300
+ version: '0'
321
301
  - !ruby/object:Gem::Dependency
322
- name: rake
302
+ name: pry-rescue
323
303
  requirement: !ruby/object:Gem::Requirement
324
304
  requirements:
325
305
  - - ">="
@@ -489,23 +469,27 @@ extensions: []
489
469
  extra_rdoc_files: []
490
470
  files:
491
471
  - ".gitignore"
472
+ - ".rubocop.yml"
492
473
  - ".travis.yml"
474
+ - CODE_OF_CONDUCT.md
493
475
  - Gemfile
476
+ - LICENSE.txt
477
+ - README.md
494
478
  - Rakefile
495
479
  - bin/console
496
480
  - bin/setup
481
+ - dciy.toml
497
482
  - hyper-spec.gemspec
498
483
  - lib/bin/firebug-2.0.13-fx.xpi
499
484
  - lib/bin/firebug-2.0.19-fx.xpi
500
485
  - lib/hyper-spec.rb
501
486
  - lib/hyper-spec/component_test_helpers.rb
502
487
  - lib/hyper-spec/time_cop.rb
503
- - lib/hyper-spec/unparser_patch.rb
504
488
  - lib/hyper-spec/version.rb
505
489
  - lib/hyper-spec/wait_for_ajax.rb
490
+ - lib/react/top_level_rails_component.rb
506
491
  - lib/selenium/web_driver/firefox/profile.rb
507
492
  - lib/sources/lolex.js
508
- - lib/sources/top_level_rails_component.rb
509
493
  homepage: http://ruby-hyperloop.org
510
494
  licenses:
511
495
  - MIT
@@ -525,7 +509,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
525
509
  - !ruby/object:Gem::Version
526
510
  version: 1.3.1
527
511
  requirements: []
528
- rubygems_version: 3.0.4
512
+ rubyforge_project:
513
+ rubygems_version: 2.7.6
529
514
  signing_key:
530
515
  specification_version: 4
531
516
  summary: Drive your Hyperloop client and server specs from RSpec and Capybara
@@ -1,10 +0,0 @@
1
- module Unparser
2
- class Emitter
3
- # Emitter for send
4
- class Send < self
5
- def local_variable_clash?
6
- selector =~ /^[A-Z]/ || local_variable_scope.local_variable_defined_for_node?(node, selector)
7
- end
8
- end
9
- end
10
- end
@@ -1,103 +0,0 @@
1
- module Hyperstack
2
- module Internal
3
- module Component
4
- class TopLevelRailsComponent
5
-
6
- # original class declares these params:
7
- # param :component_name
8
- # param :controller
9
- # param :render_params
10
-
11
- class << self
12
- attr_accessor :event_history
13
-
14
- def callback_history_for(proc_name)
15
- event_history[proc_name]
16
- end
17
-
18
- def last_callback_for(proc_name)
19
- event_history[proc_name].last
20
- end
21
-
22
- def clear_callback_history_for(proc_name)
23
- event_history[proc_name] = []
24
- end
25
-
26
- def event_history_for(event_name)
27
- event_history["on_#{event_name}"]
28
- end
29
-
30
- def last_event_for(event_name)
31
- event_history["on_#{event_name}"].last
32
- end
33
-
34
- def clear_event_history_for(event_name)
35
- event_history["on_#{event_name}"] = []
36
- end
37
- end
38
-
39
- def component
40
- return @component if @component
41
- paths_searched = []
42
- component = nil
43
- if @ComponentName.start_with?('::')
44
- # if absolute path of component is given, look it up and fail if not found
45
- paths_searched << @ComponentName
46
- component = begin
47
- Object.const_get(@ComponentName)
48
- rescue NameError
49
- nil
50
- end
51
- else
52
- # if relative path is given, look it up like this
53
- # 1) we check each path + controller-name + component-name
54
- # 2) if we can't find it there we check each path + component-name
55
- # if we can't find it we just try const_get
56
- # so (assuming controller name is Home)
57
- # ::Foo::Bar will only resolve to some component named ::Foo::Bar
58
- # but Foo::Bar will check (in this order) ::Home::Foo::Bar, ::Components::Home::Foo::Bar, ::Foo::Bar, ::Components::Foo::Bar
59
- self.class.search_path.each do |scope|
60
- paths_searched << "#{scope.name}::#{@Controller}::#{@ComponentName}"
61
- component = begin
62
- scope.const_get(@Controller, false).const_get(@ComponentName, false)
63
- rescue NameError
64
- nil
65
- end
66
- break if component != nil
67
- end
68
- unless component
69
- self.class.search_path.each do |scope|
70
- paths_searched << "#{scope.name}::#{@ComponentName}"
71
- component = begin
72
- scope.const_get(@ComponentName, false)
73
- rescue NameError
74
- nil
75
- end
76
- break if component != nil
77
- end
78
- end
79
- end
80
- @component = component
81
- return @component if @component && @component.method_defined?(:render)
82
- raise "Could not find component class '#{@ComponentName}' for @Controller '#{@Controller}' in any component directory. Tried [#{paths_searched.join(", ")}]"
83
- end
84
-
85
- before_mount do
86
- TopLevelRailsComponent.event_history = Hash.new { |h, k| h[k] = [] }
87
- component.validator.rules.each do |name, rules|
88
- next unless rules[:type] == Proc
89
-
90
- TopLevelRailsComponent.event_history[name] = []
91
- @RenderParams[name] = lambda do |*args|
92
- TopLevelRailsComponent.event_history[name] << args
93
- end
94
- end
95
- end
96
-
97
- def render
98
- Hyperstack::Internal::Component::RenderingContext.render(component, @RenderParams)
99
- end
100
- end
101
- end
102
- end
103
- end