fortitude 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +73 -0
  3. data/CONTRIBUTORS.md +17 -0
  4. data/ext/com/fortituderuby/ext/fortitude/FortitudeNativeLibrary.java +23 -7
  5. data/ext/fortitude_native_ext/fortitude_native_ext.c +91 -54
  6. data/lib/fortitude/doctypes/html4.rb +4 -0
  7. data/lib/fortitude/doctypes/html5.rb +4 -0
  8. data/lib/fortitude/doctypes/unknown_doctype.rb +4 -0
  9. data/lib/fortitude/doctypes/xhtml10.rb +4 -0
  10. data/lib/fortitude/doctypes/xhtml11.rb +4 -0
  11. data/lib/fortitude/erector.rb +1 -0
  12. data/lib/fortitude/errors.rb +16 -0
  13. data/lib/fortitude/extensions/fortitude_ruby_ext.rb +27 -12
  14. data/lib/fortitude/method_templates/assign_locals_from_template.rb.smpl +2 -0
  15. data/lib/fortitude/method_templates/need_assignment_template.rb.smpl +2 -2
  16. data/lib/fortitude/method_templates/simple_compiled_template.rb +94 -0
  17. data/lib/fortitude/method_templates/tag_method_template.rb.smpl +4 -4
  18. data/lib/fortitude/method_templates/text_method_template.rb.smpl +2 -2
  19. data/lib/fortitude/rails/railtie.rb +5 -1
  20. data/lib/fortitude/rails/rendering_methods.rb +66 -47
  21. data/lib/fortitude/rails/template_handler.rb +0 -1
  22. data/lib/fortitude/rendering_context.rb +2 -2
  23. data/lib/fortitude/tags/tag.rb +4 -3
  24. data/lib/fortitude/version.rb +1 -1
  25. data/lib/fortitude/widget.rb +1 -1
  26. data/lib/fortitude/widget/content.rb +1 -1
  27. data/lib/fortitude/widget/integration.rb +12 -3
  28. data/lib/fortitude/widget/localization.rb +1 -37
  29. data/lib/fortitude/widget/needs.rb +41 -12
  30. data/lib/fortitude/widget/rendering.rb +25 -7
  31. data/lib/fortitude/widget/start_and_end_comments.rb +1 -0
  32. data/lib/fortitude/widget/tags.rb +2 -1
  33. data/lib/fortitude/widget/widget_class_inheritable_attributes.rb +1 -0
  34. data/lib/fortitude_jruby_native_ext.jar +0 -0
  35. data/spec/helpers/system_helpers.rb +4 -0
  36. data/spec/rails/class_loading_system_spec.rb +10 -2
  37. data/spec/rails/development_mode_system_spec.rb +91 -0
  38. data/spec/rails/erector_coexistence_system_spec.rb +16 -0
  39. data/spec/rails/layouts_system_spec.rb +8 -3
  40. data/spec/rails/rendering_system_spec.rb +24 -2
  41. data/spec/rails/templates/class_loading_system_spec/app/controllers/class_loading_system_spec_controller.rb +6 -2
  42. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/_foo.rb +5 -0
  43. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/bar.html.rb +5 -0
  44. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/bar.rb +5 -0
  45. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/foo.rb +5 -0
  46. data/spec/rails/templates/development_mode_system_spec/app/controllers/development_mode_system_spec_controller.rb +4 -0
  47. data/spec/rails/templates/development_mode_system_spec/app/views/base.rb +5 -0
  48. data/spec/rails/templates/development_mode_system_spec/app/views/development_mode_system_spec/form.rb +11 -0
  49. data/spec/rails/templates/erector_coexistence_system_spec/app/controllers/erector_coexistence_system_spec_controller.rb +16 -0
  50. data/spec/rails/templates/erector_coexistence_system_spec/app/views/erector_widget.rb +5 -0
  51. data/spec/rails/templates/erector_coexistence_system_spec/app/views/fortitude_widget.rb +5 -0
  52. data/spec/rails/templates/localization_system_spec/app/views/localization_system_spec/content_method.rb +2 -0
  53. data/spec/rails/templates/rendering_system_spec/app/controllers/rendering_system_spec_controller.rb +14 -1
  54. data/spec/rails/templates/rendering_system_spec/app/helpers/application_helper.rb +5 -0
  55. data/spec/rails/templates/rendering_system_spec/app/views/widget_to_render_class_only.rb +5 -0
  56. data/spec/rails/templates/rendering_system_spec/app/views/widget_to_render_with_helper.rb +5 -0
  57. data/spec/system/doctypes_system_spec.rb +30 -8
  58. data/spec/system/erector_compatibility_system_spec.rb +27 -0
  59. data/spec/system/localization_system_spec.rb +4 -0
  60. data/spec/system/needs_system_spec.rb +31 -0
  61. data/spec/system/rebuild_notifications_system_spec.rb +180 -85
  62. data/spec/system/setting_inheritance_system_spec.rb +47 -0
  63. data/spec/system/static_method_system_spec.rb +2 -0
  64. data/spec/system/tag_rendering_system_spec.rb +41 -0
  65. data/spec/system/void_tags_system_spec.rb +1 -0
  66. data/spec/system/yield_system_spec.rb +188 -0
  67. metadata +27 -5
  68. data/lib/fortitude/method_templates/simple_template.rb +0 -50
  69. data/spec/rails/templates/class_loading_system_spec/app/views/class_loading_system_spec/_underscore_widget.rb +0 -11
@@ -50,7 +50,7 @@ module Fortitude
50
50
  end
51
51
 
52
52
  rebuild_run_content!(:initial_setup)
53
- rebuild_needs!(:initial_setup)
53
+ invalidate_needs!(:initial_setup)
54
54
  rebuild_text_methods!(:initial_setup)
55
55
  end
56
56
  end
@@ -27,7 +27,7 @@ module Fortitude
27
27
  text += " " + (" " * index) + "#{method_name}(*args) do\n"
28
28
  end
29
29
 
30
- if has_localized_content_methods?
30
+ if use_localized_content_methods
31
31
  text += " " + (" " * acm.length) + "the_locale = widget_locale\n"
32
32
  text += " " + (" " * acm.length) + "locale_method_name = \"localized_content_\#{the_locale}\" if the_locale\n"
33
33
  text += " " + (" " * acm.length) + "out = if locale_method_name && respond_to?(locale_method_name)\n"
@@ -1,7 +1,7 @@
1
1
  require 'active_support'
2
2
  require 'active_support/concern'
3
3
 
4
- require 'fortitude/method_templates/simple_template'
4
+ require 'fortitude/method_templates/simple_compiled_template'
5
5
 
6
6
  module Fortitude
7
7
  class Widget
@@ -15,10 +15,15 @@ module Fortitude
15
15
  end
16
16
  private :rebuilding
17
17
 
18
+ def invalidating(what, why, klass, &block)
19
+ ActiveSupport::Notifications.instrument("fortitude.invalidating", :what => what, :why => why, :originating_class => klass, :class => self, &block)
20
+ end
21
+ private :invalidating
22
+
18
23
  # INTERNAL USE ONLY
19
24
  def rebuild_text_methods!(why, klass = self)
20
25
  rebuilding(:text_methods, why, klass) do
21
- class_eval(Fortitude::MethodTemplates::SimpleTemplate.template('text_method_template').result(
26
+ class_eval(Fortitude::MethodTemplates::SimpleCompiledTemplate.template('text_method_template').result(
22
27
  :format_output => format_output,
23
28
  :record_emitting_tag => self._fortitude_record_emitting_tag?))
24
29
  direct_subclasses.each { |s| s.rebuild_text_methods!(why, klass) }
@@ -54,7 +59,7 @@ module Fortitude
54
59
 
55
60
  _fortitude_on_class_inheritable_attribute_change(
56
61
  :debug, :extra_assigns, :use_instance_variables_for_assigns) do |attribute_name, old_value, new_value|
57
- rebuild_needs!(:"#{attribute_name}_changed")
62
+ invalidate_needs!(:"#{attribute_name}_changed")
58
63
  end
59
64
 
60
65
  _fortitude_on_class_inheritable_attribute_change(:implicit_shared_variable_access) do |attribute_name, old_value, new_value|
@@ -72,6 +77,10 @@ module Fortitude
72
77
  remove_around_content :start_and_end_comments, :fail_if_not_present => false
73
78
  end
74
79
  end
80
+
81
+ _fortitude_on_class_inheritable_attribute_change(:use_localized_content_methods) do |attribute_name, old_value, new_value|
82
+ rebuild_run_content!(:use_localized_content_methods_changed)
83
+ end
75
84
  end
76
85
  end
77
86
  end
@@ -6,43 +6,7 @@ module Fortitude
6
6
  module Localization
7
7
  extend ActiveSupport::Concern
8
8
 
9
- module ClassMethods
10
- # RUBY CALLBACK
11
- def method_added(method_name)
12
- super(method_name)
13
- check_localized_methods!
14
- end
15
-
16
- # RUBY CALLBACK
17
- def method_removed(method_name)
18
- super(method_name)
19
- check_localized_methods!
20
- end
21
-
22
- # RUBY CALL
23
- def include(*args)
24
- super(*args)
25
- check_localized_methods!
26
- end
27
-
28
- LOCALIZED_CONTENT_PREFIX = "localized_content_"
29
-
30
- # INTERNAL USE ONLY
31
- def check_localized_methods!(original_class = self)
32
- currently_has = instance_methods(true).detect { |i| i =~ /^#{LOCALIZED_CONTENT_PREFIX}/i }
33
- if currently_has != @last_localized_methods_check_has
34
- @last_localized_methods_check_has = currently_has
35
- rebuild_run_content!(:localized_methods_presence_changed, original_class)
36
- end
37
- direct_subclasses.each { |s| s.check_localized_methods!(original_class) }
38
- end
39
-
40
- # INTERNAL USE ONLY
41
- def has_localized_content_methods?
42
- !! (instance_methods(true).detect { |i| i =~ /^#{LOCALIZED_CONTENT_PREFIX}/i })
43
- end
44
- private :has_localized_content_methods?
45
- end
9
+ LOCALIZED_CONTENT_PREFIX = "localized_content_"
46
10
 
47
11
  # PUBLIC API
48
12
  def t(key, *args)
@@ -1,7 +1,7 @@
1
1
  require 'active_support'
2
2
  require 'active_support/concern'
3
3
 
4
- require 'fortitude/method_templates/simple_template'
4
+ require 'fortitude/method_templates/simple_compiled_template'
5
5
  require 'fortitude/support/assigns_proxy'
6
6
 
7
7
  module Fortitude
@@ -45,7 +45,7 @@ module Fortitude
45
45
  @this_class_needs[name] = default_value.freeze
46
46
  end
47
47
 
48
- rebuild_needs!(:need_declared)
48
+ invalidate_needs!(:need_declared)
49
49
 
50
50
  needs_as_hash
51
51
  end
@@ -65,11 +65,11 @@ module Fortitude
65
65
  end
66
66
 
67
67
  # INTERNAL USE ONLY
68
- def rebuild_needs!(why, klass = self)
69
- rebuilding(:needs, why, klass) do
68
+ def invalidate_needs!(why, klass = self)
69
+ invalidating(:needs, why, klass) do
70
70
  @_fortitude_needs_as_hash = nil
71
- rebuild_my_needs_methods!
72
- direct_subclasses.each { |s| s.rebuild_needs!(why, klass) }
71
+ invalidate_my_needs_methods!
72
+ direct_subclasses.each { |s| s.invalidate_needs!(why, klass) }
73
73
  end
74
74
  end
75
75
 
@@ -96,30 +96,59 @@ module Fortitude
96
96
  end
97
97
 
98
98
  # INTERNAL USE ONLY
99
+ def invalidate_my_needs_methods!
100
+ @_fortitude_my_needs_methods_valid = false
101
+ end
102
+
103
+ def ensure_needs_methods_are_valid!(originating_class = self)
104
+ out = false
105
+ out ||= superclass.ensure_needs_methods_are_valid!(originating_class) if superclass.respond_to?(:ensure_needs_methods_are_valid!)
106
+
107
+ unless @_fortitude_my_needs_methods_valid
108
+ rebuilding(:needs, :invalid, originating_class) do
109
+ rebuild_my_needs_methods!
110
+ @_fortitude_my_needs_methods_valid = true
111
+ end
112
+
113
+ out = true
114
+ end
115
+
116
+ out
117
+ end
118
+
99
119
  def rebuild_my_needs_methods!
100
120
  n = needs_as_hash
101
121
 
122
+ start_time = Time.now
102
123
  needs_text = n.map do |need, default_value|
103
- Fortitude::MethodTemplates::SimpleTemplate.template('need_assignment_template').result(:extra_assigns => extra_assigns,
124
+ Fortitude::MethodTemplates::SimpleCompiledTemplate.template('need_assignment_template').result(:extra_assigns => extra_assigns,
104
125
  :need => need, :has_default => (default_value != REQUIRED_NEED),
105
126
  :ivar_name => instance_variable_name_for_need(need)
106
127
  )
107
128
  end.join("\n\n")
108
129
 
109
- assign_locals_from_text = Fortitude::MethodTemplates::SimpleTemplate.template('assign_locals_from_template').result(
130
+ assign_locals_from_text = Fortitude::MethodTemplates::SimpleCompiledTemplate.template('assign_locals_from_template').result(
110
131
  :extra_assigns => extra_assigns, :needs_text => needs_text)
111
- class_eval(assign_locals_from_text)
112
132
 
133
+ needs_methods_text = ""
113
134
  n.each do |need, default_value|
114
- text = Fortitude::MethodTemplates::SimpleTemplate.template('need_method_template').result(
135
+ needs_methods_text << (Fortitude::MethodTemplates::SimpleCompiledTemplate.template('need_method_template').result(
115
136
  :need => need, :ivar_name => instance_variable_name_for_need(need),
116
- :debug => self.debug)
117
- needs_module.module_eval(text)
137
+ :debug => self.debug))
118
138
  end
139
+
140
+ class_eval(assign_locals_from_text)
141
+ needs_module.module_eval(needs_methods_text)
119
142
  end
143
+
120
144
  private :rebuild_my_needs_methods!
121
145
  end
122
146
 
147
+ def assign_locals_from(assigns)
148
+ self.class.ensure_needs_methods_are_valid!
149
+ assign_locals_from(assigns)
150
+ end
151
+
123
152
  # PUBLIC API
124
153
  def shared_variables
125
154
  @_fortitude_rendering_context.instance_variable_set
@@ -23,17 +23,19 @@ module Fortitude
23
23
  end
24
24
  end
25
25
 
26
- def render_to(rendering_context)
26
+ def render_to(rendering_context, &block_for_content_method)
27
27
  @_fortitude_rendering_context = rendering_context
28
28
  @_fortitude_output_buffer_holder = rendering_context.output_buffer_holder
29
+ @_fortitude_block_for_content_method = block_for_content_method
29
30
 
30
- block = lambda { |*args| @_fortitude_rendering_context.yield_from_widget(*args) }
31
+ block = lambda { |*args| yield_from_widget(*args) }
31
32
 
32
33
  rendering_context.record_widget(self) do
33
34
  begin
34
35
  run_content(&block)
35
36
  ensure
36
37
  @_fortitude_rendering_context = nil
38
+ @_fortitude_block_for_content_method = nil
37
39
  end
38
40
  end
39
41
  end
@@ -50,12 +52,12 @@ module Fortitude
50
52
  end
51
53
 
52
54
  # PUBLIC API
53
- def widget(w, hash = nil)
55
+ def widget(w, hash = nil, &block)
54
56
  if w.respond_to?(:render_to)
55
- w.render_to(@_fortitude_rendering_context)
57
+ w.render_to(@_fortitude_rendering_context, &block)
56
58
  elsif w.kind_of?(Class)
57
59
  hash ||= { }
58
- w.new(hash).render_to(@_fortitude_rendering_context)
60
+ w.new(hash, &block).render_to(@_fortitude_rendering_context)
59
61
  else
60
62
  raise "You tried to render a widget, but this is not valid: #{w.inspect}(#{hash.inspect})"
61
63
  end
@@ -67,8 +69,9 @@ module Fortitude
67
69
  end
68
70
 
69
71
  # PUBLIC API
70
- def initialize(assigns = { })
72
+ def initialize(assigns = { }, &block)
71
73
  assign_locals_from(assigns)
74
+ @_fortitude_constructor_block = block
72
75
  end
73
76
 
74
77
  # INTERNAL USE ONLY
@@ -96,9 +99,24 @@ module Fortitude
96
99
  end
97
100
  private :_fortitude_class_for_new_buffer
98
101
 
102
+ def _fortitude_yield_from_widget(*args)
103
+ if @_fortitude_block_for_content_method
104
+ @_fortitude_block_for_content_method.call(*args)
105
+ elsif @_fortitude_constructor_block
106
+ @_fortitude_constructor_block.call(*args)
107
+ else
108
+ @_fortitude_rendering_context.yield_from_widget(*args)
109
+ end
110
+ end
111
+
99
112
  # PUBLIC API
100
113
  def yield_from_widget(*args)
101
- @_fortitude_rendering_context.yield_from_widget(*args)
114
+ _fortitude_yield_from_widget(self, *args)
115
+ end
116
+
117
+ # PUBLIC API (Erector compatibility)
118
+ def call_block
119
+ _fortitude_yield_from_widget
102
120
  end
103
121
  end
104
122
  end
@@ -35,6 +35,7 @@ module Fortitude
35
35
  out << "(DEFAULT) " if assigns.is_default?(assign)
36
36
 
37
37
  value_string = if value.respond_to?(:to_fortitude_comment_string) then value.to_fortitude_comment_string else value.inspect end
38
+ value_string ||= ''
38
39
  if value_string.length > MAX_START_COMMENT_VALUE_STRING_LENGTH
39
40
  value_string = value_string[0..(MAX_START_COMMENT_VALUE_STRING_LENGTH - START_COMMENT_VALUE_STRING_TOO_LONG_ELLIPSIS.length)] + START_COMMENT_VALUE_STRING_TOO_LONG_ELLIPSIS
40
41
  end
@@ -48,7 +48,8 @@ module Fortitude
48
48
  :record_emitting_tag => self._fortitude_record_emitting_tag?,
49
49
  :enforce_attribute_rules => self.enforce_attribute_rules,
50
50
  :enforce_id_uniqueness => self.enforce_id_uniqueness,
51
- :close_void_tags => self.close_void_tags)
51
+ :close_void_tags => self.close_void_tags,
52
+ :allows_bare_attributes => self.doctype.allows_bare_attributes?)
52
53
  end
53
54
 
54
55
  direct_subclasses.each { |s| s.rebuild_tag_methods!(why, which_tags_in, klass) }
@@ -30,6 +30,7 @@ module Fortitude
30
30
  end
31
31
  end)
32
32
  _fortitude_class_inheritable_attribute :debug, false, [ true, false ]
33
+ _fortitude_class_inheritable_attribute :use_localized_content_methods, false, [ true, false ]
33
34
  end
34
35
 
35
36
  module ClassMethods
Binary file
@@ -42,6 +42,10 @@ module SystemHelpers
42
42
  { }
43
43
  end
44
44
 
45
+ def allows_bare_attributes?
46
+ true
47
+ end
48
+
45
49
  def needs_cdata_in_javascript_tag?
46
50
  false
47
51
  end
@@ -45,10 +45,18 @@ describe "Rails class-loading support", :type => :rails do
45
45
  expect_exception('underscore_view', 'ActionView::MissingTemplate', /class_loading_system_spec\/underscore_view/)
46
46
  end
47
47
 
48
- it "should not let me define a widget in a file starting with an underscore, and autoload it" do
49
- expect_exception('underscore_widget', 'NameError', /uninitialized constant Views::ClassLoadingSystemSpec::UnderscoreWidget/)
48
+ it "should prefer widgets defined in a file without an underscore to those with" do
49
+ expect_match('foo', /foo WITHOUT underscore/)
50
50
  end
51
51
 
52
+ it "should prefer widgets ending in .html.rb to those just ending in .rb" do
53
+ expect_match('bar', /bar WITH html/)
54
+ end
55
+
56
+ # it "should not let me define a widget in a file starting with an underscore, and autoload it" do
57
+ # expect_exception('underscore_widget', 'NameError', /uninitialized constant Views::ClassLoadingSystemSpec::UnderscoreWidget/)
58
+ # end
59
+
52
60
  it "should not let me 'require' files in app/views without a views/ prefix" do
53
61
  expect_exception('require_loaded_underscore_widget_without_views', 'LoadError', /(cannot load such file|no such file to load)/)
54
62
  end
@@ -82,7 +82,98 @@ describe "Rails development-mode support", :type => :rails do
82
82
  expect_match("namespace_reference", /before.*referenced.*after/mi)
83
83
  end
84
84
 
85
+ it "should allow you to toggle back and forth between two forms of referencing a superclass" do
86
+ current_form = :full_reference
87
+ 5.times do
88
+ if current_form == :full_reference
89
+ splat_full_reference_edit!
90
+ else
91
+ splat_partial_reference_edit!
92
+ end
93
+
94
+ sleep 1
95
+ $stderr.puts "checking for #{current_form.inspect}"
96
+ expect_match("edit", /#{Regexp.escape(current_form.to_s)}/i)
97
+
98
+ current_form = if current_form == :full_reference
99
+ :partial_reference
100
+ else
101
+ :full_reference
102
+ end
103
+ end
104
+ end
105
+
85
106
  private
107
+ def splat_full_reference_edit!
108
+ widget_file = File.join(rails_server.rails_root, "app/views/development_mode_system_spec/edit.rb")
109
+ File.open(widget_file, 'w') do |f|
110
+ f.puts <<-EOS
111
+ module Views
112
+ module DevelopmentModeSystemSpec
113
+ if const_defined?(:Edit)
114
+ $stderr.puts "(full) Edit constant: \#{const_get(:Edit).inspect}"
115
+ $stderr.puts "(full) Edit superclass: \#{const_get(:Edit).superclass}/\#{const_get(:Edit).superclass.object_id}"
116
+
117
+ if (::Views.const_defined?(:Base))
118
+ $stderr.puts "(full) Views::Base already defined: \#{::Views::Base.object_id}"
119
+ else
120
+ $stderr.puts "(full) Views::Base not defined"
121
+ end
122
+
123
+ $stderr.puts "(full) ::Views::Base: \#{::Views::Base.name}/\#{::Views::Base.object_id}"
124
+ $stderr.puts "(full) Views::Base: \#{Views::Base.name}/\#{Views::Base.object_id}"
125
+ else
126
+ $stderr.puts "(full) No edit constant!"
127
+ end
128
+
129
+ class Edit < Views::Base
130
+ def content
131
+ widget(Views::DevelopmentModeSystemSpec::Form, :label => "full_reference")
132
+ end
133
+ end
134
+
135
+ $stderr.puts "(full) After definition: \#{::Views::Base.object_id}"
136
+ end
137
+ end
138
+ EOS
139
+ end
140
+ end
141
+
142
+ def splat_partial_reference_edit!
143
+ widget_file = File.join(rails_server.rails_root, "app/views/development_mode_system_spec/edit.rb")
144
+ File.open(widget_file, 'w') do |f|
145
+ f.puts <<-EOS
146
+ module Views
147
+ module DevelopmentModeSystemSpec
148
+ if const_defined?(:Edit)
149
+ $stderr.puts "(partial) Edit constant: \#{const_get(:Edit).inspect}"
150
+ $stderr.puts "(partial) Edit superclass: \#{const_get(:Edit).superclass}/\#{const_get(:Edit).superclass.object_id}"
151
+
152
+ if (::Views.const_defined?(:Base))
153
+ $stderr.puts "(partial) Views::Base already defined: \#{::Views::Base.object_id}"
154
+ else
155
+ $stderr.puts "(partial) Views::Base not defined"
156
+ end
157
+
158
+ $stderr.puts "(partial) ::Views::Base: \#{::Views::Base.name}/\#{::Views::Base.object_id}"
159
+ $stderr.puts "(partial) Views::Base: \#{Views::Base.name}/\#{Views::Base.object_id}"
160
+ else
161
+ $stderr.puts "(partial) No edit constant!"
162
+ end
163
+
164
+ class Edit < Views::Base
165
+ def content
166
+ widget(Form, :label => "partial_reference")
167
+ end
168
+ end
169
+
170
+ $stderr.puts "(partial) After definition: \#{::Views::Base.object_id}"
171
+ end
172
+ end
173
+ EOS
174
+ end
175
+ end
176
+
86
177
  def splat_new_widget!
87
178
  reload_file = File.join(rails_server.rails_root, 'app/views/development_mode_system_spec/reload_widget.rb')
88
179
  File.open(reload_file, 'w') do |f|