fortitude 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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