fortitude 0.0.4 → 0.0.5

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +19 -19
  3. data/CHANGES.md +31 -0
  4. data/Gemfile +1 -0
  5. data/README-erector.md +1 -1
  6. data/lib/fortitude/erector.rb +32 -0
  7. data/lib/fortitude/method_templates/tag_method_template.rb.smpl +6 -6
  8. data/lib/fortitude/method_templates/text_method_template.rb.smpl +3 -3
  9. data/lib/fortitude/rails/railtie.rb +6 -4
  10. data/lib/fortitude/rails/renderer.rb +7 -4
  11. data/lib/fortitude/rails/template_handler.rb +18 -3
  12. data/lib/fortitude/rendering_context.rb +20 -2
  13. data/lib/fortitude/tags/render_widget_placeholder.rb +19 -0
  14. data/lib/fortitude/tags/tag.rb +18 -4
  15. data/lib/fortitude/tags/tag_return_value.rb +1 -1
  16. data/lib/fortitude/tags/tag_store.rb +4 -0
  17. data/lib/fortitude/tilt/fortitude_template.rb +6 -128
  18. data/lib/fortitude/version.rb +1 -1
  19. data/lib/fortitude/widget.rb +2 -0
  20. data/lib/fortitude/widget/files.rb +162 -0
  21. data/lib/fortitude/widget/integration.rb +5 -3
  22. data/lib/fortitude/widget/modules_and_subclasses.rb +17 -0
  23. data/lib/fortitude/widget/rendering.rb +12 -5
  24. data/lib/fortitude/widget/start_and_end_comments.rb +4 -2
  25. data/lib/fortitude/widget/tags.rb +6 -1
  26. data/lib/fortitude/widget/widget_class_inheritable_attributes.rb +7 -0
  27. data/spec/helpers/rails_server.rb +4 -0
  28. data/spec/rails/basic_rails_system_spec.rb +4 -0
  29. data/spec/rails/erector_coexistence_system_spec.rb +33 -0
  30. data/spec/rails/rendering_context_system_spec.rb +19 -3
  31. data/spec/rails/rendering_system_spec.rb +6 -0
  32. data/spec/rails/templates/basic_rails_system_spec/app/controllers/basic_rails_system_spec_controller.rb +5 -0
  33. data/spec/rails/templates/basic_rails_system_spec/app/views/basic_rails_system_spec/double_render_one.rb +5 -0
  34. data/spec/rails/templates/basic_rails_system_spec/app/views/basic_rails_system_spec/double_render_three.rb +5 -0
  35. data/spec/rails/templates/basic_rails_system_spec/app/views/basic_rails_system_spec/double_render_two.rb +9 -0
  36. data/spec/rails/templates/erector_coexistence_system_spec/app/controllers/erector_coexistence_system_spec_controller.rb +19 -0
  37. data/spec/rails/templates/erector_coexistence_system_spec/app/v/views/erector_coexistence_system_spec/erector_widget_in_app_v_views.rb +7 -0
  38. data/spec/rails/templates/erector_coexistence_system_spec/app/v/views/erector_coexistence_system_spec/fortitude_widget_in_app_v_views.rb +7 -0
  39. data/spec/rails/templates/erector_coexistence_system_spec/app/views/erector_coexistence_system_spec/erector_widget_in_app_views.rb +7 -0
  40. data/spec/rails/templates/erector_coexistence_system_spec/app/views/erector_coexistence_system_spec/fortitude_widget_in_app_views.rb +7 -0
  41. data/spec/rails/templates/erector_coexistence_system_spec/config/application.rb +25 -0
  42. data/spec/rails/templates/rendering_context_system_spec/app/controllers/rendering_context_system_spec_controller.rb +2 -2
  43. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/_current_element_nesting_intermediate.html.erb +3 -0
  44. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/current_element_nesting_child.rb +13 -0
  45. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/current_element_nesting_toplevel.rb +9 -0
  46. data/spec/rails/templates/rendering_context_system_spec/app/views/rendering_context_system_spec/start_end_widget_through_partials.rb +2 -2
  47. data/spec/system/convenience_methods_system_spec.rb +22 -0
  48. data/spec/system/inline_system_spec.rb +2 -2
  49. data/spec/system/record_tag_emission_system_spec.rb +71 -0
  50. data/spec/system/rendering_context_system_spec.rb +21 -0
  51. data/spec/system/setting_inheritance_system_spec.rb +52 -0
  52. data/spec/system/tag_return_value_system_spec.rb +7 -0
  53. data/spec/system/tilt_system_spec.rb +13 -18
  54. data/spec/system/widget_class_from_spec.rb +240 -0
  55. data/spec/system/widget_method_system_spec.rb +52 -0
  56. metadata +37 -2
@@ -139,6 +139,30 @@ describe "Fortitude setting inheritance", :type => :system do
139
139
  end
140
140
 
141
141
 
142
+ def record_tag_emission_should_be(expected_result, *klasses)
143
+ klasses.each do |klass|
144
+ expect(klass.record_tag_emission).to eq(expected_result)
145
+ send("record_tag_emission_should_be_#{expected_result}", klass)
146
+ end
147
+ end
148
+
149
+ def record_tag_emission_should_be_true(klass)
150
+ instance = klass.new
151
+ expect(render(instance)).to eq("<p><div></div></p>")
152
+ nesting = instance.inner_element_nesting
153
+ expect(nesting.shift).to be(instance)
154
+ expect(nesting.map(&:name)).to eq([ :p, :div ])
155
+ end
156
+
157
+ def record_tag_emission_should_be_false(klass)
158
+ instance = klass.new
159
+ expect(render(instance)).to eq("<p><div></div></p>")
160
+ nesting = instance.inner_element_nesting
161
+ expect(nesting.shift).to be(instance)
162
+ expect(nesting).to eq([ ])
163
+ end
164
+
165
+
142
166
  def format_output_should_be(expected_result, *klasses)
143
167
  klasses.each do |klass|
144
168
  expect(klass.format_output).to eq(expected_result)
@@ -405,6 +429,34 @@ describe "Fortitude setting inheritance", :type => :system do
405
429
  enforce_element_nesting_rules_should_be(true, @parent1, @child11, @child12)
406
430
  end
407
431
 
432
+ it "should properly inherit record_tag_emission" do
433
+ @grandparent.class_eval do
434
+ attr_reader :inner_element_nesting
435
+
436
+ def content
437
+ p { div { @inner_element_nesting = rendering_context.current_element_nesting.dup } }
438
+ end
439
+ end
440
+
441
+ record_tag_emission_should_be(false, @grandparent, @parent1, @child11, @child12, @parent2, @child21, @child22)
442
+
443
+ @parent1.record_tag_emission true
444
+ record_tag_emission_should_be(false, @grandparent, @parent2, @child21, @child22)
445
+ record_tag_emission_should_be(true, @parent1, @child11, @child12)
446
+
447
+ @parent2.record_tag_emission false
448
+ record_tag_emission_should_be(false, @grandparent, @parent2, @child21, @child22)
449
+ record_tag_emission_should_be(true, @parent1, @child11, @child12)
450
+
451
+ @grandparent.record_tag_emission true
452
+ record_tag_emission_should_be(false, @parent2, @child21, @child22)
453
+ record_tag_emission_should_be(true, @grandparent, @parent1, @child11, @child12)
454
+
455
+ @grandparent.record_tag_emission false
456
+ record_tag_emission_should_be(false, @grandparent, @parent2, @child21, @child22)
457
+ record_tag_emission_should_be(true, @parent1, @child11, @child12)
458
+ end
459
+
408
460
  it "should properly inherit translation_base" do
409
461
  @grandparent.class_eval do
410
462
  def content
@@ -38,4 +38,11 @@ describe "Fortitude tag return values", :type => :system do
38
38
  expect_nrv(:foo) { p("foo", :foo => :bar) { text "whatever" }.foo }
39
39
  end
40
40
  end
41
+
42
+ context "should not blow up when calling" do
43
+ it "#is_a?" do
44
+ wc = widget_class_with_content { text("value: #{p.is_a?(String).inspect}") }
45
+ expect(render(wc)).to eq("<p></p>value: false")
46
+ end
47
+ end
41
48
  end
@@ -308,14 +308,14 @@ EOS
308
308
  end
309
309
 
310
310
  it "should fail with a nice message if it can't figure out which class to render" do
311
- e = capture_exception(Fortitude::Tilt::CannotDetermineTemplateClassError) do
311
+ e = capture_exception(Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
312
312
  render_text_with_tilt("random_#{rand(1_000_000)}.rb", impossible_to_find_class_name_text(5), context_object, { })
313
313
  end
314
314
 
315
315
  expect(e).to be
316
316
  expect(e.tried_class_names).to eq([ ])
317
- expect(e.message).to match(/\#\!fortitude_tilt_class/)
318
- expect(e.message).to match(/:fortitude_class/)
317
+ expect(e.message).to match(/fortitude_tilt_class/)
318
+ expect(e.message).to match(/:class_names_to_try/)
319
319
  end
320
320
 
321
321
  it "should allow overriding the class that's defined in the module explicitly with an option" do
@@ -325,32 +325,29 @@ EOS
325
325
  end
326
326
 
327
327
  it "should fail with a nice message if you tell it to use something that doesn't exist, using an option" do
328
- e = capture_exception(Fortitude::Tilt::NotATemplateClassError) do
328
+ e = capture_exception(Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
329
329
  render_text_with_tilt("random_#{rand(1_000_000)}.rb", impossible_to_find_class_name_text(7), context_object, { },
330
330
  { :fortitude_class => "NonExistent" })
331
331
  end
332
- expect(e.class_name).to eq("NonExistent")
333
- expect(e.actual_object).to be_nil
332
+ expect(e.tried_class_names).to be_include("NonExistent")
334
333
  expect(e.message).to match(/NonExistent/)
335
334
  end
336
335
 
337
336
  it "should fail with a nice message if you tell it to use something that isn't a class, using an option" do
338
- e = capture_exception(Fortitude::Tilt::NotATemplateClassError) do
337
+ e = capture_exception(Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
339
338
  render_text_with_tilt("random_#{rand(1_000_000)}.rb", impossible_to_find_class_name_text(8), context_object, { },
340
339
  { :fortitude_class => 12345 })
341
340
  end
342
- expect(e.class_name).to eq(12345)
343
- expect(e.actual_object).to eq(12345)
341
+ expect(e.tried_class_names).to be_include(12345)
344
342
  expect(e.message).to match(/12345/)
345
343
  end
346
344
 
347
345
  it "should fail with a nice message if you tell it to use something that isn't a widget class, using an option" do
348
- e = capture_exception(Fortitude::Tilt::NotATemplateClassError) do
346
+ e = capture_exception(Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
349
347
  render_text_with_tilt("random_#{rand(1_000_000)}.rb", impossible_to_find_class_name_text(9), context_object, { },
350
348
  { :fortitude_class => "String" })
351
349
  end
352
- expect(e.class_name).to eq("String")
353
- expect(e.actual_object).to eq(String)
350
+ expect(e.tried_class_names).to be_include("String")
354
351
  expect(e.message).to match(/String/)
355
352
  end
356
353
 
@@ -361,22 +358,20 @@ EOS
361
358
  end
362
359
 
363
360
  it "should fail with a nice message if you tell it to use something that isn't a class, using a comment in the template" do
364
- e = capture_exception(Fortitude::Tilt::NotATemplateClassError) do
361
+ e = capture_exception(Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
365
362
  render_text_with_tilt("random_#{rand(1_000_000)}.rb",
366
363
  impossible_to_find_class_name_text(11, "#!fortitude_tilt_class: 12345"), context_object, { })
367
364
  end
368
- expect(e.class_name).to eq("12345")
369
- expect(e.actual_object).to be_nil
365
+ expect(e.tried_class_names).to be_include("12345")
370
366
  expect(e.message).to match(/12345/)
371
367
  end
372
368
 
373
369
  it "should fail with a nice message if you tell it to use something that isn't a widget class, using a comment in the template" do
374
- e = capture_exception(Fortitude::Tilt::NotATemplateClassError) do
370
+ e = capture_exception(Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
375
371
  render_text_with_tilt("random_#{rand(1_000_000)}.rb",
376
372
  impossible_to_find_class_name_text(12, "#!fortitude_tilt_class: String"), context_object, { })
377
373
  end
378
- expect(e.class_name).to eq("String")
379
- expect(e.actual_object).to eq(String)
374
+ expect(e.tried_class_names).to be_include("String")
380
375
  expect(e.message).to match(/String/)
381
376
  end
382
377
  end
@@ -0,0 +1,240 @@
1
+ require 'fileutils'
2
+
3
+ describe "Fortitude widget-class-from-(file|source) support", :type => :system do
4
+ def tempdir
5
+ @tempdir ||= begin
6
+ out = File.join(File.dirname(File.dirname(File.dirname(__FILE__))), 'tmp', 'spec', 'widget_class_from_spec')
7
+ FileUtils.rm_rf(out)
8
+ FileUtils.mkdir_p(out)
9
+ out
10
+ end
11
+ end
12
+
13
+ def splat!(filename, text)
14
+ full_path = File.join(tempdir, filename)
15
+ FileUtils.mkdir_p(File.dirname(full_path))
16
+ File.open(full_path, 'w') { |f| f << text }
17
+ full_path
18
+ end
19
+
20
+ def wcfs(*args)
21
+ ::Fortitude::Widget.widget_class_from_source(*args)
22
+ end
23
+
24
+ def wcff(filename, *args)
25
+ filename = File.join(tempdir, filename)
26
+ ::Fortitude::Widget.widget_class_from_file(filename, *args)
27
+ end
28
+
29
+ context "with no hints" do
30
+ it "should return a widget subclass that's already been evaluated" do
31
+ text = "class WidgetFromClass1 < Fortitude::Widget; end"
32
+ ::Object.class_eval(text)
33
+ expect(wcfs(text)).to eq(::WidgetFromClass1)
34
+ end
35
+
36
+ it "should automatically evaluate the source, if needed" do
37
+ text = "class WidgetFromClass2 < Fortitude::Widget; end"
38
+ expect(wcfs(text)).to eq(::WidgetFromClass2)
39
+ end
40
+
41
+ it "should fail if given source code it can't guess the class name from" do
42
+ expect do
43
+ wcfs("cname = 'WidgetFromCla' + 'ss3'; eval('class ' + cname + ' < ::Fortitude::Widget; end')")
44
+ end.to raise_error(::Fortitude::Widget::Files::CannotDetermineWidgetClassNameError)
45
+ end
46
+
47
+ it "should fail if the source code contains something that isn't a widget class" do
48
+ cdne = capture_exception(::Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
49
+ wcfs("class WidgetFromClass11; end")
50
+ end
51
+ expect(cdne.tried_class_names).to be_include("WidgetFromClass11")
52
+ end
53
+
54
+ it "should work if given something that's a grandchild of Fortitude::Widget, not a direct child" do
55
+ ::Object.class_eval("class WidgetFromClass12Parent < ::Fortitude::Widget; end")
56
+ expect(wcfs("class WidgetFromClass12 < WidgetFromClass12Parent; end")).to eq(WidgetFromClass12)
57
+ end
58
+
59
+ it "should be able to guess the class name of a class namespaced in a module" do
60
+ module ::Wcfs1; end
61
+ expect(wcfs("class Wcfs1::WidgetFromClass6 < ::Fortitude::Widget; end")).to eq(Wcfs1::WidgetFromClass6)
62
+ end
63
+
64
+ it "should be able to guess the class name of a class nested in a module" do
65
+ expect(wcfs("module Wcfs2; class WidgetFromClass7 < ::Fortitude::Widget; end; end")).to eq(Wcfs2::WidgetFromClass7)
66
+ end
67
+
68
+ it "should be able to guess the class name of a class nested in a module several levels deep" do
69
+ expect(wcfs("module Wcfs3; module Wcfs4; class WidgetFromClass8 < ::Fortitude::Widget; end; end; end")).to eq(Wcfs3::Wcfs4::WidgetFromClass8)
70
+ end
71
+
72
+ it "should be able to guess the class name of a class nested in a module several levels deep, using newlines" do
73
+ expect(wcfs(%{module Wcfs5
74
+ module Wcfs6
75
+ class WidgetFromClass9 < ::Fortitude::Widget
76
+ end
77
+ end
78
+ end})).to eq(Wcfs5::Wcfs6::WidgetFromClass9)
79
+ end
80
+
81
+ it "should be able to guess the class name of a class with both nesting and namespacing" do
82
+ ::Object.class_eval %{module Wcfs7; module Wcfs8; module Wcfs9; end; end; end}
83
+
84
+ expect(wcfs(%{module Wcfs7
85
+ module Wcfs8
86
+ class Wcfs9::WidgetFromClass10 < ::Fortitude::Widget
87
+ end
88
+ end
89
+ end})).to eq(Wcfs7::Wcfs8::Wcfs9::WidgetFromClass10)
90
+ end
91
+ end
92
+
93
+ context "with an explicit class name provided" do
94
+ it "should be able to get a widget class, even if it can't get it by parsing the source code" do
95
+ result = wcfs("cname = 'WidgetFromCla' + 'ss4'; eval('class ' + cname + ' < ::Fortitude::Widget; end')",
96
+ :class_names_to_try => [ 'WidgetFromClass4' ])
97
+ expect(result).to eq(WidgetFromClass4)
98
+ end
99
+
100
+ it "should be able to get a widget class, even if it can't get it by parsing the source code, if passed in among a bunch of other crap" do
101
+ result = wcfs("cname = 'WidgetFromCla' + 'ss5'; eval('class ' + cname + ' < ::Fortitude::Widget; end')",
102
+ :class_names_to_try => [ 'String', 'Integer', 'Foo::Bar::Baz', 'WidgetFromClass5', 'Baz::Quux' ])
103
+ expect(result).to eq(WidgetFromClass5)
104
+ end
105
+ end
106
+
107
+ context "with a magic comment provided" do
108
+ it "should be able to get a widget class, even if it can't get it by parsing the source code" do
109
+ result = wcfs(%{#!fortitude_class: WidgetFromClass13
110
+ cname = 'WidgetFromCla' + 'ss13'; eval('class ' + cname + ' < ::Fortitude::Widget; end')})
111
+ expect(result).to eq(WidgetFromClass13)
112
+ end
113
+
114
+ it "should be able to get a widget class, even if it can't get it by parsing the source code, using an alternate magic comment text" do
115
+ result = wcfs(%{#!foo_bar_baz: WidgetFromClass14
116
+ cname = 'WidgetFromCla' + 'ss14'; eval('class ' + cname + ' < ::Fortitude::Widget; end')},
117
+ :magic_comment_text => %w{bar_baz_quux foo_bar_baz foo_Bar})
118
+ expect(result).to eq(WidgetFromClass14)
119
+ end
120
+
121
+ it "should be able to get a widget class, even if it can't get it by parsing the source code, using a standard magic comment text, even if an alternate is provided" do
122
+ result = wcfs(%{#!fortitude_class: WidgetFromClass20
123
+ cname = 'WidgetFromCla' + 'ss20'; eval('class ' + cname + ' < ::Fortitude::Widget; end')},
124
+ :magic_comment_text => %w{bar_baz_quux foo_bar_baz foo_Bar})
125
+ expect(result).to eq(WidgetFromClass20)
126
+ end
127
+
128
+ it "should be able to get a widget class, even if it can't get it by parsing the source code, even at the end" do
129
+ result = wcfs(%{
130
+ cname = 'WidgetFromCla' + 'ss15'; eval('class ' + cname + ' < ::Fortitude::Widget; end')
131
+ #!fortitude_class: WidgetFromClass15})
132
+ expect(result).to eq(WidgetFromClass15)
133
+ end
134
+
135
+ it "should not fail if it's wrong (something that doesn't exist)" do
136
+ text = %{#!fortitude_class: Whatever
137
+ class WidgetFromClass16 < Fortitude::Widget; end}
138
+ expect(wcfs(text)).to eq(::WidgetFromClass16)
139
+ end
140
+
141
+ it "should not fail if it's wrong (something that isn't a widget class)" do
142
+ text = %{#!fortitude_class: String
143
+ class WidgetFromClass17 < Fortitude::Widget; end}
144
+ expect(wcfs(text)).to eq(::WidgetFromClass17)
145
+ end
146
+
147
+ it "should tell you the magic comment texts it was looking for in the error if it can't find a class" do
148
+ cdne = capture_exception(::Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
149
+ wcfs(%{class WidgetFromClass18; end})
150
+ end
151
+ expect(cdne.magic_comment_texts).to eq(%w{fortitude_class})
152
+ end
153
+
154
+ it "should tell you the magic comment texts it was looking for in the error if it can't find a class and custom magic texts were provided" do
155
+ cdne = capture_exception(::Fortitude::Widget::Files::CannotDetermineWidgetClassNameError) do
156
+ wcfs(%{class WidgetFromClass19; end}, :magic_comment_text => %w{foo_bar bar_baz})
157
+ end
158
+ expect(cdne.magic_comment_texts).to be_include('fortitude_class')
159
+ expect(cdne.magic_comment_texts).to be_include('foo_bar')
160
+ expect(cdne.magic_comment_texts).to be_include('bar_baz')
161
+ end
162
+ end
163
+
164
+ context "when given a file" do
165
+ it "should still be able to guess the class name correctly" do
166
+ splat!('widget_from_file_1.rb', %{class WidgetFromClass21 < Fortitude::Widget; end})
167
+ expect(wcff('widget_from_file_1.rb')).to eq(WidgetFromClass21)
168
+ end
169
+
170
+ it "should still be able to use magic comments" do
171
+ splat!('widget_from_file_2.rb', %{#!fortitude_class: WidgetFromClass22\ncname = 'WidgetFromCla' + 'ss22'; eval('class ' + cname + ' < ::Fortitude::Widget; end')})
172
+ expect(wcff('widget_from_file_2.rb')).to eq(WidgetFromClass22)
173
+ end
174
+
175
+ it "should be able to use a root directory to infer a class name" do
176
+ ::Object.class_eval("module Wcfs10; module Wcfs11; end; end")
177
+ splat!('wcfs10/wcfs_11/widget_from_class_23.rb', %{cname = 'WidgetFromCla' + 'ss23'; eval('class Wcfs10::Wcfs11::' + cname + ' < ::Fortitude::Widget; end')})
178
+ expect(wcff('wcfs10/wcfs_11/widget_from_class_23.rb', :root_dirs => tempdir)).to eq(Wcfs10::Wcfs11::WidgetFromClass23)
179
+ end
180
+
181
+ it "should be able to use an array of root directories to infer a class name, and find the right one" do
182
+ ::Object.class_eval("module Wcfs10; module Wcfs11; end; end")
183
+ splat!('bar/wcfs10/wcfs_11/widget_from_class_23.rb', %{cname = 'WidgetFromCla' + 'ss23'; eval('class Wcfs10::Wcfs11::' + cname + ' < ::Fortitude::Widget; end')})
184
+ expect(wcff('bar/wcfs10/wcfs_11/widget_from_class_23.rb', :root_dirs => [ "#{tempdir}/foo", "#{tempdir}/bar" ])).to eq(Wcfs10::Wcfs11::WidgetFromClass23)
185
+ end
186
+ end
187
+
188
+ it "should prioritize a magic comment above class names you told it to try or directory-based names or scanned source text" do
189
+ splat!('widget_baz.rb', %{
190
+ #!fortitude_class: WidgetFoo
191
+
192
+ eval('class WidgetB' +
193
+ 'az < Fortitud' +
194
+ 'e::Widget; end')
195
+ eval('class WidgetB' +
196
+ 'ar < Fortitud' +
197
+ 'e::Widget; end')
198
+ class WidgetQuux < Fortitude::Widget; end
199
+ eval('class WidgetF' +
200
+ 'oo < Fortitud' +
201
+ 'e::Widget; end')
202
+ })
203
+
204
+ expect(wcff('widget_baz.rb', :root_dirs => tempdir, :class_names_to_try => %w{WidgetBar})).to eq(WidgetFoo)
205
+ end
206
+
207
+ it "should prioritize class names you told it to try above directory-based names or scanned source text" do
208
+ splat!('widget_baz.rb', %{
209
+ eval('class WidgetB' +
210
+ 'az < Fortitud' +
211
+ 'e::Widget; end')
212
+ eval('class WidgetB' +
213
+ 'ar < Fortitud' +
214
+ 'e::Widget; end')
215
+ class WidgetQuux < Fortitude::Widget; end
216
+ eval('class WidgetF' +
217
+ 'oo < Fortitud' +
218
+ 'e::Widget; end')
219
+ })
220
+
221
+ expect(wcff('widget_baz.rb', :root_dirs => tempdir, :class_names_to_try => %w{WidgetBar})).to eq(WidgetBar)
222
+ end
223
+
224
+ it "should prioritize directory-based names above scanned source text" do
225
+ splat!('widget_baz.rb', %{
226
+ eval('class WidgetB' +
227
+ 'az < Fortitud' +
228
+ 'e::Widget; end')
229
+ eval('class WidgetB' +
230
+ 'ar < Fortitud' +
231
+ 'e::Widget; end')
232
+ class WidgetQuux < Fortitude::Widget; end
233
+ eval('class WidgetF' +
234
+ 'oo < Fortitud' +
235
+ 'e::Widget; end')
236
+ })
237
+
238
+ expect(wcff('widget_baz.rb', :root_dirs => tempdir)).to eq(WidgetBaz)
239
+ end
240
+ end
@@ -0,0 +1,52 @@
1
+ describe "Fortitude::Widget#widget method", :type => :system do
2
+ let(:child_widget_class) do
3
+ widget_class do
4
+ needs :value => nil
5
+
6
+ def content
7
+ p "child widget: #{value.inspect}"
8
+ end
9
+ end
10
+ end
11
+
12
+ def parent_widget_class(&block)
13
+ out = widget_class do
14
+ class << self
15
+ attr_accessor :child_widget_class
16
+ end
17
+
18
+ def child_widget_class
19
+ self.class.child_widget_class
20
+ end
21
+
22
+ define_method(:content, &block)
23
+ end
24
+
25
+ out.child_widget_class = child_widget_class
26
+ out
27
+ end
28
+
29
+ it "should let you render one widget from another by specifying it as an instance" do
30
+ expect(render(parent_widget_class { text "before"; widget child_widget_class.new; text "after" })).to eq(
31
+ "before<p>child widget: nil</p>after")
32
+ end
33
+
34
+ it "should let you render one widget from another by specifying it as an instance, passing parameters" do
35
+ expect(render(parent_widget_class { text "before"; widget child_widget_class.new(:value => 123); text "after" })).to eq(
36
+ "before<p>child widget: 123</p>after")
37
+ end
38
+
39
+ it "should let you render one widget from another by specifying it as just a class" do
40
+ expect(render(parent_widget_class { text "before"; widget child_widget_class; text "after" })).to eq(
41
+ "before<p>child widget: nil</p>after")
42
+ end
43
+
44
+ it "should let you render one widget from another by specifying it as a class, and a hash of parameters" do
45
+ expect(render(parent_widget_class { text "before"; widget child_widget_class, :value => 123; text "after" })).to eq(
46
+ "before<p>child widget: 123</p>after")
47
+ end
48
+
49
+ it "should not let you specify anything but a Hash as the second parameter" do
50
+ expect { render(parent_widget_class { text "before"; widget child_widget_class, 123; text "after" }) }.to raise_error
51
+ end
52
+ end