ruber 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.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,328 @@
1
+ require 'spec/common'
2
+
3
+ require 'yaml'
4
+
5
+ require 'ruber/qt_sugar'
6
+
7
+ describe 'An instance of a Qt class' do
8
+
9
+ it 'should return false when the nil_object? method is called and the object is not Qt::NilObject, if its class inherits Qt::Object (in the C++ sense)' do
10
+ o = Qt::Object.new
11
+ o.should_not be_nil_object
12
+ end
13
+
14
+ it 'should raise NoMethodError when the nil_object? method is called and its class doesn\'t inherit Qt::Object (in the C++ sense)' do
15
+ lambda{Qt::Rect.new.nil_object?}.should raise_error(NoMethodError)
16
+
17
+ end
18
+
19
+ it 'should return true when the nil_object? method is called and the object is Qt::NilObject' do
20
+ Qt::NilObject.should be_nil_object
21
+ end
22
+
23
+ end
24
+
25
+ describe 'Qt::Point' do
26
+
27
+ it 'should be serializable using YAML' do
28
+ pt = Qt::Point.new(1,3)
29
+ res = YAML.load(YAML.dump(pt))
30
+ res.should == pt
31
+ res.should_not equal(pt)
32
+ end
33
+
34
+ it 'should be marshallable' do
35
+ pt = Qt::Point.new(1,3)
36
+ res = Marshal.load(Marshal.dump(pt))
37
+ res.should == pt
38
+ res.should_not equal(pt)
39
+ end
40
+
41
+ end
42
+
43
+ describe 'Qt::PointF' do
44
+
45
+ it 'should be serializable using YAML' do
46
+ pt = Qt::PointF.new(1.9,-3.4)
47
+ res = YAML.load(YAML.dump(pt))
48
+ res.should == pt
49
+ res.should_not equal(pt)
50
+ end
51
+
52
+ it 'should be marshallable' do
53
+ pt = Qt::PointF.new(1.9,-3.4)
54
+ res = Marshal.load(Marshal.dump(pt))
55
+ res.should == pt
56
+ res.should_not equal(pt)
57
+ end
58
+
59
+ end
60
+
61
+ describe 'Qt::Size' do
62
+
63
+ it 'should be serializable using YAML' do
64
+ sz = Qt::Size.new(4,3)
65
+ res = YAML.load(YAML.dump(sz))
66
+ res.should == sz
67
+ res.should_not equal(sz)
68
+ end
69
+
70
+ it 'should be marshallable' do
71
+ sz = Qt::Size.new(4,3)
72
+ res = Marshal.load(Marshal.dump(sz))
73
+ res.should == sz
74
+ res.should_not equal(sz)
75
+ end
76
+
77
+ end
78
+
79
+ describe 'Qt::SizeF' do
80
+
81
+ it 'should be serializable using YAML' do
82
+ sz = Qt::SizeF.new(-4.1,3.7)
83
+ res = YAML.load(YAML.dump(sz))
84
+ res.should == sz
85
+ res.should_not equal(sz)
86
+ end
87
+
88
+ it 'should be marshallable' do
89
+ sz = Qt::SizeF.new(-4.1,3.7)
90
+ res = Marshal.load(Marshal.dump(sz))
91
+ res.should == sz
92
+ res.should_not equal(sz)
93
+ end
94
+
95
+ end
96
+
97
+ describe 'Qt::Rect' do
98
+
99
+ it 'should be serializable using YAML' do
100
+ rec = Qt::Rect.new(1,3,5,6)
101
+ res = YAML.load(YAML.dump(rec))
102
+ res.should == rec
103
+ res.should_not equal(rec)
104
+ end
105
+
106
+ it 'should be marshallable' do
107
+ rec = Qt::Rect.new(1,3,5,6)
108
+ res = Marshal.load(Marshal.dump(rec))
109
+ res.should == rec
110
+ res.should_not equal(rec)
111
+ end
112
+
113
+
114
+ end
115
+
116
+ describe 'Qt::RectF' do
117
+
118
+ it 'should be serializable using YAML' do
119
+ rec = Qt::RectF.new(1.2,-4.1,3.7,5.8)
120
+ res = YAML.load(YAML.dump(rec))
121
+ res.should == rec
122
+ res.should_not equal(rec)
123
+ end
124
+
125
+ it 'should be marshallable' do
126
+ rec = Qt::RectF.new(1.2,-4.1,3.7,5.8)
127
+ res = Marshal.load(Marshal.dump(rec))
128
+ res.should == rec
129
+ res.should_not equal(rec)
130
+ end
131
+
132
+ end
133
+
134
+ describe 'Qt::Color' do
135
+
136
+ it 'should be serializable using YAML' do
137
+ c= Qt::Color.new(178, 201, 89)
138
+ res = YAML.load(YAML.dump(c))
139
+ res.should == c
140
+ res.should_not equal(c)
141
+ end
142
+
143
+ it 'should be marshallable' do
144
+ c= Qt::Color.new(178, 201, 89)
145
+ res = Marshal.load(Marshal.dump(c))
146
+ res.should == c
147
+ res.should_not equal(c)
148
+ end
149
+
150
+ end
151
+
152
+ describe 'Qt::Date' do
153
+
154
+ it 'should be serializable using YAML' do
155
+ d = Qt::Date.new(2008, 10, 23)
156
+ res = YAML.load(YAML.dump(d))
157
+ res.should == d
158
+ res.should_not equal(d)
159
+ end
160
+
161
+ it 'should be marshallable' do
162
+ d = Qt::Date.new(2008, 10, 23)
163
+ res = Marshal.load(Marshal.dump(d))
164
+ res.should == d
165
+ res.should_not equal(d)
166
+ end
167
+
168
+ end
169
+
170
+ describe 'Qt::Font' do
171
+
172
+ it 'should be serializable using YAML' do
173
+ f = Qt::Font.new('Utopia', 13, 10, true)
174
+ res = YAML.load(YAML.dump(f))
175
+ res.should == f
176
+ res.should_not equal(f)
177
+ end
178
+
179
+ it 'should be marshallable' do
180
+ f = Qt::Font.new('Utopia', 13, 10, true)
181
+ res = Marshal.load(Marshal.dump(f))
182
+ res.should == f
183
+ res.should_not equal(f)
184
+ end
185
+
186
+ end
187
+
188
+ describe 'Qt::DateTime' do
189
+
190
+ it 'should be serializable using YAML' do
191
+ d = Qt::DateTime.new(Qt::Date.new(2008, 10, 24), Qt::Time.new(13,49,58,688), Qt::UTC)
192
+ res = YAML.load(YAML.dump(d))
193
+ res.should == d
194
+ res.should_not equal(d)
195
+ end
196
+
197
+ it 'should be marshallable' do
198
+ d = Qt::DateTime.new(Qt::Date.new(2008, 10, 24), Qt::Time.new(13,49,58,688), Qt::UTC)
199
+ res = Marshal.load(Marshal.dump(d))
200
+ res.should == d
201
+ res.should_not equal(d)
202
+ end
203
+
204
+ end
205
+
206
+ describe 'Qt::Time' do
207
+
208
+ it 'should be serializable using YAML' do
209
+ t = Qt::Time.new(14, 36, 52, 140)
210
+ res = YAML.load(YAML.dump(t))
211
+ res.should == t
212
+ res.should_not equal(t)
213
+ res.should be_valid
214
+
215
+ t = Qt::Time.new(0,0,0)
216
+ res = YAML.load(YAML.dump(t))
217
+ res.should == t
218
+ res.should_not equal(t)
219
+ res.should be_valid
220
+
221
+ t = Qt::Time.new
222
+ res = YAML.load(YAML.dump(t))
223
+ res.should == t
224
+ res.should_not equal(t)
225
+ res.should_not be_valid
226
+ end
227
+
228
+ it 'should be marshallable' do
229
+ t = Qt::Time.new(14, 36, 52, 140)
230
+ res = Marshal.load(Marshal.dump(t))
231
+ res.should == t
232
+ res.should_not equal(t)
233
+ res.should be_valid
234
+
235
+ t = Qt::Time.new(0,0,0)
236
+ res = Marshal.load(Marshal.dump(t))
237
+ res.should == t
238
+ res.should_not equal(t)
239
+ res.should be_valid
240
+
241
+ t = Qt::Time.new
242
+ res = Marshal.load(Marshal.dump(t))
243
+ res.should == t
244
+ res.should_not equal(t)
245
+ res.should_not be_valid
246
+ end
247
+
248
+ end
249
+
250
+ describe 'Qt::Url' do
251
+
252
+ it 'should be serializable using YAML' do
253
+ u = Qt::Url.new 'http://www.kde.org'
254
+ res = YAML.load(YAML.dump(u))
255
+ res.should == u
256
+ res.should_not equal(u)
257
+ end
258
+
259
+ it 'should be marshallable' do
260
+ u = Qt::Url.new 'http://www.kde.org'
261
+ res = Marshal.load(Marshal.dump(u))
262
+ res.should == u
263
+ res.should_not equal(u)
264
+ end
265
+
266
+ end
267
+
268
+ module QtNamedConnectSpec
269
+
270
+ class Sender < Qt::Object
271
+ signals 's1()', 's2(QString)'
272
+ def emit_signal sig, *args
273
+ emit method(sig).call(*args)
274
+ end
275
+ end
276
+
277
+ end
278
+
279
+ describe 'Qt::Base#named_connect' do
280
+
281
+ before do
282
+ @sender = QtNamedConnectSpec::Sender.new
283
+ end
284
+
285
+ it 'should make a connection' do
286
+ m = flexmock{|mk| mk.should_receive(:test).once}
287
+ @sender.named_connect(SIGNAL('s1()'), 'test'){m.test}
288
+ @sender.emit_signal 's1'
289
+ end
290
+
291
+ it 'should allow to disconnect the block' do
292
+ m = flexmock{|mk| mk.should_receive(:test).never}
293
+ @sender.named_connect(SIGNAL('s1()'), 'test'){m.test}
294
+ rec = @sender.find_children(Qt::SignalBlockInvocation, 'test')[0]
295
+ @sender.disconnect SIGNAL('s1()'), rec
296
+ @sender.emit_signal 's1'
297
+ end
298
+
299
+ end
300
+
301
+ describe 'Qt::Base#named_connect' do
302
+
303
+ before do
304
+ @sender = QtNamedConnectSpec::Sender.new
305
+ end
306
+
307
+ it 'should allow to disconnect the block' do
308
+ m = flexmock{|mk| mk.should_receive(:test).never}
309
+ @sender.named_connect(SIGNAL('s1()'), 'test'){m.test}
310
+ @sender.named_disconnect 'test'
311
+ @sender.emit_signal 's1'
312
+ end
313
+
314
+ end
315
+
316
+ describe Qt::Variant, '#to_bool' do
317
+
318
+ it 'calls method_missing with :to_bool' do
319
+ v = Qt::Variant.new false
320
+ def v.method_missing *args
321
+ @method_called = args[0]
322
+ super *args
323
+ end
324
+ v.to_bool.should be_false
325
+ v.instance_variable_get(:@method_called).should == :to_bool
326
+ end
327
+
328
+ end
@@ -0,0 +1,617 @@
1
+ require 'spec/common'
2
+ require 'pathname'
3
+ require 'set'
4
+
5
+ require 'ruber/settings_container'
6
+
7
+ class SimpleContainer
8
+
9
+ include Ruber::SettingsContainer
10
+
11
+ def initialize back
12
+ setup_container back
13
+ end
14
+
15
+ end
16
+
17
+ describe 'Ruber::SettingsContainer' do
18
+
19
+ before do
20
+ @back = flexmock('backend')
21
+ @back.should_ignore_missing
22
+ @obj = Object.new
23
+ @obj.extend Ruber::SettingsContainer
24
+ end
25
+
26
+ it 'should create the needed instance variables in the setup_container method' do
27
+ @obj.send :setup_container, @back
28
+ iv = @obj.instance_variables.map{|v| v.to_s}
29
+ %w[@known_options @options @backend @dialog @widgets @dialog_title].each{|i| iv.should include(i)}
30
+ end
31
+
32
+ it 'should set the @backend instance variable to the object passed as first argument' do
33
+ @obj.send :setup_container, @back
34
+ @obj.instance_variable_get(:@backend).should equal(@back)
35
+ end
36
+
37
+ it 'should set the @dialog instance variable to nil' do
38
+ @obj.send :setup_container, @back
39
+ @obj.instance_variable_get(:@dialog).should be_nil
40
+ end
41
+
42
+ it 'should set the base directory to the value of the second argument, if given' do
43
+ @obj.send :setup_container, @back, '/home/stefano'
44
+ @obj.instance_variable_get(:@base_directory).should == '/home/stefano'
45
+ end
46
+
47
+ it 'should set the base directory to nil, if only one argument is given' do
48
+ @obj.send :setup_container, @back
49
+ @obj.instance_variable_get(:@base_directory).should be_nil
50
+ end
51
+
52
+ it 'should raise ArgumentError if the second argument is given, but it\'s not an absolute path' do
53
+ lambda{@obj.send :setup_container, @back, 'dir1/dir2'}.should raise_error(ArgumentError, "The second argument to setup_container should be either an absolute path or nil")
54
+ end
55
+
56
+ it 'sets the dialog_class instance variable to SettingsDialog' do
57
+ @obj.send :setup_container, @back
58
+ @obj.instance_variable_get(:@dialog_class).should == Ruber::SettingsDialog
59
+ end
60
+
61
+ end
62
+
63
+ describe 'Ruber::SettingsContainer#add_option' do
64
+
65
+ before do
66
+ @back = flexmock('backend')
67
+ @back.should_ignore_missing
68
+
69
+ @cont = SimpleContainer.new @back
70
+ @opt = OS.new({:name => :o1, :default => 'abc', :group => :G1})
71
+ end
72
+
73
+ it 'should add the new option to the list of known options' do
74
+ @cont.add_option @opt
75
+ @cont.instance_variable_get(:@known_options)[[:G1, :o1]].should == @opt
76
+ end
77
+
78
+ it 'should set the value of the option to that is returned by the backend' do
79
+ @back.should_receive(:[]).with(@opt).once.and_return('xyz')
80
+ @cont.add_option @opt
81
+ @cont.instance_variable_get(:@options)[[:G1, :o1]].should == 'xyz'
82
+ end
83
+
84
+ it 'should call the delete_dialog method' do
85
+ flexmock(@cont).should_receive(:delete_dialog).once
86
+ @cont.add_option @opt
87
+ end
88
+
89
+ it 'should raise ArgumentError if an option with the same name and group is already known' do
90
+ @cont.add_option @opt
91
+ lambda{@cont.add_option @opt}.should raise_error(ArgumentError, "An option with name #{@opt.name} belonging to group #{@opt.group} already exists")
92
+ end
93
+
94
+
95
+ end
96
+
97
+ describe 'Ruber::SettingsContainer#remove_option' do
98
+
99
+ before do
100
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
101
+ @cont = SimpleContainer.new @back
102
+ @opt = OS.new({:name => :o1, :default => 'abc', :group => :G1})
103
+ @cont.add_option @opt
104
+ end
105
+
106
+ it 'should remove the option whose group and name correspond to the given arguments from the list of known options, when called with two arguments' do
107
+ @cont.remove_option @opt.group, @opt.name
108
+ @cont.instance_variable_get(:@known_options).should_not include([@opt.group, @opt.name])
109
+ end
110
+
111
+ it 'should remove the option whose group and name correspond to the given arguments from the list of option values, when called with two arguments' do
112
+ @cont.remove_option @opt.group, @opt.name
113
+ @cont.instance_variable_get(:@options).should_not include([@opt.group, @opt.name])
114
+ end
115
+
116
+ it 'should remove the option corresponding to the one passed as argument from the list of known options, when called with one argument' do
117
+ @cont.remove_option @opt
118
+ @cont.instance_variable_get(:@known_options).should_not include([@opt.group, @opt.name])
119
+ end
120
+
121
+ it 'should remove the option corresponding to the one passed as argument from the list of option values, when called with one argument' do
122
+ @cont.remove_option @opt
123
+ @cont.instance_variable_get(:@options).should_not include([@opt.group, @opt.name])
124
+ end
125
+
126
+ it 'should do nothing if an option corresponding to the given argument(s) isn\'t known' do
127
+ old_known = @cont.instance_variable_get(:@known_options).dup
128
+ old_options = @cont.instance_variable_get(:@options).dup
129
+ @cont.remove_option(:o2, :G1)
130
+ @cont.instance_variable_get(:@known_options).should == old_known
131
+ @cont.instance_variable_get(:@options).should == old_options
132
+ @cont.remove_option(OS.new({:name => :o1, :group => :G2}))
133
+ @cont.instance_variable_get(:@known_options).should == old_known
134
+ @cont.instance_variable_get(:@options).should == old_options
135
+ end
136
+
137
+ it 'should call the delete_dialog method' do
138
+ flexmock(@cont).should_receive(:delete_dialog).once
139
+ @cont.remove_option @opt
140
+ end
141
+
142
+ end
143
+
144
+ describe 'Ruber::SettingsContainer#has_option?' do
145
+
146
+ before do
147
+ @back = flexmock('backend')
148
+ @back.should_ignore_missing
149
+
150
+ @cont = SimpleContainer.new @back
151
+ @opt = OS.new({:name => :o1, :default => 'abc', :group => :G1})
152
+ end
153
+
154
+ it 'returns true if an option with the given name belonging to the given group is known' do
155
+ @cont.add_option @opt
156
+ @cont.should have_option(@opt.group, @opt.name)
157
+ end
158
+
159
+ it 'returns false if no options with the given name belonging to the given group are known' do
160
+ @cont.add_option @opt
161
+ @cont.should_not have_option(:G2, @opt.name)
162
+ @cont.should_not have_option(:G1, :x)
163
+ @cont.should_not have_option(:G2, :x)
164
+ end
165
+
166
+ end
167
+
168
+ describe 'Ruber::SettingsContainer#[]' do
169
+
170
+ before do
171
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
172
+
173
+ @cont = SimpleContainer.new @back
174
+ @options = [OS.new({:name => :o1, :default => 'abc', :group => :G1}), OS.new({:name => :o2, :default => 3, :group => :G2})]
175
+ @back.should_receive(:[]).with(@options[0]).once.and_return('xyz').by_default
176
+ @back.should_receive(:[]).with(@options[1]).once.and_return(3).by_default
177
+ @options.each{|o| @cont.add_option o}
178
+ end
179
+
180
+ it 'should return the value of the option with group and name equal to the arguments if called with two arguments' do
181
+ @cont[:G1, :o1].should == 'xyz'
182
+ @cont[:G2, :o2].should == 3
183
+ end
184
+
185
+ it 'should raise IndexError if the option corresponding to the group and name given isn\'t known, when called with two arguments' do
186
+ lambda{@cont[:G1, :o2]}.should raise_error("An option called o2 belonging to group G1 doesn't exist")
187
+ lambda{@cont[:G2, :o1]}.should raise_error("An option called o1 belonging to group G2 doesn't exist")
188
+ lambda{@cont[:G4, :o3]}.should raise_error("An option called o3 belonging to group G4 doesn't exist")
189
+ end
190
+
191
+ it 'should treat the value of the option with group and name corresponding to the first two arguments as a path relative to the base directory and return the full path to it, if the third argument is :abs or :absolute and the value is a string' do
192
+ base = '/home/stefano'
193
+ @cont.instance_variable_set :@base_directory, base
194
+ @cont[:G1, :o1, :abs].should == File.join(base, 'xyz')
195
+ @cont[:G1, :o1, :absolute].should == File.join(base, 'xyz')
196
+ end
197
+
198
+ it 'should treat the value of the option with group and name corresponding to the first two arguments as a path relative to the base directory and return the full path to it, if the third argument is :abs or :absolute and the value is a Pathname' do
199
+ base = '/home/stefano'
200
+ @cont.instance_variable_set :@base_directory, base
201
+ @cont[:G1, :o1] = Pathname.new('xyz')
202
+ @cont[:G1, :o1, :abs].should == Pathname.new(base)+'xyz'
203
+ @cont[:G1, :o1, :absolute].should == Pathname.new(base)+'xyz'
204
+ end
205
+
206
+ it 'should ignore the third argument if it is different from :abs and :absolute' do
207
+ base = '/home/stefano'
208
+ @cont.instance_variable_set :@base_directory, base
209
+ @cont[:G1, :o1, :xtz].should == 'xyz'
210
+ @cont[:G1, :o1, 3].should == 'xyz'
211
+ end
212
+
213
+ it 'should ignore the third argument if the value is not a string or a Pathname' do
214
+ base = '/home/stefano'
215
+ @cont.instance_variable_set :@base_directory, base
216
+ @cont[:G1, :o1] = nil
217
+ @cont[:G1, :o1, :abs].should == nil
218
+ @cont[:G1, :o1] = %w[a b c]
219
+ @cont[:G1, :o1, :abs].should == %w[a b c]
220
+ end
221
+
222
+ it 'should ignore the third argument if the base directory is set to nil' do
223
+ @cont[:G1, :o1, :abs].should == 'xyz'
224
+ @cont[:G1, :o1, :absolute].should == 'xyz'
225
+ end
226
+
227
+ it 'should return an instance of class Ruber::SettingsContainer::Proxy set to the group passed as argument (even if no options of that group are known) if called with one argument' do
228
+ pr1 = flexmock('proxy1')
229
+ pr2 = flexmock('proxy2')
230
+ flexmock(Ruber::SettingsContainer::Proxy).should_receive(:new).once.with(@cont, :G1).and_return pr1
231
+ flexmock(Ruber::SettingsContainer::Proxy).should_receive(:new).once.with(@cont, :G3).and_return pr2
232
+ @cont[:G1].should equal(pr1)
233
+ @cont[:G3].should equal(pr2)
234
+ end
235
+
236
+ it 'raises IndexError if a settings with the given name and group doesn\'t exist' do
237
+ lambda{@cont[:G1, :ox]}.should raise_error(IndexError)
238
+ lambda{@cont[:Gx, :o1]}.should raise_error(IndexError)
239
+ end
240
+
241
+ it 'doesn\'t raises IndexError if only the group name is given' do
242
+ lambda{@cont[:Gx]}.should_not raise_error
243
+ end
244
+
245
+ end
246
+
247
+ describe 'Ruber::SettingsContainer#[]=' do
248
+
249
+ before do
250
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
251
+
252
+ @cont = SimpleContainer.new @back
253
+ @options = [OS.new({:name => :o1, :default => 'abc', :group => :G1}), OS.new({:name => :o2, :default => 3, :group => :G2})]
254
+ @back.should_receive(:[]).with(@options[0]).once.and_return('xyz').by_default
255
+ @back.should_receive(:[]).with(@options[1]).once.and_return(3).by_default
256
+ @options.each{|o| @cont.add_option o}
257
+ end
258
+
259
+ it 'should set the content of the option corresponding to the first two arguments to the value passed as third argument' do
260
+ @cont[:G1, :o1] = 'ijk'
261
+ @cont[:G1, :o1].should == 'ijk'
262
+ @cont[:G2, :o2] = 7
263
+ @cont[:G2, :o2].should == 7
264
+ end
265
+
266
+ it 'should make the value passed as third argument relative to the base directory, and store it as the content corresponding to the first two arguments, if the relative_path method of the option returns true' do
267
+ base = '/home/stefano'
268
+ @cont.instance_variable_set(:@base_directory, base)
269
+ @options[0].relative_path = true
270
+ @cont[:G1, :o1] = File.join base, 'dir1/dir2'
271
+ @cont[:G1, :o1].should == 'dir1/dir2'
272
+ end
273
+
274
+ it 'should not attemp to make the value relative to the base directory if the value isn\'t a string' do
275
+ base = '/home/stefano'
276
+ @cont.instance_variable_set(:@base_directory, base)
277
+ @options[0].relative_path = true
278
+ @cont[:G1, :o1] = 3
279
+ @cont[:G1, :o1].should == 3
280
+ end
281
+
282
+
283
+ it 'should not attemp to make the value relative to the base directory if the base directory is nil' do
284
+ @options[0].relative_path = true
285
+ @cont[:G1, :o1] = '/home/stefano/dir1/dir2'
286
+ @cont[:G1, :o1].should == '/home/stefano/dir1/dir2'
287
+ end
288
+
289
+ it 'should not attemp to make the value relative to the base directory if the value isn\'t an absolute path' do
290
+ base = '/home/stefano'
291
+ @cont.instance_variable_set(:@base_directory, base)
292
+ @options[0].relative_path = true
293
+ @cont[:G1, :o1] = 'stefano/dir1/dir2'
294
+ @cont[:G1, :o1].should == 'stefano/dir1/dir2'
295
+ end
296
+
297
+ it 'should raise IndexError if no option corresponding to the first two arguments exist' do
298
+ lambda{@cont[:G1, :o2]=1}.should raise_error(IndexError, 'No option called o2 and belonging to group G1 exists')
299
+ lambda{@cont[:G2, :o1]='x'}.should raise_error(IndexError, 'No option called o1 and belonging to group G2 exists')
300
+ lambda{@cont[:G3, :o4]=%w[a b]}.should raise_error(IndexError, 'No option called o4 and belonging to group G3 exists')
301
+ end
302
+
303
+ end
304
+
305
+ describe 'Ruber::SettingsContainer#default' do
306
+
307
+ before do
308
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
309
+ @cont = SimpleContainer.new @back
310
+ @options = [OS.new({:name => :o1, :default => 'abc', :group => :G1}), OS.new({:name => :o2, :default => 3, :group => :G2})]
311
+ @options.each{|o| @cont.add_option o}
312
+ end
313
+
314
+ it 'should return the default value for the option corresponding to the arguments' do
315
+ obj = Object.new
316
+ @cont.add_option OS.new({:name => :o2, :group => :G1, :default => obj})
317
+ @cont.default(:G1, :o1).should == 'abc'
318
+ @cont.default(:G2, :o2).should == 3
319
+ @cont.default(:G1, :o2).should equal(obj)
320
+ end
321
+
322
+ it 'should raise IndexError if no options corresponding to the arguments exist' do
323
+ lambda{@cont.default :G1, :o2}.should raise_error(IndexError, 'No option called o2 and belonging to group G1 exists')
324
+ lambda{@cont.default :G2, :o1}.should raise_error(IndexError, 'No option called o1 and belonging to group G2 exists')
325
+ lambda{@cont.default :G3, :o4}.should raise_error(IndexError, 'No option called o4 and belonging to group G3 exists')
326
+ end
327
+
328
+ end
329
+
330
+ describe 'Ruber::SettingsContainer#relative_path?' do
331
+
332
+ before do
333
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
334
+ @cont = SimpleContainer.new @back
335
+ @options = [OS.new({:name => :o1, :default => 'abc', :group => :G1, :relative_path => true}), OS.new({:name => :o2, :default => 3, :group => :G2})]
336
+ @options.each{|o| @cont.add_option o}
337
+ end
338
+
339
+ it 'should return true if the given option is a relative path option and false otherwise' do
340
+ @cont.relative_path?(:G1, :o1).should be_true
341
+ @cont.relative_path?(:G2, :o2).should be_false
342
+ end
343
+
344
+ it 'should return true if the given option doesn\'t have a relative_path method' do
345
+ flexmock(@options[0]).should_receive(:relative_path).and_raise(NoMethodError)
346
+ @cont.relative_path?(:G1, :o1).should be_false
347
+ end
348
+
349
+ end
350
+
351
+ describe 'Ruber::SettingsContainer#add_widget' do
352
+
353
+ before do
354
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
355
+ @cont = SimpleContainer.new @back
356
+ end
357
+
358
+ it 'should add the argument to the list of widgets, according to the caption specified in the argument' do
359
+ widgets = [
360
+ OS.new({:caption => 'G1', :class_obj => Qt::Widget}),
361
+ OS.new({:caption => 'G2', :class_obj => Qt::PushButton}),
362
+ OS.new({:caption => 'G1', :class_obj => Qt::LineEdit}),
363
+ OS.new({:caption => 'G2', :class_obj => Qt::CheckBox})
364
+ ]
365
+ widgets.each{|w| @cont.add_widget w}
366
+ @cont.instance_variable_get(:@widgets).should == widgets
367
+ end
368
+
369
+ it 'should call the delete_dialog method' do
370
+ flexmock(@cont).should_receive(:delete_dialog).times(4)
371
+ widgets = [
372
+ OS.new({:caption => 'G1', :class_obj => Qt::Widget}),
373
+ OS.new({:caption => 'G2', :class_obj => Qt::PushButton}),
374
+ OS.new({:caption => 'G1', :class_obj => Qt::LineEdit}),
375
+ OS.new({:caption => 'G2', :class_obj => Qt::CheckBox})
376
+ ]
377
+ widgets.each{|w| @cont.add_widget w}
378
+ end
379
+
380
+ end
381
+
382
+ describe 'Ruber::SettingsContainer#remove_widget' do
383
+
384
+ before do
385
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
386
+ @cont = SimpleContainer.new @back
387
+ @widgets = [
388
+ OS.new({:caption => 'G1', :class_obj => Qt::Widget}),
389
+ OS.new({:caption => 'G1', :class_obj => Qt::CheckBox}),
390
+ OS.new({:caption => 'G2', :class_obj => Qt::LineEdit}),
391
+ OS.new({:caption => 'G2', :class_obj => Qt::Widget})
392
+ ]
393
+ @widgets.each{|w| @cont.add_widget w}
394
+ end
395
+
396
+ it 'should remove the given widget from the list' do
397
+ @cont.remove_widget @widgets[0].dup
398
+ widgets = @cont.instance_variable_get(:@widgets).should == @widgets[1..-1]
399
+ end
400
+
401
+ it 'should call the delete_dialog method' do
402
+ flexmock(@cont).should_receive(:delete_dialog).times(2)
403
+ @cont.remove_widget @widgets[0]
404
+ @cont.remove_widget @widgets[1]
405
+ end
406
+
407
+ it 'should do nothing if the object passed as argument doesn\'t correspond to a registered widget' do
408
+ flexmock(@cont).should_receive(:delete_dialog).never
409
+ @cont.remove_widget OS.new({:caption => 'G1', :class_obj => Qt::LineEdit})
410
+ @cont.instance_variable_get(:@widgets).should == @widgets
411
+ end
412
+
413
+ end
414
+
415
+ describe 'Ruber::SettingsContainer#dialog_title=' do
416
+
417
+ before do
418
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
419
+ @cont = SimpleContainer.new @back
420
+ end
421
+
422
+ it 'should set the @dialog_title instance variable' do
423
+ @cont.send :dialog_title=, 'Test'
424
+ @cont.instance_variable_get(:@dialog_title).should == 'Test'
425
+ end
426
+
427
+ it 'should call the delete_dialog method' do
428
+ flexmock(@cont).should_receive(:delete_dialog).once
429
+ @cont.send :dialog_title=, 'Test'
430
+ end
431
+
432
+ end
433
+
434
+ describe 'Ruber::SettingsContainer#dialog' do
435
+
436
+ include FlexMock::ArgumentTypes
437
+
438
+ before do
439
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
440
+ @cont = SimpleContainer.new @back
441
+ end
442
+
443
+ it 'should return the dialog object if it exists' do
444
+ dlg = flexmock 'dialog'
445
+ @cont.instance_variable_set :@dialog, dlg
446
+ flexmock(Ruber::SettingsDialog).should_receive(:new).never
447
+ @cont.dialog.should equal(dlg)
448
+ end
449
+
450
+ it 'creates and returns a new instance of the class specified in the dialog_class instance variable if the dialog doesn\'t exist' do
451
+ dlg = Qt::Dialog.new
452
+ flexmock(Qt::Dialog).should_receive(:new).once.and_return dlg
453
+ @cont.instance_variable_set :@dialog_class, Qt::Dialog
454
+ res = @cont.dialog
455
+ res.should be_instance_of Qt::Dialog
456
+ end
457
+
458
+ it 'should create a new dialog, passing it self, a list of options and a list of widgets, store it in the @dialog instance variable and return it if the dialog object is nil' do
459
+ widgets = [
460
+ OS.new({:caption => 'G1', :class_obj => Qt::Widget}),
461
+ OS.new({:caption => 'G1', :class_obj => Qt::CheckBox}),
462
+ OS.new({:caption => 'G2', :class_obj => Qt::LineEdit}),
463
+ OS.new({:caption => 'G2', :class_obj => Qt::Widget})
464
+ ]
465
+ widgets.each{|w| @cont.add_widget w}
466
+ opts = [OS.new({:name => :o1, :default => 'abc', :group => :G1}), OS.new({:name => :o2, :default => 3, :group => :G2})]
467
+ values = ['x', 5]
468
+ opts.each_index do |i|
469
+ @cont.add_option opts[i]
470
+ @cont[opts[i].group, opts[i].name] = values[i]
471
+ end
472
+ flexmock(Ruber::SettingsDialog).should_receive(:new).once.with @cont, on{|a| Set.new(a) == Set.new(opts)}, on{|w| Set.new(w) == Set.new(widgets)}, nil
473
+ @cont.dialog
474
+ end
475
+
476
+ it 'should set the title of the dialog to the @dialog_title instance variable, if set' do
477
+ @mw = Qt::Widget.new
478
+ flexmock(Ruber).should_receive(:[]).with(:main_window).and_return @mw
479
+ @cont.dialog.window_title.should == KDE::Application.instance.application_name
480
+ @cont.send :delete_dialog
481
+ @cont.send :dialog_title=, 'Test title'
482
+ @cont.dialog.window_title.should == 'Test title'
483
+ end
484
+
485
+ end
486
+
487
+ describe 'Ruber::SettingsContainer#delete_dialog' do
488
+
489
+ before do
490
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
491
+ @cont = SimpleContainer.new @back
492
+ @dlg = flexmock('dialog'){|m| m.should_ignore_missing}
493
+ @cont.instance_variable_set :@dialog, @dlg
494
+ end
495
+
496
+ it 'should call the delete_later method on the dialog object' do
497
+ @dlg.should_receive(:delete_later).once
498
+ @cont.send :delete_dialog
499
+ end
500
+
501
+ it 'should set the @dialog instance variable to nil' do
502
+ @cont.send :delete_dialog
503
+ @cont.instance_variable_get(:@dialog).should be_nil
504
+ end
505
+
506
+ it 'should do nothing if the @dialog instance variable is nil' do
507
+ @cont.instance_variable_set :@dialog, nil
508
+ lambda{@cont.send :delete_dialog}.should_not raise_error
509
+ end
510
+
511
+ end
512
+
513
+ describe 'Ruber::SettingsContainer#write' do
514
+
515
+ before do
516
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
517
+ @cont = SimpleContainer.new @back
518
+ @options_data = [
519
+ OS.new({:group => 'G1', :name => :o1, :default => 'a'}),
520
+ OS.new({:group => 'G1', :name => :o2, :default => -1}),
521
+ OS.new({:group => 'G2', :name => :o1, :default => nil}),
522
+ OS.new({:group => 'G2', :name => :o3, :default => (1..4)})
523
+ ]
524
+ @options_values = ['b', 5, /a/, nil]
525
+ @options_data.each_index do |i|
526
+ data = @options_data[i]
527
+ @cont.add_option data
528
+ @cont[data.group, data.name] = @options_values[i]
529
+ end
530
+ end
531
+
532
+ it 'should call the write method of the backend, passing it the value returned by the collect_options method' do
533
+ exp = @options_data.zip(@options_values).inject({}){|res, i| res[i[0]] = i[1]; res}
534
+ flexmock(@cont).should_receive(:collect_options).once.and_return exp
535
+ @back.should_receive(:write).once.with(exp)
536
+ @cont.write
537
+ end
538
+
539
+ end
540
+
541
+ describe 'Ruber::SettingsContainer#collect_options' do
542
+
543
+ before do
544
+ @back = flexmock('backend'){|m| m.should_ignore_missing}
545
+ @cont = SimpleContainer.new @back
546
+ @options_data = [
547
+ OS.new({:group => 'G1', :name => :o1, :default => 'a'}),
548
+ OS.new({:group => 'G1', :name => :o2, :default => -1}),
549
+ OS.new({:group => 'G2', :name => :o1, :default => nil}),
550
+ OS.new({:group => 'G2', :name => :o3, :default => (1..4)})
551
+ ]
552
+ @options_values = ['b', 5, /a/, nil]
553
+ @options_data.each_index do |i|
554
+ data = @options_data[i]
555
+ @cont.add_option data
556
+ @cont[data.group, data.name] = @options_values[i]
557
+ end
558
+ end
559
+
560
+ it 'should return a hash having the option objects as keys and the corresponding values as keys' do
561
+ exp = @options_data.zip(@options_values).inject({}){|res, i| res[i[0]] = i[1]; res}
562
+ @cont.send(:collect_options).should == exp
563
+ end
564
+
565
+ end
566
+
567
+ describe 'Ruber::SettingsContainer::Proxy' do
568
+
569
+ before do
570
+ @back = flexmock('backend')
571
+ @back.should_ignore_missing
572
+
573
+ @cont = SimpleContainer.new @back
574
+ @opt = OS.new({:name => :o1, :default => 'abc', :group => :G1})
575
+ end
576
+
577
+ it 'should inherit BasicObject' do
578
+ Ruber::SettingsContainer::Proxy.ancestors.should include(BasicObject)
579
+ end
580
+
581
+ it 'should call the [] method of the container, passing the group and the received arguments, when the [] method is called' do
582
+ proxy = Ruber::SettingsContainer::Proxy.new @cont, :G1
583
+ flexmock(@cont).should_receive(:[]).once.with(:G1, :o1, nil).and_return 'a'
584
+ flexmock(@cont).should_receive(:[]).once.with(:G1, :o2, nil).and_return 3
585
+ flexmock(@cont).should_receive(:[]).once.with(:G1, :o1, :abs).and_return ENV['HOME']
586
+ proxy[:o1].should == 'a'
587
+ proxy[:o2].should == 3
588
+ proxy[:o1, :abs].should == ENV['HOME']
589
+ end
590
+
591
+ it 'should call the []= method of the container, passing the group and the received arguments, when the []= method is called' do
592
+ proxy = Ruber::SettingsContainer::Proxy.new @cont, :G1
593
+ flexmock(@cont).should_receive(:[]=).once.with(:G1, :o1, 1)
594
+ proxy[:o1] = 1
595
+ end
596
+
597
+ it 'should treat a call to a missing method as a call to [method_name, *args], if the method doesn\'t end in =' do
598
+ proxy = Ruber::SettingsContainer::Proxy.new @cont, :G1
599
+ flexmock(@cont).should_receive(:[]).once.with(:G1, :o1).and_return 'a'
600
+ flexmock(@cont).should_receive(:[]).once.with(:G1, :o2).and_return 3
601
+ flexmock(@cont).should_receive(:[]).once.with(:G1, :o1, :abs).and_return ENV['HOME']
602
+ proxy.o1.should == 'a'
603
+ proxy.o2.should == 3
604
+ proxy.o1(:abs).should == ENV['HOME']
605
+ end
606
+
607
+ it 'should treat a call to a missing method as a call to [method_name, *args]=, if the method ends in =' do
608
+ proxy = Ruber::SettingsContainer::Proxy.new @cont, :G1
609
+ flexmock(@cont).should_receive(:[]=).once.with(:G1, :o1, 'b')
610
+ flexmock(@cont).should_receive(:[]=).once.with(:G1, :o2, 5)
611
+ flexmock(@cont).should_receive(:[]=).once.with(:G1, :o1, ENV['HOME'])
612
+ proxy.o1= 'b'
613
+ proxy.o2= 5
614
+ proxy.o1= ENV['HOME']
615
+ end
616
+
617
+ end