hyper-spec 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.rubocop.yml DELETED
@@ -1,107 +0,0 @@
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,306 +0,0 @@
1
- # see component_test_helpers_spec.rb for examples
2
-
3
- require 'parser/current'
4
- require 'unparser'
5
- require 'method_source'
6
- require_relative '../../vendor/assets/javascripts/time_cop' # 'hyper-spec/time_cop'
7
-
8
- module HyperSpec
9
- module ComponentTestHelpers
10
- TOP_LEVEL_COMPONENT_PATCH =
11
- Opal.compile(File.read(File.expand_path('../../react/top_level_rails_component.rb', __FILE__)))
12
-
13
- class << self
14
- attr_accessor :current_example
15
- attr_accessor :description_displayed
16
-
17
- def display_example_description
18
- "<script type='text/javascript'>console.log(console.log('%c#{current_example.description}'"\
19
- ",'color:green; font-weight:bold; font-size: 200%'))</script>"
20
- end
21
- end
22
-
23
- def build_test_url_for(controller)
24
- unless controller
25
- unless defined?(::ReactTestController)
26
- Object.const_set('ReactTestController', Class.new(ActionController::Base))
27
- end
28
-
29
- controller = ::ReactTestController
30
- end
31
-
32
- route_root = controller.name.gsub(/Controller$/, '').underscore
33
-
34
- unless controller.method_defined?(:test)
35
- controller.class_eval do
36
- define_method(:test) do
37
- route_root = self.class.name.gsub(/Controller$/, '').underscore
38
- test_params = ::Rails.cache.read("/#{route_root}/#{params[:id]}")
39
- @component_name = test_params[0]
40
- @component_params = test_params[1]
41
- render_params = test_params[2]
42
- render_on = render_params.delete(:render_on) || :client_only
43
- _mock_time = render_params.delete(:mock_time)
44
- style_sheet = render_params.delete(:style_sheet)
45
- javascript = render_params.delete(:javascript)
46
- code = render_params.delete(:code)
47
-
48
- page = '<%= react_component @component_name, @component_params, '\
49
- "{ prerender: #{render_on != :client_only} } %>"
50
- page = "<script type='text/javascript'>\n#{TOP_LEVEL_COMPONENT_PATCH}\n</script>\n#{page}"
51
-
52
- page = "<script type='text/javascript'>\n#{code}\n</script>\n#{page}" if code
53
-
54
- page = "<%= javascript_include_tag 'time_cop' %>\n#{page}" if true || Lolex.initialized?
55
-
56
- if (render_on != :server_only && !render_params[:layout]) || javascript
57
- page = "<%= javascript_include_tag '#{javascript || 'application'}' %>\n#{page}"
58
- end
59
-
60
- if !render_params[:layout] || style_sheet
61
- page = "<%= stylesheet_link_tag '#{style_sheet || 'application'}' %>\n#{page}"
62
- end
63
-
64
- if render_on == :server_only # so that test helper wait_for_ajax works
65
- page = "<script type='text/javascript'>window.jQuery = {'active': 0}</script>\n#{page}"
66
- else
67
- page = "<%= javascript_include_tag 'jquery' %>\n"\
68
- "<%= javascript_include_tag 'jquery_ujs' %>\n#{page}"
69
- end
70
-
71
- page = "<script type='text/javascript'>go = function() "\
72
- "{window.hyper_spec_waiting_for_go = false}</script>\n#{page}"
73
-
74
- title = view_context.escape_javascript(ComponentTestHelpers.current_example.description)
75
- title = "#{title}...continued." if ComponentTestHelpers.description_displayed
76
-
77
- page = "<script type='text/javascript'>console.log(console.log('%c#{title}',"\
78
- "'color:green; font-weight:bold; font-size: 200%'))</script>\n#{page}"
79
-
80
- ComponentTestHelpers.description_displayed = true
81
- render_params[:inline] = page
82
- render render_params
83
- end
84
- end
85
-
86
- begin
87
- routes = ::Rails.application.routes
88
- routes.disable_clear_and_finalize = true
89
- routes.clear!
90
- routes.draw do
91
- get "/#{route_root}/:id", to: "#{route_root}#test"
92
- end
93
- ::Rails.application.routes_reloader.paths.each { |path| load(path) }
94
- routes.finalize!
95
- ActiveSupport.on_load(:action_controller) { routes.finalize! }
96
- ensure
97
- routes.disable_clear_and_finalize = false
98
- end
99
- end
100
-
101
- "/#{route_root}/#{@test_id = (@test_id || 0) + 1}"
102
- end
103
-
104
- def isomorphic(&block)
105
- yield
106
- on_client(&block)
107
- end
108
-
109
- def evaluate_ruby(str = '', opts = {}, &block)
110
- insure_mount
111
- if block
112
- str = "#{str}\n#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.last}"
113
- end
114
- js = Opal.compile(str).delete("\n").gsub('(Opal);', '(Opal)')
115
- JSON.parse(evaluate_script("[#{js}].$to_json()"), opts).first
116
- end
117
-
118
- def expect_evaluate_ruby(str = '', opts = {}, &block)
119
- insure_mount
120
- expect(evaluate_ruby(add_opal_block(str, block), opts))
121
- end
122
-
123
- def add_opal_block(str, block)
124
- # big assumption here is that we are going to follow this with a .to
125
- # hence .children.first followed by .children.last
126
- # probably should do some kind of "search" to make this work nicely
127
- return str unless block
128
- "#{str}\n"\
129
- "#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.first.children.last}"
130
- end
131
-
132
- def expect_promise(str = '', opts = {}, &block)
133
- insure_mount
134
-
135
- str = add_opal_block(str, block)
136
- str = "#{str}.then { |args| args = [args]; `window.hyper_spec_promise_result = args` }"
137
- js = Opal.compile(str).delete("\n").gsub('(Opal);', '(Opal)')
138
- page.evaluate_script('window.hyper_spec_promise_result = false')
139
- page.execute_script(js)
140
-
141
- Timeout.timeout(Capybara.default_max_wait_time) do
142
- loop do
143
- sleep 0.25
144
- break if page.evaluate_script('!!window.hyper_spec_promise_result')
145
- end
146
- end
147
-
148
- result =
149
- JSON.parse(page.evaluate_script('window.hyper_spec_promise_result.$to_json()'), opts).first
150
- expect(result)
151
- end
152
-
153
- def ppr(str)
154
- js = Opal.compile(str).delete("\n").gsub('(Opal);', '(Opal)')
155
- execute_script("console.log(#{js})")
156
- end
157
-
158
- def on_client(&block)
159
- @client_code =
160
- "#{@client_code}#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.last}\n"
161
- end
162
-
163
- def debugger
164
- `debugger`
165
- nil
166
- end
167
-
168
- def insure_mount
169
- # rescue in case page is not defined...
170
- mount unless page.instance_variable_get('@hyper_spec_mounted')
171
- end
172
-
173
- def client_option(opts = {})
174
- @client_options ||= {}
175
- @client_options.merge! opts
176
- end
177
-
178
- alias client_options client_option
179
-
180
- def mount(component_name = nil, params = nil, opts = {}, &block)
181
- unless params
182
- params = opts
183
- opts = {}
184
- end
185
-
186
- opts = client_options opts
187
- test_url = build_test_url_for(opts.delete(:controller))
188
-
189
- if block || @client_code || component_name.nil?
190
- block_with_helpers = <<-code
191
- module ComponentHelpers
192
- def self.js_eval(s)
193
- `eval(s)`
194
- end
195
- def self.dasherize(s)
196
- `s.replace(/[-_\\s]+/g, '-')
197
- .replace(/([A-Z\\d]+)([A-Z][a-z])/g, '$1-$2')
198
- .replace(/([a-z\\d])([A-Z])/g, '$1-$2')
199
- .toLowerCase()`
200
- end
201
- def self.add_class(class_name, styles={})
202
- style = styles.collect { |attr, value| "\#{dasherize(attr)}:\#{value}"}.join("; ")
203
- s = "<style type='text/css'> .\#{class_name}{ \#{style} } </style>"
204
- `$(\#{s}).appendTo("head");`
205
- end
206
- end
207
- class React::Component::HyperTestDummy < React::Component::Base
208
- def render; end
209
- end
210
- #{@client_code}
211
- #{Unparser.unparse(Parser::CurrentRuby.parse(block.source).children.last) if block}
212
- code
213
- opts[:code] = Opal.compile(block_with_helpers)
214
- end
215
-
216
- component_name ||= 'React::Component::HyperTestDummy'
217
- ::Rails.cache.write(test_url, [component_name, params, opts])
218
- visit test_url
219
- wait_for_ajax unless opts[:no_wait]
220
- page.instance_variable_set('@hyper_spec_mounted', true)
221
- Lolex.init(self, client_options[:time_zone], client_options[:clock_resolution])
222
- end
223
-
224
- [:callback_history_for, :last_callback_for, :clear_callback_history_for,
225
- :event_history_for, :last_event_for, :clear_event_history_for].each do |method|
226
- define_method(method) do |event_name|
227
- evaluate_ruby("React::TopLevelRailsComponent.#{method}('#{event_name}')")
228
- end
229
- end
230
-
231
- def run_on_client(&block)
232
- script = Opal.compile(Unparser.unparse(Parser::CurrentRuby.parse(block.source).children.last))
233
- execute_script(script)
234
- end
235
-
236
- def add_class(class_name, style)
237
- @client_code = "#{@client_code}ComponentHelpers.add_class '#{class_name}', #{style}\n"
238
- end
239
-
240
- def open_in_chrome
241
- if false && ['linux', 'freebsd'].include?(`uname`.downcase)
242
- `google-chrome http://#{page.server.host}:#{page.server.port}#{page.current_path}`
243
- else
244
- `open http://#{page.server.host}:#{page.server.port}#{page.current_path}`
245
- end
246
-
247
- while true
248
- sleep 1.hour
249
- end
250
- end
251
-
252
- def pause(message = nil)
253
- if message
254
- puts message
255
- page.evaluate_ruby "puts #{message.inspect}.to_s + ' (type go() to continue)'"
256
- end
257
-
258
- page.evaluate_script('window.hyper_spec_waiting_for_go = true')
259
-
260
- loop do
261
- sleep 0.25
262
- break unless page.evaluate_script('window.hyper_spec_waiting_for_go')
263
- end
264
- end
265
-
266
- def size_window(width = nil, height = nil)
267
- width, height = [height, width] if width == :portrait
268
- width, height = width if width.is_a? Array
269
- portrait = true if height == :portrait
270
-
271
- case width
272
- when :small
273
- width, height = [480, 320]
274
- when :mobile
275
- width, height = [640, 480]
276
- when :tablet
277
- width, height = [960, 640]
278
- when :large
279
- width, height = [1920, 6000]
280
- when :default, nil
281
- width, height = [1024, 768]
282
- end
283
-
284
- width, height = [height, width] if portrait
285
-
286
- Capybara.current_session.current_window.resize_to(width, height)
287
- end
288
- end
289
-
290
- RSpec.configure do |config|
291
- config.before(:each) do |example|
292
- ComponentTestHelpers.current_example = example
293
- ComponentTestHelpers.description_displayed = false
294
- end
295
-
296
- if defined?(ActiveRecord)
297
- config.before(:all) do
298
- ActiveRecord::Base.class_eval do
299
- def attributes_on_client(page)
300
- page.evaluate_ruby("#{self.class.name}.find(#{id}).attributes", symbolize_names: true)
301
- end
302
- end
303
- end
304
- end
305
- end
306
- end
@@ -1,66 +0,0 @@
1
- module HyperSpec
2
- class Lolex
3
- class << self
4
- def init(page, client_time_zone, resolution)
5
- @capybara_page = page
6
- @resolution = resolution || 10
7
- @client_time_zone = client_time_zone
8
- run_pending_evaluations
9
- @initialized = true
10
- end
11
-
12
- def initialized?
13
- @initialized
14
- end
15
-
16
- def push(mock_type, *args)
17
- scale = if mock_type == :freeze
18
- 0
19
- elsif mock_type == :scale
20
- args[0]
21
- else
22
- 1
23
- end
24
- evaluate_ruby do
25
- "Lolex.push('#{time_string_in_zone}', #{scale}, #{@resolution})"
26
- end
27
- end
28
-
29
- def pop
30
- evaluate_ruby { 'Lolex.pop' }
31
- end
32
-
33
- def unmock
34
- evaluate_ruby { "Lolex.unmock('#{time_string_in_zone}', #{@resolution})" }
35
- end
36
-
37
- def restore
38
- evaluate_ruby { 'Lolex.restore' }
39
- end
40
-
41
- private
42
-
43
- def time_string_in_zone
44
- Time.now.in_time_zone(@client_time_zone).strftime('%Y/%m/%d %H:%M:%S %z')
45
- end
46
-
47
- def pending_evaluations
48
- @pending_evaluations ||= []
49
- end
50
-
51
- def evaluate_ruby(&block)
52
- if @capybara_page
53
- @capybara_page.evaluate_ruby(yield)
54
- else
55
- pending_evaluations << block
56
- end
57
- end
58
-
59
- def run_pending_evaluations
60
- return if pending_evaluations.empty?
61
- @capybara_page.evaluate_ruby(pending_evaluations.collect(&:call).join("\n"))
62
- @pending_evaluations ||= []
63
- end
64
- end
65
- end
66
- end