hyper-spec 1.0.alpha1.5 → 1.0.alpha1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/hyper-spec.gemspec +13 -10
- data/lib/hyper-spec.rb +162 -28
- data/lib/hyper-spec/controller_helpers.rb +164 -0
- data/lib/hyper-spec/expectations.rb +64 -0
- data/lib/hyper-spec/helpers.rb +221 -0
- data/lib/hyper-spec/internal/client_execution.rb +94 -0
- data/lib/hyper-spec/internal/component_mount.rb +140 -0
- data/lib/hyper-spec/internal/controller.rb +70 -0
- data/lib/hyper-spec/internal/copy_locals.rb +103 -0
- data/lib/hyper-spec/internal/patches.rb +86 -0
- data/lib/hyper-spec/internal/rails_controller_helpers.rb +50 -0
- data/lib/hyper-spec/{time_cop.rb → internal/time_cop.rb} +14 -2
- data/lib/hyper-spec/internal/window_sizing.rb +73 -0
- data/lib/hyper-spec/rack.rb +67 -0
- data/lib/hyper-spec/version.rb +1 -1
- data/lib/hyper-spec/wait_for_ajax.rb +1 -1
- data/multi_level_how_it_works.md +49 -0
- metadata +92 -54
- data/lib/hyper-spec/component_test_helpers.rb +0 -365
- data/lib/hyper-spec/unparser_patch.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 443b8fc1d67013a7ffa37d43b8b5076d8b5375d83b247dc2f36b348d97da2ed8
|
4
|
+
data.tar.gz: 5c5264998e05d454a97bab490f9db4be02a5956e8b08fc47c8cc2c9292daf40a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35cf7981c3612173408aa541cb06db31d8367c0ab5dc8f3d5354785a941d02f6902c21e8f8ae39a5284d9152e05621bad06af9a1e342ef12b7a349f0e74079b6
|
7
|
+
data.tar.gz: bc5cf881fc4e20b85bb15a68559c4d2b7adc5de0687cde7ca38653392f9bdde6c52e4dc0650ca6f9ca0dfc7eee7e8e1b6f78ee17007b77bbd7a07353c7a23826
|
data/bin/console
CHANGED
File without changes
|
data/bin/setup
CHANGED
File without changes
|
data/hyper-spec.gemspec
CHANGED
@@ -24,30 +24,33 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ['lib']
|
26
26
|
|
27
|
+
spec.add_dependency 'actionview'
|
27
28
|
spec.add_dependency 'capybara'
|
28
29
|
spec.add_dependency 'chromedriver-helper', '1.2.0'
|
29
|
-
spec.add_dependency '
|
30
|
+
spec.add_dependency 'filecache'
|
31
|
+
# spec.add_dependency 'libv8', '~> 7.3.492.27.1'
|
30
32
|
spec.add_dependency 'method_source'
|
31
|
-
spec.add_dependency '
|
32
|
-
spec.add_dependency '
|
33
|
-
spec.add_dependency '
|
34
|
-
spec.add_dependency 'pry'
|
35
|
-
spec.add_dependency 'rspec-rails'
|
33
|
+
spec.add_dependency 'opal', ENV['OPAL_VERSION'] || '>= 0.11.0', '< 2.0'
|
34
|
+
spec.add_dependency 'parser', '>= 2.3.3.1' # on rails-6 this is now >= 2.3
|
35
|
+
spec.add_dependency 'rspec'
|
36
36
|
spec.add_dependency 'selenium-webdriver'
|
37
37
|
spec.add_dependency 'timecop', '~> 0.8.1'
|
38
38
|
spec.add_dependency 'uglifier'
|
39
|
-
spec.add_dependency 'unparser', '>= 0.4.2'
|
39
|
+
spec.add_dependency 'unparser', '>= 0.4.2'
|
40
40
|
spec.add_dependency 'webdrivers'
|
41
41
|
|
42
|
-
spec.add_development_dependency 'bundler'
|
42
|
+
spec.add_development_dependency 'bundler'
|
43
43
|
spec.add_development_dependency 'hyper-component', HyperSpec::VERSION
|
44
|
+
spec.add_development_dependency 'mini_racer'
|
44
45
|
spec.add_development_dependency 'opal-browser', '~> 0.2.0'
|
45
|
-
spec.add_development_dependency 'opal-rails', '
|
46
|
+
spec.add_development_dependency 'opal-rails', '>= 0.9.4'
|
46
47
|
spec.add_development_dependency 'pry-rescue'
|
48
|
+
spec.add_development_dependency 'pry-stack_explorer'
|
47
49
|
spec.add_development_dependency 'puma'
|
48
|
-
spec.add_development_dependency 'rails', '>=
|
50
|
+
spec.add_development_dependency 'rails', ENV['RAILS_VERSION'] || '>= 5.0.0', '< 7.0'
|
49
51
|
spec.add_development_dependency 'rake'
|
50
52
|
spec.add_development_dependency 'react-rails', '>= 2.3.0', '< 2.5.0'
|
53
|
+
spec.add_development_dependency 'rspec-rails'
|
51
54
|
spec.add_development_dependency 'rspec-collection_matchers'
|
52
55
|
spec.add_development_dependency 'rspec-expectations'
|
53
56
|
spec.add_development_dependency 'rspec-its'
|
data/lib/hyper-spec.rb
CHANGED
@@ -1,14 +1,136 @@
|
|
1
|
-
|
1
|
+
# hyper-spec
|
2
|
+
require 'action_view'
|
2
3
|
require 'opal'
|
4
|
+
require 'unparser'
|
5
|
+
require 'method_source'
|
6
|
+
require 'filecache'
|
7
|
+
|
8
|
+
require 'capybara/rspec'
|
9
|
+
require 'hyper-spec/internal/client_execution'
|
10
|
+
require 'hyper-spec/internal/component_mount'
|
11
|
+
require 'hyper-spec/internal/controller'
|
12
|
+
require 'hyper-spec/internal/copy_locals'
|
13
|
+
require 'hyper-spec/internal/patches'
|
14
|
+
require 'hyper-spec/internal/rails_controller_helpers'
|
15
|
+
require 'hyper-spec/internal/time_cop.rb'
|
16
|
+
require 'hyper-spec/internal/window_sizing'
|
17
|
+
|
18
|
+
require 'hyper-spec/controller_helpers'
|
19
|
+
|
20
|
+
require 'hyper-spec/wait_for_ajax'
|
21
|
+
|
22
|
+
require 'hyper-spec/helpers'
|
23
|
+
require 'hyper-spec/expectations'
|
24
|
+
|
25
|
+
require 'parser/current'
|
26
|
+
if defined?(Selenium::WebDriver::Firefox)
|
27
|
+
require 'selenium/web_driver/firefox/profile'
|
28
|
+
end
|
3
29
|
require 'selenium-webdriver'
|
4
30
|
|
5
|
-
require 'hyper-spec/component_test_helpers'
|
6
31
|
require 'hyper-spec/version'
|
7
|
-
|
8
|
-
|
32
|
+
|
33
|
+
|
34
|
+
begin
|
35
|
+
require 'pry'
|
36
|
+
rescue LoadError
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
Parser::Builders::Default.emit_procarg0 = true
|
41
|
+
|
42
|
+
# not available in parser 2.3
|
43
|
+
if Parser::Builders::Default.respond_to? :emit_arg_inside_procarg0
|
44
|
+
Parser::Builders::Default.emit_arg_inside_procarg0 = true
|
45
|
+
end
|
46
|
+
|
47
|
+
module HyperSpec
|
48
|
+
if defined? Pry
|
49
|
+
# add a before eval hook to pry so we can capture the source
|
50
|
+
class << self
|
51
|
+
attr_accessor :current_pry_code_block
|
52
|
+
Pry.hooks.add_hook(:before_eval, 'hyper_spec_code_capture') do |code|
|
53
|
+
HyperSpec.current_pry_code_block = code
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.reset_between_examples
|
59
|
+
@reset_between_examples ||= []
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.reset_between_examples?
|
63
|
+
RSpec.configuration.reset_between_examples
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.reset_sessions!
|
67
|
+
Capybara.old_reset_sessions!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: figure out why we need this patch - its because we are on an old version
|
72
|
+
# of Selenium Webdriver, but why?
|
73
|
+
require 'selenium-webdriver'
|
74
|
+
|
75
|
+
module Selenium
|
76
|
+
module WebDriver
|
77
|
+
module Chrome
|
78
|
+
module Bridge
|
79
|
+
COMMANDS = remove_const(:COMMANDS).dup
|
80
|
+
COMMANDS[:get_log] = [:post, 'session/:session_id/log']
|
81
|
+
COMMANDS.freeze
|
82
|
+
|
83
|
+
def log(type)
|
84
|
+
data = execute :get_log, {}, type: type.to_s
|
85
|
+
|
86
|
+
Array(data).map do |l|
|
87
|
+
begin
|
88
|
+
LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
|
89
|
+
rescue KeyError
|
90
|
+
next
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
module Capybara
|
100
|
+
class << self
|
101
|
+
alias old_reset_sessions! reset_sessions!
|
102
|
+
def reset_sessions!
|
103
|
+
old_reset_sessions! if HyperSpec.reset_between_examples?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
RSpec.configure do |config|
|
109
|
+
config.add_setting :reset_between_examples, default: true
|
110
|
+
config.before(:all, no_reset: true) do
|
111
|
+
HyperSpec.reset_between_examples << RSpec.configuration.reset_between_examples
|
112
|
+
RSpec.configuration.reset_between_examples = false
|
113
|
+
end
|
114
|
+
config.before(:all, no_reset: false) do
|
115
|
+
HyperSpec.reset_between_examples << RSpec.configuration.reset_between_examples
|
116
|
+
RSpec.configuration.reset_between_examples = true
|
117
|
+
end
|
118
|
+
config.after(:all) do
|
119
|
+
HyperSpec.reset_sessions! unless HyperSpec.reset_between_examples?
|
120
|
+
# If rspecs step is used first in a file, it will NOT call config.before(:all) causing the
|
121
|
+
# reset_between_examples stack to be mismatched, so we check, if its already empty we
|
122
|
+
# just leave.
|
123
|
+
next if HyperSpec.reset_between_examples.empty?
|
124
|
+
|
125
|
+
RSpec.configuration.reset_between_examples = HyperSpec.reset_between_examples.pop
|
126
|
+
end
|
127
|
+
config.before(:each) do |example|
|
128
|
+
insure_page_loaded(true) if example.metadata[:js] && !HyperSpec.reset_between_examples?
|
129
|
+
end
|
130
|
+
end
|
9
131
|
|
10
132
|
RSpec.configure do |config|
|
11
|
-
config.include HyperSpec::
|
133
|
+
config.include HyperSpec::Helpers
|
12
134
|
config.include HyperSpec::WaitForAjax
|
13
135
|
config.include Capybara::DSL
|
14
136
|
|
@@ -17,17 +139,21 @@ RSpec.configure do |config|
|
|
17
139
|
config.add_setting :debugger_width, default: nil
|
18
140
|
|
19
141
|
config.before(:each) do
|
20
|
-
Hyperstack
|
21
|
-
|
22
|
-
|
142
|
+
if defined?(Hyperstack)
|
143
|
+
Hyperstack.class_eval do
|
144
|
+
def self.on_server?
|
145
|
+
true
|
146
|
+
end
|
23
147
|
end
|
24
|
-
end
|
148
|
+
end
|
25
149
|
# for compatibility with HyperMesh
|
26
|
-
HyperMesh
|
27
|
-
|
28
|
-
|
150
|
+
if defined?(HyperMesh)
|
151
|
+
HyperMesh.class_eval do
|
152
|
+
def self.on_server?
|
153
|
+
true
|
154
|
+
end
|
29
155
|
end
|
30
|
-
end
|
156
|
+
end
|
31
157
|
end
|
32
158
|
|
33
159
|
config.before(:each, js: true) do
|
@@ -43,42 +169,51 @@ RSpec.configure do |config|
|
|
43
169
|
PusherFake::Channel.reset if defined? PusherFake
|
44
170
|
end
|
45
171
|
end
|
46
|
-
|
47
172
|
end
|
48
173
|
|
49
174
|
# Capybara config
|
50
|
-
RSpec.configure do |
|
175
|
+
RSpec.configure do |config|
|
176
|
+
config.before(:each) do |example|
|
177
|
+
HyperSpec::Internal::Controller.current_example = example
|
178
|
+
HyperSpec::Internal::Controller.description_displayed = false
|
179
|
+
end
|
180
|
+
|
181
|
+
config.add_setting :wait_for_initialization_time
|
182
|
+
config.wait_for_initialization_time = 3
|
183
|
+
|
51
184
|
Capybara.default_max_wait_time = 10
|
52
185
|
|
53
186
|
Capybara.register_driver :chrome do |app|
|
54
187
|
options = {}
|
55
188
|
options.merge!(
|
56
|
-
|
57
|
-
|
58
|
-
)
|
59
|
-
# this does not seem to work properly. Don't document this feature yet.
|
189
|
+
w3c: false,
|
190
|
+
args: %w[auto-open-devtools-for-tabs]
|
191
|
+
)
|
60
192
|
options['mobileEmulation'] = { 'deviceName' => ENV['DEVICE'].tr('-', ' ') } if ENV['DEVICE']
|
61
|
-
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
|
193
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
|
194
|
+
chromeOptions: options, 'goog:loggingPrefs' => { browser: 'ALL' }
|
195
|
+
)
|
62
196
|
Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
|
63
197
|
end
|
64
198
|
|
199
|
+
Capybara.register_driver :firefox do |app|
|
200
|
+
Capybara::Selenium::Driver.new(app, browser: :firefox)
|
201
|
+
end
|
202
|
+
|
65
203
|
Capybara.register_driver :chrome_headless_docker_travis do |app|
|
66
204
|
options = ::Selenium::WebDriver::Chrome::Options.new
|
67
205
|
options.add_argument('--headless')
|
68
206
|
options.add_argument('--no-sandbox')
|
69
207
|
options.add_argument('--disable-dev-shm-usage')
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
Capybara.register_driver :firefox do |app|
|
74
|
-
Capybara::Selenium::Driver.new(app, browser: :firefox)
|
208
|
+
Selenium::WebDriver::Chrome::Service.driver_path = '/usr/lib/chromium-browser/chromedriver'
|
209
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
|
75
210
|
end
|
76
211
|
|
77
212
|
Capybara.register_driver :firefox_headless do |app|
|
78
213
|
options = Selenium::WebDriver::Firefox::Options.new
|
79
214
|
options.headless!
|
80
215
|
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)
|
81
|
-
end
|
216
|
+
end if defined?(Selenium::WebDriver::Firefox)
|
82
217
|
|
83
218
|
Capybara.register_driver :selenium_with_firebug do |app|
|
84
219
|
profile = Selenium::WebDriver::Firefox::Profile.new
|
@@ -86,7 +221,7 @@ RSpec.configure do |_config|
|
|
86
221
|
profile.enable_firebug
|
87
222
|
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
88
223
|
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)
|
89
|
-
end
|
224
|
+
end if defined?(Selenium::WebDriver::Firefox)
|
90
225
|
|
91
226
|
Capybara.register_driver :safari do |app|
|
92
227
|
Capybara::Selenium::Driver.new(app, browser: :safari)
|
@@ -103,5 +238,4 @@ RSpec.configure do |_config|
|
|
103
238
|
when 'travis' then :chrome_headless_docker_travis
|
104
239
|
else :selenium_chrome_headless
|
105
240
|
end
|
106
|
-
|
107
241
|
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module HyperSpec
|
2
|
+
# Defines a series of methods that will build a test page
|
3
|
+
# This module is typically included into the HyperSpecTestController class.
|
4
|
+
module ControllerHelpers
|
5
|
+
# These methods are dependent on the stack being used. See the
|
6
|
+
# RailsControllerHelpers module and rack.rb for two implementations.
|
7
|
+
# Each method should append the appropriate code to the @page array
|
8
|
+
|
9
|
+
# return an empty 204 status either by setting headers or
|
10
|
+
# returning and appropriate response for rack.
|
11
|
+
def ping!
|
12
|
+
raise 'must implement'
|
13
|
+
end
|
14
|
+
|
15
|
+
def json!
|
16
|
+
# this can be a no-op but if json is not included by the application,
|
17
|
+
# hyper-spec will fail, with an error complaining about to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
# return a script or style_sheet tag pointing to some asset.
|
21
|
+
# typically you be pointing to a path on the server or using
|
22
|
+
# sprockets to deliver the file.
|
23
|
+
|
24
|
+
def require!(_file_)
|
25
|
+
raise 'must implement'
|
26
|
+
end
|
27
|
+
|
28
|
+
def style_sheet!(_file_)
|
29
|
+
raise 'must implement'
|
30
|
+
end
|
31
|
+
|
32
|
+
# deliver the page. The @page variable will contain the html ready to go,
|
33
|
+
# any additional options that are passed through from the spec will be
|
34
|
+
# in the @render_params variable. For example layout: 'my_special_layout'
|
35
|
+
|
36
|
+
def deliver!
|
37
|
+
raise 'must implement'
|
38
|
+
end
|
39
|
+
|
40
|
+
# generate a react_render top level block. This will only be called if
|
41
|
+
# you use the mount directive in your specs, so it is optional.
|
42
|
+
|
43
|
+
def mount_component!
|
44
|
+
raise 'mount_component not implemented in HyperSpecTestController'
|
45
|
+
end
|
46
|
+
|
47
|
+
# by default the route back to the controller will be the controller name, less the
|
48
|
+
# word Controller, and underscored. If you want some other name redefine this
|
49
|
+
# method in the HyperSpecController class.
|
50
|
+
|
51
|
+
def self.included(base)
|
52
|
+
def base.route_root
|
53
|
+
# Implement underscore without using rails underscore, so we don't have a
|
54
|
+
# dependency on ActiveSupport
|
55
|
+
name.gsub(/Controller$/, '')
|
56
|
+
.gsub(/::/, '/')
|
57
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
58
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
59
|
+
.tr('-', '_')
|
60
|
+
.downcase
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# The remainder of the methods should work for most implementations.
|
65
|
+
|
66
|
+
# helper method checking the render_on parameter
|
67
|
+
|
68
|
+
def on_client?
|
69
|
+
@render_on != :server_only
|
70
|
+
end
|
71
|
+
|
72
|
+
# The controllers behavior is kept as an array of values in the Controller cache
|
73
|
+
# under a unique id for each test run. Grab the parameters and move them to instance vars
|
74
|
+
|
75
|
+
# If this is just a ping! Then we can just exit with nil.
|
76
|
+
|
77
|
+
def initialize!
|
78
|
+
return if params[:id] == 'ping'
|
79
|
+
|
80
|
+
key = "/#{self.class.route_root}/#{params[:id]}"
|
81
|
+
test_params = Internal::Controller.cache_read(key)
|
82
|
+
|
83
|
+
@component_name = test_params[0]
|
84
|
+
@component_params = test_params[1]
|
85
|
+
@html_block = test_params[2]
|
86
|
+
@render_params = test_params[3]
|
87
|
+
@render_on = @render_params.delete(:render_on) || :client_only
|
88
|
+
@_mock_time = @render_params.delete(:mock_time)
|
89
|
+
@style_sheet = @render_params.delete(:style_sheet)
|
90
|
+
@javascript = @render_params.delete(:javascript)
|
91
|
+
@code = @render_params.delete(:code)
|
92
|
+
|
93
|
+
@page = ['<body>']
|
94
|
+
end
|
95
|
+
|
96
|
+
# add any html code generated by the insert_html directive
|
97
|
+
|
98
|
+
def html_block!
|
99
|
+
@page << @html_block
|
100
|
+
end
|
101
|
+
|
102
|
+
# patch behavior of the HyperComponent TopLevelRailsComponent class
|
103
|
+
# so that things like events are passed back to the test harness
|
104
|
+
TOP_LEVEL_COMPONENT_PATCH =
|
105
|
+
Opal.compile(File.read(File.expand_path('../sources/top_level_rails_component.rb', __dir__)))
|
106
|
+
|
107
|
+
# patch time cop and lolex so they stay in sync across the client and server
|
108
|
+
TIME_COP_CLIENT_PATCH =
|
109
|
+
Opal.compile(File.read(File.expand_path('../hyper-spec/internal/time_cop.rb', __dir__))) +
|
110
|
+
"\n#{File.read(File.expand_path('../sources/lolex.js', __dir__))}"
|
111
|
+
|
112
|
+
def client_code!
|
113
|
+
if @component_name
|
114
|
+
@page << "<script type='text/javascript'>\n#{TOP_LEVEL_COMPONENT_PATCH}\n</script>"
|
115
|
+
end
|
116
|
+
@page << "<script type='text/javascript'>\n#{@code}\n</script>" if @code
|
117
|
+
end
|
118
|
+
|
119
|
+
def time_cop_patch!
|
120
|
+
@page << "<script type='text/javascript'>\n#{TIME_COP_CLIENT_PATCH}\n</script>"
|
121
|
+
end
|
122
|
+
|
123
|
+
# Add the go_function to the client console. This is used to stop a hyper-spec pause directive.
|
124
|
+
|
125
|
+
def go_function!
|
126
|
+
@page << "<script type='text/javascript'>go = function() "\
|
127
|
+
'{window.hyper_spec_waiting_for_go = false}</script>'
|
128
|
+
end
|
129
|
+
|
130
|
+
# First lines displayed on the console will be the name of the spec
|
131
|
+
|
132
|
+
def example_title!
|
133
|
+
title = Internal::Controller.current_example_description!
|
134
|
+
@page << "<script type='text/javascript'>console.log('%c#{title}',"\
|
135
|
+
"'color:green; font-weight:bold; font-size: 200%')</script>"
|
136
|
+
end
|
137
|
+
|
138
|
+
# generate each piece of the page, and then deliver it
|
139
|
+
|
140
|
+
def style_sheet_file
|
141
|
+
@style_sheet || (!@render_params[:layout] && 'application')
|
142
|
+
end
|
143
|
+
|
144
|
+
def application_file
|
145
|
+
@javascript || (on_client? && !@render_params[:layout] && 'application')
|
146
|
+
end
|
147
|
+
|
148
|
+
def test
|
149
|
+
return ping! unless initialize!
|
150
|
+
|
151
|
+
html_block!
|
152
|
+
example_title! if Internal::Controller.current_example
|
153
|
+
go_function! if on_client?
|
154
|
+
style_sheet!(style_sheet_file) if style_sheet_file
|
155
|
+
application!(application_file) if application_file
|
156
|
+
json!
|
157
|
+
time_cop_patch! if on_client? || Lolex.initialized?
|
158
|
+
client_code! if on_client?
|
159
|
+
mount_component! if @component_name
|
160
|
+
@page = @page.join("\n") + "\n</body>\n"
|
161
|
+
deliver!
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|