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,406 @@
1
+ require 'spec/common'
2
+
3
+ describe Kernel do
4
+
5
+ describe '#silently' do
6
+
7
+ it 'calls the block after setting the $VERBOSE variable to nil' do
8
+ $VERBOSE = true
9
+ res = true
10
+ silently{res = $VERBOSE}
11
+ res.should be_nil
12
+ end
13
+
14
+ it 'restores the original value of the $VERBOSE variable after calling the block' do
15
+ $VERBOSE= true
16
+ res = true
17
+ silently{res = $VERBOSE}
18
+ res.should be_nil
19
+ $VERBOSE.should == true
20
+ end
21
+
22
+ it 'restores the original value of the $VERBOSE variable even if the block raises an exception' do
23
+ $VERBOSE= true
24
+ res = true
25
+ lambda do
26
+ silently do
27
+ res = $VERBOSE
28
+ raise Exception
29
+ end
30
+ end.should raise_error
31
+ res.should be_nil
32
+ $VERBOSE.should == true
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ describe 'Ruber::Signaler' do
41
+
42
+ it 'should create a new, Ruber::Signaler::SignalerCls-derived class with the given signals when the "create" class method is called' do
43
+ cls = Ruber::Signaler.create 's1()', 's2(QString)', 's3(QObject*)'
44
+ cls.superclass.should == Qt::Object
45
+ methods = cls.instance_methods.map{|s| s.to_s}
46
+ methods.should include('s1')
47
+ methods.should include('s2')
48
+ methods.should include('s3')
49
+ end
50
+
51
+ it 'should provide a private signaler_object= method which sets the @__signaler instance variable' do
52
+ cls = Class.new do
53
+ include Ruber::Signaler
54
+ Signaler = Ruber::Signaler.create 's1(QString)', 's2(QPoint, QRect)'
55
+ end
56
+
57
+ cls.new.private_methods.map{|m| m.to_s}.should include('signaler_object=')
58
+ obj = cls.new
59
+ sig = cls::Signaler.new
60
+ obj.send :signaler_object=, sig
61
+ obj.instance_variable_get(:@__signaler).should equal(sig)
62
+ end
63
+
64
+ it 'should provide a "connect!" instance method, which works as the standard Qt connect method, when called with a block' do
65
+ cls = Class.new do
66
+ include Ruber::Signaler
67
+ Signaler = Ruber::Signaler.create 's1(QString)', 's2(QPoint, QRect)'
68
+
69
+ def initialize
70
+ @__signaler = Signaler.new
71
+ end
72
+
73
+ end
74
+ str = "test"
75
+ pt = Qt::Point.new(-4,2)
76
+ rect = Qt::Rect.new(5,-7,10,8)
77
+ m = flexmock('m') do |mk|
78
+ mk.should_receive(:s1).with(str).once
79
+ mk.should_receive(:s2).with(pt, rect).once
80
+ end
81
+ obj = cls.new
82
+ obj.connect!(SIGNAL('s1(QString)')){|s| m.s1(s)}
83
+ obj.connect!(SIGNAL('s2(QPoint, QRect)')) {|p, r| m.s2(p, r)}
84
+ obj.instance_eval{emit!('s1', str)}
85
+ obj.instance_eval{emit!('s2', pt, rect)}
86
+ end
87
+
88
+ it 'should provide a "connect!" instance method which works as the standard Qt connect method, when called with four arguments' do
89
+
90
+ cls = Class.new do
91
+ include Ruber::Signaler
92
+ SignalerCls = Ruber::Signaler.create 'test_signal(int, QString)'
93
+ def initialize
94
+ @__signaler = SignalerCls.new
95
+ end
96
+ end
97
+
98
+ eval <<-EOS
99
+ class Obj < Qt::Object
100
+ slots 'sl(int, QString)'
101
+ signals 'si(int, QString)'
102
+
103
+ def initialize mock
104
+ super()
105
+ @mock = mock
106
+ end
107
+
108
+ def sl n, s
109
+ @mock.test(n, s)
110
+ end
111
+ end
112
+ EOS
113
+
114
+ obj = cls.new
115
+ m = flexmock('mock'){|mk| mk.should_receive(:test).twice.with(2,"test")}
116
+
117
+ test_obj = Obj.new m
118
+ test_obj.connect(SIGNAL('si(int, QString)')){|n, s| m.test(n, s)}
119
+ obj.connect! SIGNAL('test_signal(int, QString)'), test_obj, SLOT('sl(int, QString)')
120
+ obj.connect! SIGNAL('test_signal(int, QString)'), test_obj, SIGNAL('si(int, QString)')
121
+ obj.send :emit!, 'test_signal', 2, 'test'
122
+ end
123
+
124
+ it 'should provide a disconnect! method which works as Qt::Object#disconnect' do
125
+ cls = Class.new do
126
+ include Ruber::Signaler
127
+ SignalerCls = Ruber::Signaler.create 'test_signal(int, QString)'
128
+ def initialize
129
+ self.signaler_object = SignalerCls.new
130
+ end
131
+ end
132
+
133
+ obj = cls.new
134
+
135
+ def (obj.instance_variable_get(:@__signaler)).disconnect *args
136
+ end
137
+
138
+ test = Qt::Object.new
139
+ flexmock(obj.instance_variable_get(:@__signaler)).should_receive(:disconnect).once.with_no_args.once
140
+ flexmock(obj.instance_variable_get(:@__signaler)).should_receive(:disconnect).once.with( SIGNAL('test_signal(int, QString)'))
141
+ flexmock(obj.instance_variable_get(:@__signaler)).should_receive(:disconnect).once.with( SIGNAL('test_signal(int, QString)'), test)
142
+ flexmock(obj.instance_variable_get(:@__signaler)).should_receive(:disconnect).once.with( SIGNAL('test_signal(int, QString)'), test, SLOT('test_slot()'))
143
+ obj.disconnect!
144
+ obj.disconnect!(SIGNAL('test_signal(int, QString)'))
145
+ obj.disconnect!(SIGNAL('test_signal(int, QString)'), test)
146
+ obj.disconnect!(SIGNAL('test_signal(int, QString)'), test, SLOT('test_slot()'))
147
+ end
148
+
149
+ it 'should provide a private "emit!" method which calls the emit_signal method of the signaler object' do
150
+ cls = Class.new do
151
+ include Ruber::Signaler
152
+ SignalerCls = Ruber::Signaler.create 'test_signal(int, QString)'
153
+ def initialize
154
+ self.signaler_object = SignalerCls.new
155
+ end
156
+ end
157
+ obj = cls.new
158
+ obj.private_methods.map{|m| m.to_s}.should include("emit!")
159
+ m = flexmock("test"){|mk| mk.should_receive(:test).with(3, 'test').once}
160
+ obj.connect!(SIGNAL('test_signal(int, QString)')){|i, s| m.test i, s}
161
+ obj.send(:emit!, :test_signal, 3, "test")
162
+ end
163
+
164
+ end
165
+
166
+ describe 'Dictionary#reverse_each' do
167
+
168
+ it 'should call the block with each key/value pair in reverse order' do
169
+ pairs = [['x', 3], ['a', 2], ['b', 5]]
170
+ d = Dictionary.alpha
171
+ pairs.each{|p| d << p}
172
+ m = flexmock do |mk|
173
+ pairs.sort_by{|k, v| k}.reverse.each{|i| mk.should_receive(:test).with(i).globally.ordered.once}
174
+ end
175
+ d.reverse_each do |k, v|
176
+ m.test [k, v]
177
+ end
178
+ end
179
+
180
+ end
181
+
182
+ describe 'Array#to_h' do
183
+
184
+ it 'should use each entry of the array as key/value pair if no argument is given' do
185
+ a = [[:a, 1], [:b, 2], [:c, 3]]
186
+ a.to_h.should == {:a => 1, :b => 2, :c => 3}
187
+ end
188
+
189
+ it 'should use each entry of the array as key/value pair if the argument is true' do
190
+ a = [[:a, 1], [:b, 2], [:c, 3]]
191
+ a.to_h(true).should == {:a => 1, :b => 2, :c => 3}
192
+ end
193
+
194
+ it 'should consider the array as a list of keys and values if the argument is false' do
195
+ a = [:a, 1, :b, 2, :c, 3]
196
+ a.to_h(false).should == {:a => 1, :b => 2, :c => 3}
197
+ end
198
+
199
+ end
200
+
201
+ describe Ruber::Activable do
202
+
203
+ class SimpleActivable < Qt::Object
204
+ signals :activated, :deactivated
205
+ include Ruber::Activable
206
+ def initialize
207
+ super
208
+ @active = false
209
+ end
210
+ end
211
+
212
+ before do
213
+ @cls = self.class.const_get(:SimpleActivable)
214
+ @obj = @cls.new
215
+ end
216
+
217
+ it 'should return true or false, depending on whether it\'s active or not when the active? method is called' do
218
+ @obj.should_not be_active
219
+ @obj.instance_variable_set(:@active, true)
220
+ @obj.should be_active
221
+ end
222
+
223
+ it 'should set the @active instance variable to false when the deactivate method is called' do
224
+ @obj.deactivate
225
+ @obj.should_not be_active
226
+ @obj.instance_variable_set(:@active, true)
227
+ @obj.deactivate
228
+ @obj.should_not be_active
229
+ end
230
+
231
+ it 'should emit the "deactivated" signal when the deactivated method is called, unless it was already inactive' do
232
+ m1 = flexmock{|m| m.should_receive(:deactivated).once}
233
+ m2 = flexmock{|m| m.should_receive(:deactivated).never}
234
+ @obj.connect(SIGNAL(:deactivated)){m2.deactivated}
235
+ @obj.deactivate
236
+ @obj.disconnect
237
+ @obj.connect(SIGNAL(:deactivated)){m1.deactivated}
238
+ @obj.instance_variable_set(:@active, true)
239
+ @obj.deactivate
240
+ end
241
+
242
+ it 'should set the @active instance variable to true when the activate method is called' do
243
+ @obj.activate
244
+ @obj.should be_active
245
+ @obj.instance_variable_set(:@active, false)
246
+ @obj.activate
247
+ @obj.should be_active
248
+ end
249
+
250
+ it 'should emit the "activated" signal when the activated method is called, unless it was already active' do
251
+ m1 = flexmock{|m| m.should_receive(:activated).never}
252
+ m2 = flexmock{|m| m.should_receive(:activated).once}
253
+ @obj.connect(SIGNAL(:activated)){m2.activated}
254
+ @obj.activate
255
+ @obj.disconnect
256
+ @obj.connect(SIGNAL(:activated)){m1.activated}
257
+ @obj.instance_variable_set(:@active, true)
258
+ @obj.activate
259
+ end
260
+
261
+ it 'should set the @active instance variable to the value passed as argument when the active= method is called' do
262
+ @obj.active= false
263
+ @obj.should_not be_active
264
+ @obj.active= true
265
+ @obj.should be_active
266
+ @obj.active= false
267
+ @obj.should_not be_active
268
+ end
269
+
270
+ it 'should convert the argument to a boolean value when the active= method is called' do
271
+ @obj.active= nil
272
+ @obj.active?.should be_false
273
+ @obj.active= "abc"
274
+ @obj.active?.should be_true
275
+ end
276
+
277
+ it 'should emit the "deactivated" signal when the active= method is called with false as argument and the object was active' do
278
+ m1 = flexmock{|m| m.should_receive(:deactivated).once}
279
+ m2 = flexmock{|m| m.should_receive(:deactivated).never}
280
+ @obj.connect(SIGNAL(:deactivated)){m2.deactivated}
281
+ @obj.active = false
282
+ @obj.disconnect
283
+ @obj.connect(SIGNAL(:deactivated)){m1.deactivated}
284
+ @obj.instance_variable_set(:@active, true)
285
+ @obj.active = false
286
+ end
287
+
288
+ it 'should emit the "activated" signal when the active= method is called with true as argument and the object was inactive' do
289
+ m1 = flexmock{|m| m.should_receive(:activated).never}
290
+ m2 = flexmock{|m| m.should_receive(:activated).once}
291
+ @obj.connect(SIGNAL(:activated)){m2.activated}
292
+ @obj.active = true
293
+ @obj.disconnect
294
+ @obj.connect(SIGNAL(:activated)){m1.activated}
295
+ @obj.instance_variable_set(:@active, true)
296
+ @obj.active = true
297
+ end
298
+
299
+
300
+ it 'should not attempt to emit signals if the object is not a Qt::Object' do
301
+ obj = Object.new
302
+ obj.extend Ruber::Activable
303
+ obj.instance_variable_set(:@active, false)
304
+ lambda{obj.activate}.should_not raise_error
305
+ obj.should be_active
306
+ lambda{obj.deactivate}.should_not raise_error
307
+ obj.should_not be_active
308
+ lambda{obj.active = true}.should_not raise_error
309
+ obj.should be_active
310
+ lambda{obj.active = false}.should_not raise_error
311
+ obj.should_not be_active
312
+ end
313
+
314
+ it 'should not attempt to emit signals if the object is a Qt::Object but doesn\'t provide the needed signals' do
315
+ obj = Qt::Object.new
316
+ obj.extend Ruber::Activable
317
+ obj.instance_variable_set(:@active, false)
318
+ lambda{obj.activate}.should_not raise_error
319
+ obj.should be_active
320
+ lambda{obj.deactivate}.should_not raise_error
321
+ obj.should_not be_active
322
+ lambda{obj.active = true}.should_not raise_error
323
+ obj.should be_active
324
+ lambda{obj.active = false}.should_not raise_error
325
+ obj.should_not be_active
326
+ end
327
+
328
+
329
+ end
330
+
331
+ describe 'String#split_lines' do
332
+
333
+ it 'should return an array with each entry corresponding to a line' do
334
+ "a b c\nd e f\n\ng h i\n".split_lines.should == ['a b c', 'd e f','', 'g h i']
335
+ end
336
+
337
+ end
338
+
339
+ describe Kernel do
340
+
341
+ describe '#string_like?' do
342
+
343
+ it 'should return false' do
344
+ Object.new.should_not be_string_like
345
+ end
346
+
347
+ end
348
+
349
+ describe '#obj_binding' do
350
+
351
+ it 'should return the binding of the object' do
352
+ obj = Object.new
353
+ obj.instance_variable_set(:@x, 7)
354
+ eval( "@x", obj.obj_binding).should == 7
355
+ end
356
+
357
+ end
358
+
359
+ end
360
+
361
+ describe String do
362
+
363
+ describe '#string_like?' do
364
+
365
+ it 'should return true' do
366
+ String.new.should be_string_like
367
+ "abc".should be_string_like
368
+ end
369
+
370
+ end
371
+
372
+ end
373
+
374
+ describe Symbol do
375
+
376
+ describe '#string_like?' do
377
+
378
+ it 'should return true' do
379
+ :abc.should be_string_like
380
+ end
381
+
382
+ end
383
+
384
+ end
385
+
386
+ describe Shellwords, '.split_with_quotes' do
387
+
388
+ it 'works as Shellwords.split if there are no quotes in the argument' do
389
+ arg = "-a xyx --bc ab x=cd"
390
+ Shellwords.split_with_quotes(arg).should == Shellwords.split(arg)
391
+ end
392
+
393
+ it 'encloses in double quotes the tokens which where enclosed in quotes in the argument, unless the token contains double quotes' do
394
+ arg = "-a xyz --bc 'ab x=cd' xh 'a1 bc'"
395
+ exp = ['-a', 'xyz', '--bc', '"ab x=cd"', 'xh', '"a1 bc"']
396
+ Shellwords.split_with_quotes(arg).should == exp
397
+ end
398
+
399
+ it 'encloses in single quotes the tokens which where enclosed in quotes in the argument, if the token contains double quotes' do
400
+ arg = "-a xyz --bc 'ab \"x\"=cd' xh 'a1 bc'"
401
+ exp = ['-a', 'xyz', '--bc', "'ab \"x\"=cd'", 'xh', '"a1 bc"']
402
+ Shellwords.split_with_quotes(arg).should == exp
403
+ end
404
+
405
+
406
+ end
@@ -0,0 +1,869 @@
1
+ require 'spec/common'
2
+
3
+ require 'ruber/main_window/workspace'
4
+
5
+ describe 'Ruber::Workspace, when created' do
6
+
7
+ before do
8
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
9
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
10
+ @ws = Ruber::Workspace.new
11
+ end
12
+
13
+ it 'should read the sizes of the tool widgets from the configuration manager' do
14
+ exp = {'Tool1' => 30, 'Tool2' => 50}
15
+ @config.should_receive(:[]).with(:workspace, :tools_sizes).once.and_return(exp)
16
+ ws = Ruber::Workspace.new
17
+ ws.instance_variable_get(:@sizes).should == exp
18
+ end
19
+
20
+ it 'should create three button bars' do
21
+ @ws.layout.item_at_position(0,0).widget.should be_a(KDE::MultiTabBar)
22
+ @ws.layout.item_at_position(0,2).widget.should be_a(KDE::MultiTabBar)
23
+ @ws.layout.item_at_position(1,0).widget.should be_a(KDE::MultiTabBar)
24
+ @ws.layout.item_at_position(1,1).widget.should be_a(KDE::MultiTabBar)
25
+ @ws.layout.item_at_position(1,2).widget.should be_a(KDE::MultiTabBar)
26
+ end
27
+
28
+ it 'should create a vertical splitter and a horizontal one' do
29
+ vsplit = @ws.layout.item_at_position(0,1).widget
30
+ vsplit.should be_a(Qt::Splitter)
31
+ vsplit.orientation.should == Qt::Vertical
32
+ hsplit = vsplit.widget(0)
33
+ hsplit.should be_a(Qt::Splitter)
34
+ hsplit.orientation.should == Qt::Horizontal
35
+ end
36
+
37
+ it 'should put a stacked widget in the bottom half of the vertical splitter' do
38
+ vsplit = @ws.layout.item_at_position(0,1).widget
39
+ vsplit.widget(1).should be_a(Qt::StackedWidget)
40
+ end
41
+
42
+ it 'should put a stacked widget in the first and third part of the horizontal splitter' do
43
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
44
+ hsplit.widget(0).should be_a(Qt::StackedWidget)
45
+ hsplit.widget(2).should be_a(Qt::StackedWidget)
46
+ end
47
+
48
+ it 'should put a KDE::TabWidget in the middle of the horizontal splitter' do
49
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
50
+ hsplit.widget(1).should be_a(KDE::TabWidget)
51
+ end
52
+
53
+ it 'should have all the stacks hidden' do
54
+ [:left, :bottom, :right].each{|s| @ws.instance_variable_get(:@stacks)[s].should be_hidden}
55
+ end
56
+
57
+ it 'should enable the document mode for the tab widget' do
58
+ @ws.instance_variable_get(:@views).document_mode.should be_true
59
+ end
60
+
61
+ end
62
+
63
+ describe 'Ruber::Workspace#add_tool_widget' do
64
+
65
+ before do
66
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
67
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
68
+ @ws = Ruber::Workspace.new
69
+ end
70
+
71
+ it 'should add a tab to the button bar on the given side' do
72
+ bar = @ws.instance_variable_get(:@button_bars)[:left]
73
+ pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
74
+ id = bar.append_tab pix, -1, "Tool"
75
+ flexmock(bar).should_receive(:append_tab).once.and_return id
76
+ @ws.add_tool_widget :left, Qt::Widget.new, pix, "Tool"
77
+ end
78
+
79
+ it 'should add the given widget to the stacked widget of the correct side' do
80
+ w = Qt::LineEdit.new
81
+ pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
82
+ @ws.add_tool_widget :right, w, pix, 'Tool'
83
+ stack = @ws.layout.item_at_position(0,1).widget.widget(0).widget(2)
84
+ stack.index_of(w).should_not == -1
85
+ end
86
+
87
+ it 'should raise ArgumentError if the widget has already been added' do
88
+ w = Qt::LineEdit.new
89
+ pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
90
+ @ws.add_tool_widget :right, w, pix, 'Tool'
91
+ lambda{@ws.add_tool_widget :right, w, pix, 'Tool'}.should raise_error(ArgumentError, "This widget has already been added as tool widget")
92
+ end
93
+
94
+ end
95
+
96
+ describe 'Ruber::Workspace#remove_tool_widget' do
97
+
98
+ before do
99
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
100
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
101
+ @ws = Ruber::Workspace.new
102
+ @widget = Qt::Label.new
103
+ @bar = @ws.instance_variable_get(:@button_bars)[:bottom]
104
+ @pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
105
+ @id = @bar.append_tab @pix, -1, "Tool"
106
+ flexmock(@bar).should_receive(:append_tab).by_default.and_return @id
107
+ @ws.add_tool_widget :bottom, @widget, @pix, 'Tool'
108
+ end
109
+
110
+ it 'should emit the "removing_tool(QWidget*)" signal' do
111
+ m = flexmock{|mk| mk.should_receive(:removing_tool).once.with(@widget)}
112
+ @ws.connect(SIGNAL('removing_tool(QWidget*)')){|w| m.removing_tool(w)}
113
+ @ws.remove_tool_widget @widget
114
+ end
115
+
116
+ it 'should remove the tab corresponding to the widget from the tab bar' do
117
+ flexmock(@bar).should_receive(:remove_tab).once.with(@id)
118
+ @ws.remove_tool_widget @widget
119
+ end
120
+
121
+ it 'should remove the widget from its stack' do
122
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
123
+ flexmock(stack).should_receive(:remove_widget).with(@widget).once
124
+ #Mocking empty? is needed because otherwise resize_tool is called (because the tool hasn't truly been removed, since we mocked the method)
125
+ flexmock(stack).should_receive(:empty?).and_return true
126
+ @ws.remove_tool_widget @widget
127
+ end
128
+
129
+ it 'should activate another tool widget on the same side if the removed widget was the raised one' do
130
+ other_widget = Qt::Widget.new
131
+ flexmock(@bar).should_receive(:append_tab).once.and_return @id + 1
132
+ @ws.add_tool_widget :bottom, other_widget, @pix, 'Tool1'
133
+ @widget.parent.current_widget.should equal(@widget)
134
+ flexmock(@ws).should_receive(:raise_tool).once.with(other_widget)
135
+ @ws.remove_tool_widget @widget
136
+ end
137
+
138
+ it 'should hide the stack if the removed tool was the last' do
139
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
140
+ stack.visible = true
141
+ @ws.remove_tool_widget @widget
142
+ stack.should be_hidden
143
+ end
144
+
145
+ it 'should find out the tool to remove from its name if passed a string argument' do
146
+ @widget.object_name = 'tool1'
147
+ flexmock(@bar).should_receive(:remove_tab).once.with(@id)
148
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
149
+ flexmock(stack).should_receive(:remove_widget).with(@widget).once
150
+ #Mocking empty? is needed because otherwise resize_tool is called (because the tool hasn't truly been removed, since we mocked the method)
151
+ flexmock(stack).should_receive(:empty?).and_return true
152
+ @ws.remove_tool_widget 'tool1'
153
+ end
154
+
155
+ it 'should find out the tool to remove from its name if passed a symbol argument' do
156
+ @widget.object_name = 'tool1'
157
+ flexmock(@bar).should_receive(:remove_tab).once.with(@id)
158
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
159
+ flexmock(stack).should_receive(:remove_widget).with(@widget).once
160
+ #Mocking empty? is needed because otherwise resize_tool is called (because the tool hasn't truly been removed, since we mocked the method)
161
+ flexmock(stack).should_receive(:empty?).and_return true
162
+ @ws.remove_tool_widget :tool1
163
+ end
164
+
165
+ it 'should do nothing if the widget isn\'t a tool widget' do
166
+ lambda{@ws.remove_tool_widget(Qt::Widget.new)}.should_not raise_error
167
+ lambda{@ws.remove_tool_widget(:xyz)}.should_not raise_error
168
+ end
169
+
170
+ end
171
+
172
+ describe 'Ruber::Workspace#raise_tool' do
173
+
174
+ before do
175
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
176
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
177
+ @ws = Ruber::Workspace.new
178
+ @widgets = [Qt::Label.new, Qt::TextEdit.new]
179
+ pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
180
+ @ws.add_tool_widget :bottom, @widgets[0], pix, 'Tool1'
181
+ @ws.add_tool_widget :bottom, @widgets[1], pix, 'Tool2'
182
+ @data = @ws.instance_variable_get :@widgets
183
+ end
184
+
185
+ it 'should lower the tab corresponding to the previously raised tool in the bar' do
186
+ bar = @ws.instance_variable_get(:@button_bars)[:bottom]
187
+ @ws.raise_tool @widgets[0]
188
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
189
+ bar.is_tab_raised(@data[@widgets[0]].id).should be_true
190
+ @ws.raise_tool @widgets[1]
191
+ bar.is_tab_raised(@data[@widgets[0]].id).should be_false
192
+ end
193
+
194
+ it 'should raise the tab corresponding to the widget' do
195
+ bar = @ws.instance_variable_get(:@button_bars)[:bottom]
196
+ bar.is_tab_raised(@data[@widgets[0]].id).should_not be
197
+ @ws.raise_tool @widgets[0]
198
+ bar.is_tab_raised(@data[@widgets[0]].id).should be_true
199
+ end
200
+
201
+ it 'should put the widget on top of its stack' do
202
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
203
+ stack.current_widget.should == @widgets[0]
204
+ @ws.raise_tool @widgets[1]
205
+ stack.current_widget.should == @widgets[1]
206
+ end
207
+
208
+ it 'should emit the "tool_raised(QWidget*)" signal' do
209
+ m = flexmock{|mk| mk.should_receive(:tool_raised).once.with(@widgets[0])}
210
+ stack = @widgets[0].parent
211
+ stack.current_widget = @widgets[1]
212
+ @ws.connect(SIGNAL('tool_raised(QWidget*)')){|w| m.tool_raised w}
213
+ @ws.raise_tool @widgets[0]
214
+ end
215
+
216
+ it 'should emit the tool_shown(QWidget*) signal if the stack was visible and the widget wasn\'t' do
217
+ stack = @widgets[0].parent
218
+ flexmock(stack).should_receive(:current_widget).and_return @widgets[1]
219
+ flexmock(stack).should_receive(:visible?).and_return true
220
+ m = flexmock{|mk| mk.should_receive(:tool_shown).once.with(@widgets[0])}
221
+ @ws.connect(SIGNAL('tool_shown(QWidget*)')){|w| m.tool_shown w}
222
+ @ws.raise_tool @widgets[0]
223
+ end
224
+
225
+ it 'should not emit the tool_shown(QWidget*) signal if the stack and the tool widget were visible' do
226
+ stack = @widgets[0].parent
227
+ flexmock(stack).should_receive(:visible?).and_return true
228
+ flexmock(stack).should_receive(:current_widget).and_return @widgets[0]
229
+ m = flexmock{|mk| mk.should_receive(:tool_shown).never.with(@widgets[0])}
230
+ @ws.connect(SIGNAL('tool_shown(QWidget*)')){|w| m.tool_shown w}
231
+ @ws.raise_tool @widgets[0]
232
+ end
233
+
234
+ it 'should not emit the tool_shown(QWidget*) signal if the stack wasn\'t visible' do
235
+ stack = @widgets[0].parent
236
+ flexmock(stack).should_receive(:visible?).and_return false
237
+ flexmock(stack).should_receive(:current_widget).and_return @widgets[1]
238
+ m = flexmock{|mk| mk.should_receive(:tool_shown).never.with(@widgets[0])}
239
+ @ws.connect(SIGNAL('tool_shown(QWidget*)')){|w| m.tool_shown w}
240
+ @ws.raise_tool @widgets[0]
241
+ end
242
+
243
+ it 'should call the resize_tool method' do
244
+ @widgets[0].parent.current_widget = @widgets[1]
245
+ flexmock(@ws).should_receive(:resize_tool).once.with(@widgets[0])
246
+ @ws.raise_tool @widgets[0]
247
+ end
248
+
249
+ it 'should work when passing the widget\'s object name instead of the widget itself' do
250
+ @widgets[1].object_name = 'tool 2'
251
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
252
+ stack.current_widget.should == @widgets[0]
253
+ @ws.raise_tool 'tool 2'
254
+ stack.current_widget.should == @widgets[1]
255
+ end
256
+
257
+ it 'should work when passing the widget\'s object name as a symbol instead of the widget itself' do
258
+ @widgets[1].object_name = 'tool2'
259
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
260
+ stack.current_widget.should == @widgets[0]
261
+ @ws.raise_tool :tool2
262
+ stack.current_widget.should == @widgets[1]
263
+ end
264
+
265
+ it 'should do nothing if the argument isn\'t a valid tool widget' do
266
+ @ws.raise_tool @widgets[0]
267
+ lambda{@ws.raise_tool Qt::Widget.new}.should_not raise_error
268
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
269
+ stack.current_widget.should equal(@widgets[0])
270
+ lambda{@ws.raise_tool 'xyz'}.should_not raise_error
271
+ stack.current_widget.should equal(@widgets[0])
272
+ end
273
+
274
+ it 'should store the size of the previously current tool widget, if it was visible' do
275
+ @ws.raise_tool @widgets[0]
276
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
277
+ flexmock(@ws).should_receive(:store_tool_size).with(@widgets[0]).once
278
+ @ws.raise_tool @widgets[1]
279
+ end
280
+
281
+ it 'should not store the size of the previously current tool widget, if it wasn\'t visible' do
282
+ @ws.raise_tool @widgets[0]
283
+ flexmock(@widgets[0]).should_receive(:visible?).and_return false
284
+ flexmock(@ws).should_receive(:store_tool_size).with(@widgets[0]).never
285
+ @ws.raise_tool @widgets[1]
286
+ end
287
+
288
+ it 'should not attempt to store the size of the previously current tool widget if there was none' do
289
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
290
+ flexmock(stack).should_receive(:current_widget).and_return nil
291
+ flexmock(@ws).should_receive(:store_tool_size).never
292
+ @ws.raise_tool @widgets[1]
293
+ end
294
+
295
+
296
+ end
297
+
298
+ describe 'Ruber::Workspace#show_tool' do
299
+
300
+ before do
301
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
302
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
303
+ @ws = Ruber::Workspace.new
304
+ @widgets = [Qt::Label.new, Qt::TextEdit.new]
305
+ pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
306
+ @ws.add_tool_widget :bottom, @widgets[0], pix, 'Tool1'
307
+ @ws.add_tool_widget :bottom, @widgets[1], pix, 'Tool2'
308
+ @data = @ws.instance_variable_get :@widgets
309
+ end
310
+
311
+ it 'should raise the given tool, unless it\'s already raised' do
312
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
313
+ stack.current_widget.should equal(@widgets[0])
314
+ flexmock(@ws).should_receive(:raise_tool).with(@widgets[1]).once
315
+ @ws.show_tool @widgets[1]
316
+ end
317
+
318
+ it 'should show the stack where the tool widget is, if it isn\'t already visible' do
319
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
320
+ stack.should be_hidden
321
+ flexmock(stack).should_receive(:show).once
322
+ @ws.show_tool @widgets[1]
323
+ end
324
+
325
+ it 'should not show the stack where the tool widget is if it\'s already visible' do
326
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
327
+ stack.visible = true
328
+ flexmock(stack).should_receive(:visible?).and_return true
329
+ flexmock(stack).should_receive(:show).never
330
+ @ws.show_tool @widgets[1]
331
+ end
332
+
333
+ it 'should emit the tool_shown(QWidget*) signal if the widget was previously hidden' do
334
+ flexmock(@widgets[1]).should_receive(:visible?).and_return false
335
+ m = flexmock{|mk| mk.should_receive(:tool_shown).once.with(@widgets[1])}
336
+ @ws.connect(SIGNAL('tool_shown(QWidget*)')){|w| m.tool_shown w}
337
+ @ws.show_tool @widgets[1]
338
+ end
339
+
340
+ it 'should not emit the tool_shown(QWidget*) signal if the widget was already visible' do
341
+ flexmock(@widgets[1]).should_receive(:visible?).and_return true
342
+ m = flexmock{|mk| mk.should_receive(:tool_shown).never.with(@widgets[1])}
343
+ @ws.connect(SIGNAL('tool_shown(QWidget*)')){|w| m.tool_shown w}
344
+ @ws.show_tool @widgets[1]
345
+ end
346
+
347
+ it 'should give focus to the tool widget if the previously current widget of its stack had focus' do
348
+ @ws.show_tool @widgets[0]
349
+ flexmock(@widgets[0]).should_receive(:has_focus).and_return true
350
+ flexmock(@widgets[1]).should_receive(:has_focus).and_return false
351
+ flexmock(@widgets[1]).should_receive(:set_focus).once
352
+ @ws.show_tool @widgets[1]
353
+ end
354
+
355
+ it 'should not give focus to the tool widget if the previously current widget of its stack didn\'t have focus' do
356
+ @ws.show_tool @widgets[0]
357
+ flexmock(@widgets[0]).should_receive(:has_focus).and_return false
358
+ flexmock(@widgets[1]).should_receive(:has_focus).and_return false
359
+ flexmock(@widgets[1]).should_receive(:set_focus).never
360
+ @ws.show_tool @widgets[1]
361
+ end
362
+
363
+ it 'should work when passing the widget\'s object name instead of the widget itself' do
364
+ @widgets[1].object_name = 'tool 2'
365
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
366
+ stack.current_widget.should == @widgets[0]
367
+ @ws.show_tool 'tool 2'
368
+ stack.current_widget.should == @widgets[1]
369
+ end
370
+
371
+ it 'should work when passing the widget\'s object name as a symbol instead of the widget itself' do
372
+ @widgets[1].object_name = 'tool2'
373
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
374
+ stack.current_widget.should == @widgets[0]
375
+ @ws.show_tool :tool2
376
+ stack.current_widget.should == @widgets[1]
377
+ end
378
+
379
+ it 'should do nothing if the argument isn\'t a valid tool widget' do
380
+ @ws.raise_tool @widgets[0]
381
+ lambda{@ws.show_tool Qt::Widget.new}.should_not raise_error
382
+ stack = @ws.instance_variable_get(:@stacks)[:bottom]
383
+ stack.current_widget.should equal(@widgets[0])
384
+ lambda{@ws.show_tool 'xyz'}.should_not raise_error
385
+ stack.current_widget.should equal(@widgets[0])
386
+ end
387
+
388
+ end
389
+
390
+ describe 'Ruber::Workspace#activate_tool' do
391
+
392
+ before do
393
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
394
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
395
+ @ws = Ruber::Workspace.new
396
+ @widgets = [Qt::Label.new, Qt::TextEdit.new]
397
+ pix = KDE::IconLoader.global.load_icon('document-new', KDE::IconLoader::Toolbar)
398
+ @ws.add_tool_widget :bottom, @widgets[0], pix, 'Tool1'
399
+ @ws.add_tool_widget :bottom, @widgets[1], pix, 'Tool2'
400
+ @data = @ws.instance_variable_get :@widgets
401
+ end
402
+
403
+ it 'should call the show_tool method if the tool is not visible' do
404
+ @widgets[0].should_not be_visible
405
+ flexmock(@ws).should_receive(:show_tool).with(@widgets[0]).once
406
+ @ws.activate_tool @widgets[0]
407
+ end
408
+
409
+ it 'should not call the show_tool method if the tool is already visible' do
410
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
411
+ flexmock(@ws).should_receive(:show_tool).with(@widgets[0]).never
412
+ @ws.activate_tool @widgets[0]
413
+ end
414
+
415
+ it 'should give focus to the tool widget' do
416
+ flexmock(@widgets[0]).should_receive(:set_focus).once
417
+ @ws.activate_tool @widgets[0]
418
+ end
419
+
420
+ it 'should work when passing the widget\'s object name instead of the widget itself' do
421
+ @widgets[1].object_name = 'tool2'
422
+ flexmock(@widgets[1]).should_receive(:set_focus).once
423
+ @ws.activate_tool 'tool2'
424
+ end
425
+
426
+ it 'should work when passing the widget\'s object name as a symbol instead of the widget itself' do
427
+ @widgets[1].object_name = 'tool2'
428
+ flexmock(@widgets[1]).should_receive(:set_focus).once
429
+ @ws.activate_tool :tool2
430
+ end
431
+
432
+ it 'should do nothing if the argument isn\'t a valid tool widget' do
433
+ @ws.raise_tool @widgets[0]
434
+ lambda{@ws.activate_tool Qt::Widget.new}.should_not raise_error
435
+ lambda{@ws.activate_tool 'xyz'}.should_not raise_error
436
+ end
437
+
438
+ end
439
+
440
+ describe 'Ruber::Workspace#hide_tool' do
441
+
442
+ before do
443
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
444
+ @mw = flexmock{|m| m.should_receive(:focus_on_editor).by_default}
445
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
446
+ flexmock(Ruber).should_receive(:[]).with(:main_window).and_return(@mw).by_default
447
+ @ws = Ruber::Workspace.new
448
+ @widgets = [Qt::LineEdit.new, Qt::GraphicsView.new]
449
+ @ws.add_tool_widget :left, @widgets[0], Qt::Pixmap.new, 'Tool1'
450
+ @ws.add_tool_widget :left, @widgets[1], Qt::Pixmap.new, 'Tool2'
451
+ end
452
+
453
+ it 'should store the size of the tool if it is visible' do
454
+ @ws.show_tool @widgets[0]
455
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
456
+ flexmock(@ws).should_receive(:store_tool_size).with(@widgets[0]).once
457
+ @ws.hide_tool @widgets[0]
458
+ end
459
+
460
+ it 'should not store the size of the tool if it isn\'t visible' do
461
+ @ws.show_tool @widgets[0]
462
+ flexmock(@widgets[0]).should_receive(:visible?).and_return false
463
+ flexmock(@ws).should_receive(:store_tool_size).with(@widgets[0]).never
464
+ @ws.hide_tool @widgets[0]
465
+ end
466
+
467
+ it 'should deactivate the tab corresponding to the raised tool, if the tool is raised' do
468
+ @ws.show_tool @widgets[0]
469
+ bar = @ws.instance_variable_get(:@button_bars)[:left]
470
+ stack = @widgets[0].parent
471
+ id = @ws.instance_variable_get(:@widgets)[@widgets[0]].id
472
+ flexmock(stack).should_receive(:current_widget).and_return @widgets[0]
473
+ flexmock(bar).should_receive(:set_tab).with(id, false).once
474
+ @ws.hide_tool @widgets[0]
475
+ end
476
+
477
+ it 'shouldn\'t deactivate the tab corresponding to the raised tool, if the tool is not raised' do
478
+ @ws.show_tool @widgets[1]
479
+ bar = @ws.instance_variable_get(:@button_bars)[:left]
480
+ stack = @widgets[0].parent
481
+ id = @ws.instance_variable_get(:@widgets)[@widgets[0]].id
482
+ flexmock(stack).should_receive(:current_widget).and_return @widgets[1]
483
+ flexmock(bar).should_receive(:set_tab).with(id, false).never
484
+ @ws.hide_tool @widgets[0]
485
+ end
486
+
487
+ it 'should hide the tool\'s stack if it is visible and the tool is raised' do
488
+ @ws.show_tool @widgets[0]
489
+ stack = @widgets[0].parent
490
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
491
+ flexmock(stack).should_receive(:visible?).and_return true
492
+ flexmock(stack).should_receive(:hide).once
493
+ @ws.hide_tool @widgets[0]
494
+ end
495
+
496
+ it 'should not hide the tool\'s stack if the tool isn\'t raised' do
497
+ @ws.show_tool @widgets[1]
498
+ stack = @widgets[0].parent
499
+ flexmock(@widgets[0]).should_receive(:visible?).and_return false
500
+ flexmock(stack).should_receive(:visible?).and_return true
501
+ flexmock(stack).should_receive(:hide).never
502
+ @ws.hide_tool @widgets[0]
503
+ end
504
+
505
+ it 'should give focus to the active editor if the stack becomes hidden' do
506
+ @ws.show_tool @widgets[0]
507
+ stack = @widgets[0].parent
508
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
509
+ flexmock(stack).should_receive(:visible?).and_return true
510
+ @mw.should_receive(:focus_on_editor).once
511
+ @ws.hide_tool @widgets[0]
512
+ end
513
+
514
+ it 'should not hide the tool\'s stack if it is already hidden' do
515
+ @ws.show_tool @widgets[0]
516
+ stack = @widgets[0].parent
517
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
518
+ flexmock(stack).should_receive(:visible?).and_return false
519
+ flexmock(stack).should_receive(:hide).never
520
+ @ws.hide_tool @widgets[0]
521
+ end
522
+
523
+ it 'should give focus to the active editor if the stack doesn\'t become hidden' do
524
+ @ws.show_tool @widgets[0]
525
+ stack = @widgets[0].parent
526
+ flexmock(@widgets[0]).should_receive(:visible?).and_return true
527
+ flexmock(stack).should_receive(:visible?).and_return false
528
+ @mw.should_receive(:focus_on_editor).never
529
+ @ws.hide_tool @widgets[0]
530
+ end
531
+
532
+
533
+ it 'should work when passing the widget\'s object name instead of the widget itself' do
534
+ @ws.raise_tool @widgets[0]
535
+ flexmock(@widgets[0]).should_receive(:visible?).and_return(:true)
536
+ stack = @widgets[0].parent
537
+ flexmock(stack).should_receive(:visible?).and_return true
538
+ flexmock(stack).should_receive(:hide).once
539
+ @widgets[0].object_name = 'tool1'
540
+ @ws.hide_tool 'tool1'
541
+ end
542
+
543
+ it 'should work when passing the widget\'s object name as a symbol instead of the widget itself' do
544
+ @ws.raise_tool @widgets[0]
545
+ flexmock(@widgets[0]).should_receive(:visible?).and_return(:true)
546
+ stack = @widgets[0].parent
547
+ flexmock(stack).should_receive(:visible?).and_return true
548
+ flexmock(stack).should_receive(:hide).once
549
+ @widgets[0].object_name = 'tool1'
550
+ @ws.hide_tool :tool1
551
+ end
552
+
553
+
554
+ it 'should do nothing if the argument isn\'t a valid tool widget' do
555
+ @ws.raise_tool @widgets[0]
556
+ lambda{@ws.hide_tool Qt::Widget.new}.should_not raise_error
557
+ lambda{@ws.hide_tool 'xyz'}.should_not raise_error
558
+ end
559
+
560
+
561
+ end
562
+
563
+ describe 'Ruber::Workspace#toggle_tool' do
564
+
565
+ before do
566
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
567
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
568
+ @ws = Ruber::Workspace.new
569
+ @widgets = [Qt::LineEdit.new, Qt::GraphicsView.new]
570
+ @ws.add_tool_widget :left, @widgets[0], Qt::Pixmap.new, 'Tool1'
571
+ @ws.add_tool_widget :left, @widgets[1], Qt::Pixmap.new, 'Tool2'
572
+ end
573
+
574
+ it 'should activate the tool if it is not visible' do
575
+ flexmock(@widgets[1]).should_receive(:visible?).and_return false
576
+ flexmock(@ws).should_receive(:activate_tool).once.with(@widgets[1])
577
+ @ws.toggle_tool @widgets[1]
578
+ end
579
+
580
+ it 'should hide the tool\'s stack if the tool is visible' do
581
+ flexmock(@widgets[1]).should_receive(:visible?).and_return true
582
+ flexmock(@ws).should_receive(:hide_tool).once
583
+ @ws.toggle_tool @widgets[1]
584
+ end
585
+
586
+ it 'should work if the argument is the id of the tab associated with the tool' do
587
+ id = @ws.instance_variable_get(:@widgets)[@widgets[1]].id
588
+ flexmock(@widgets[1]).should_receive(:visible?).and_return false
589
+ flexmock(@ws).should_receive(:activate_tool).once.with(@widgets[1])
590
+ @ws.toggle_tool id
591
+ end
592
+
593
+ it 'should work if the argument is the object_name of the widget as a string' do
594
+ @widgets[1].object_name = 'tool2'
595
+ id = @ws.instance_variable_get(:@widgets)[@widgets[1]].id
596
+ flexmock(@widgets[1]).should_receive(:visible?).and_return false
597
+ flexmock(@ws).should_receive(:activate_tool).once.with(@widgets[1])
598
+ @ws.toggle_tool 'tool2'
599
+ end
600
+
601
+ it 'should work if the argument is the object_name of the widget as a string' do
602
+ @widgets[1].object_name = 'tool2'
603
+ id = @ws.instance_variable_get(:@widgets)[@widgets[1]].id
604
+ flexmock(@widgets[1]).should_receive(:visible?).and_return false
605
+ flexmock(@ws).should_receive(:activate_tool).once.with(@widgets[1])
606
+ @ws.toggle_tool :tool2
607
+ end
608
+
609
+ it 'should do nothing if the argument is not a valid tool widget' do
610
+ id = @ws.instance_variable_get(:@widgets)[@widgets[1]].id
611
+ flexmock(@widgets[1]).should_receive(:visible?).and_return false
612
+ flexmock(@ws).should_receive(:activate_tool).with(@widgets[1]).never
613
+ lambda{@ws.toggle_tool Qt::Widget.new}.should_not raise_error
614
+ lambda{@ws.toggle_tool 'xyz'}.should_not raise_error
615
+ lambda{@ws.toggle_tool :xyz}.should_not raise_error
616
+ lambda{@ws.toggle_tool -7}.should_not raise_error
617
+ end
618
+
619
+ end
620
+
621
+ describe 'Ruber::Workspace, when a tool widget tab is clicked' do
622
+
623
+ before do
624
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
625
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
626
+ @ws = Ruber::Workspace.new
627
+ @widgets = [Qt::LineEdit.new, Qt::GraphicsView.new]
628
+ @ws.add_tool_widget :left, @widgets[0], Qt::Pixmap.new, 'Tool1'
629
+ @ws.add_tool_widget :left, @widgets[1], Qt::Pixmap.new, 'Tool2'
630
+ end
631
+
632
+ it 'should toggle the tool widget corresponding to the tab' do
633
+ id = @ws.instance_variable_get(:@widgets)[@widgets[1]].id
634
+ flexmock(@ws).should_receive(:toggle_tool).once.with(id)
635
+ bar = @ws.instance_variable_get(:@button_bars)[:left]
636
+ bar.tab(id).instance_eval{emit clicked(id)}
637
+ end
638
+
639
+ end
640
+
641
+ describe 'Ruber::Workspace#resize_tool' do
642
+
643
+ before do
644
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
645
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
646
+ @ws = Ruber::Workspace.new
647
+ @widgets = {:left => Qt::LineEdit.new, :right => Qt::GraphicsView.new, :bottom => Qt::TextEdit.new}
648
+ @widgets.each_pair do |side, w|
649
+ @ws.add_tool_widget side, w, Qt::Pixmap.new, "Tool #{side}"
650
+ end
651
+ @sizes = {'Tool left' => 40, 'Tool right' => 37, 'Tool bottom' => 82}
652
+ @ws.instance_variable_set :@sizes, @sizes
653
+ end
654
+
655
+ it 'should resize the splitter so that the size corresponding to the tool is the one stored under its caption if the tool is on the bottom' do
656
+ splitter = @ws.instance_variable_get(:@splitters)[:vertical]
657
+ flexmock(splitter).should_receive(:sizes).and_return([100, 30])
658
+ flexmock(splitter).should_receive(:sizes=).with([48, 82]).once
659
+ @ws.send :resize_tool, @widgets[:bottom]
660
+ end
661
+
662
+ it 'should resize the splitter so that the size corresponding to the tool is the one stored under its caption if the tool is on the left' do
663
+ splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
664
+ flexmock(splitter).should_receive(:sizes).and_return([70, 100, 30])
665
+ flexmock(splitter).should_receive(:sizes=).with([40, 130, 30]).once
666
+ @ws.send :resize_tool, @widgets[:left]
667
+ end
668
+
669
+ it 'should resize the splitter so that the size corresponding to the tool is the one stored under its caption if the tool is on the right' do
670
+ splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
671
+ flexmock(splitter).should_receive(:sizes).and_return([70, 100, 30])
672
+ flexmock(splitter).should_receive(:sizes=).with([70, 93, 37]).once
673
+ @ws.send :resize_tool, @widgets[:right]
674
+ end
675
+
676
+ it 'should resize the widget to 150 if there isn\'t an entry for the widget' do
677
+ @sizes.delete 'Tool right'
678
+ splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
679
+ flexmock(splitter).should_receive(:sizes).and_return([70, 300, 30])
680
+ flexmock(splitter).should_receive(:sizes=).with([70, 180, 150]).once
681
+ @ws.send :resize_tool, @widgets[:right]
682
+ end
683
+
684
+ end
685
+
686
+ describe 'Ruber::Workspace#store_tool_size' do
687
+
688
+ before do
689
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
690
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
691
+ @ws = Ruber::Workspace.new
692
+ @widgets = {:left => Qt::LineEdit.new, :right => Qt::GraphicsView.new, :bottom => Qt::TextEdit.new}
693
+ @widgets.each_pair do |side, w|
694
+ @ws.add_tool_widget side, w, Qt::Pixmap.new, "Tool #{side}"
695
+ end
696
+ end
697
+
698
+ it 'should store the size of the widget in the @sizes instance variable, using the widget\'s caption as key when the tool is at the bottom' do
699
+ splitter = @ws.instance_variable_get(:@splitters)[:vertical]
700
+ flexmock(splitter).should_receive(:sizes).and_return [100,20]
701
+ @ws.send :store_tool_size, @widgets[:bottom]
702
+ @ws.instance_variable_get(:@sizes)['Tool bottom'].should == 20
703
+ end
704
+
705
+ it 'should store the size of the widget in the @sizes instance variable, using the widget\'s caption as key when the tool is on the left' do
706
+ splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
707
+ flexmock(splitter).should_receive(:sizes).and_return [30,100,20]
708
+ @ws.send :store_tool_size, @widgets[:left]
709
+ @ws.instance_variable_get(:@sizes)['Tool left'].should == 30
710
+ end
711
+
712
+ it 'should store the size of the widget in the @sizes instance variable, using the widget\'s caption as key when the tool is on the right' do
713
+ splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
714
+ flexmock(splitter).should_receive(:sizes).and_return [30,100,20]
715
+ @ws.send :store_tool_size, @widgets[:right]
716
+ @ws.instance_variable_get(:@sizes)['Tool right'].should == 20
717
+ end
718
+
719
+ end
720
+
721
+ describe 'Ruber::Workspace#store_sizes' do
722
+
723
+ before do
724
+ @config = flexmock do |m|
725
+ m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default
726
+ m.should_receive(:[]=).by_default
727
+ end
728
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
729
+ @ws = Ruber::Workspace.new
730
+ @widgets = {:left => Qt::LineEdit.new, :right => Qt::GraphicsView.new, :bottom => Qt::TextEdit.new}
731
+ @widgets.each_pair do |side, w|
732
+ @ws.add_tool_widget side, w, Qt::Pixmap.new, "Tool #{side}"
733
+ end
734
+ end
735
+
736
+ it 'should call the store_tool_size method for each visible tool widget' do
737
+ w = Qt::Widget.new
738
+ @ws.add_tool_widget :bottom, w, Qt::Pixmap.new, "New tool"
739
+ flexmock(w).should_receive(:visible?).and_return false
740
+ flexmock(@widgets[:bottom]).should_receive(:visible?).and_return true
741
+ flexmock(@widgets[:right]).should_receive(:visible?).and_return true
742
+ flexmock(@widgets[:left]).should_receive(:visible?).and_return false
743
+ flexmock(@ws).should_receive(:store_tool_size).once.with @widgets[:bottom]
744
+ flexmock(@ws).should_receive(:store_tool_size).once.with @widgets[:right]
745
+ @ws.store_sizes
746
+ end
747
+
748
+ it 'should store the sizes in the configuration widget in the workspace group under the tools_sizes entry' do
749
+ flexmock(@widgets[:bottom]).should_receive(:visible?).and_return true
750
+ flexmock(@widgets[:right]).should_receive(:visible?).and_return false
751
+ flexmock(@widgets[:left]).should_receive(:visible?).and_return false
752
+ @ws.instance_variable_set :@sizes, {'Tool left' => 90, 'Tool right' => 10, 'Tool bottom' => 60}
753
+ splitter = @ws.instance_variable_get(:@splitters)[:vertical]
754
+ flexmock(splitter).should_receive(:sizes).and_return [100, 89]
755
+ @config.should_receive(:[]=).once.with(:workspace, :tools_sizes, {'Tool left' => 90, 'Tool right' => 10, 'Tool bottom' => 89})
756
+ @ws.store_sizes
757
+ end
758
+
759
+ end
760
+
761
+ describe 'Ruber::Workspace#tool_widgets' do
762
+
763
+ before do
764
+ @config = flexmock do |m|
765
+ m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default
766
+ m.should_receive(:[]=).by_default
767
+ end
768
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
769
+ @ws = Ruber::Workspace.new
770
+ @widgets = {:left => Qt::LineEdit.new, :right => Qt::GraphicsView.new, :bottom => Qt::TextEdit.new}
771
+ @widgets.each_pair do |side, w|
772
+ @ws.add_tool_widget side, w, Qt::Pixmap.new, "Tool #{side}"
773
+ end
774
+ end
775
+
776
+ it 'should return a hash containing all the tool widgets amd their positions' do
777
+ @ws.tool_widgets.should == @widgets.invert
778
+ end
779
+
780
+ end
781
+
782
+ describe 'Ruber::Workspace#active_tool' do
783
+
784
+ before do
785
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
786
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
787
+ @ws = Ruber::Workspace.new
788
+ @widgets = [Qt::LineEdit.new, Qt::TextEdit.new, Qt::CheckBox.new, Qt::Widget.new]
789
+ w = @widgets[-1]
790
+ @inner = [Qt::ListView.new(w), Qt::TreeWidget.new(w)]
791
+ sides = [:left, :right, :bottom, :bottom]
792
+ @widgets.each_with_index do |tool, i|
793
+ @ws.add_tool_widget sides[i], tool, Qt::Pixmap.new, "Tool #{i}"
794
+ end
795
+ end
796
+
797
+ it 'should return the application\'s focus widget, if it is a tool widget' do
798
+ flexmock(KDE::Application).should_receive(:focus_widget).once.and_return(@widgets[1])
799
+ @ws.active_tool.should equal(@widgets[1])
800
+ end
801
+
802
+ it 'should return the tool widget which contains the application\'s focus widget, if it is a child of a tool widget' do
803
+ flexmock(KDE::Application).should_receive(:focus_widget).once.and_return(@inner[0])
804
+ @ws.active_tool.should equal(@widgets[-1])
805
+ end
806
+
807
+ it 'should return nil if the application\'s focus widget is nil' do
808
+ flexmock(KDE::Application).should_receive(:focus_widget).once.and_return nil
809
+ @ws.active_tool.should be_nil
810
+ end
811
+
812
+ it 'should return nil if the application\'s focus widget is not one of tool widgets nor one of their children' do
813
+ w = Qt::Widget.new
814
+ flexmock(KDE::Application).should_receive(:focus_widget).once.and_return(w)
815
+ @ws.active_tool.should be_nil
816
+ end
817
+
818
+ end
819
+
820
+ describe Ruber::Workspace do
821
+
822
+ before do
823
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
824
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
825
+ @ws = Ruber::Workspace.new
826
+ @widgets = [Qt::LineEdit.new, Qt::TextEdit.new, Qt::CheckBox.new, Qt::Widget.new]
827
+ w = @widgets[-1]
828
+ @sides = [:left, :right, :bottom, :bottom]
829
+ end
830
+
831
+ describe '#current_widget' do
832
+
833
+ it 'returns the current widget on the left side if the argument is left' do
834
+ @sides = [:left, :right, :left, :bottom]
835
+ @widgets.each_with_index do |tool, i|
836
+ @ws.add_tool_widget @sides[i], tool, Qt::Pixmap.new, "Tool #{i}"
837
+ end
838
+ @ws.instance_variable_get(:@stacks)[:left].current_widget = @widgets[2]
839
+ @ws.current_widget(:left).should equal(@widgets[2])
840
+ end
841
+
842
+ it 'returnd the current widget on the right side if the argument is right' do
843
+ @sides = [:left, :right, :right, :bottom]
844
+ @widgets.each_with_index do |tool, i|
845
+ @ws.add_tool_widget @sides[i], tool, Qt::Pixmap.new, "Tool #{i}"
846
+ end
847
+ @ws.instance_variable_get(:@stacks)[:right].current_widget = @widgets[2]
848
+ @ws.current_widget(:right).should equal(@widgets[2])
849
+ end
850
+
851
+ it 'returns the current widget on the bottom side if the argument is bottom' do
852
+ @sides = [:left, :right, :bottom, :bottom]
853
+ @widgets.each_with_index do |tool, i|
854
+ @ws.add_tool_widget @sides[i], tool, Qt::Pixmap.new, "Tool #{i}"
855
+ end
856
+ @ws.instance_variable_get(:@stacks)[:bottom].current_widget = @widgets[3]
857
+ @ws.current_widget(:bottom).should equal(@widgets[3])
858
+ end
859
+
860
+ it 'returns nil if there is no widget on the given side' do
861
+ @ws.instance_variable_get(:@widgets).should be_empty
862
+ @ws.current_widget(:right).should be_nil
863
+ @ws.current_widget(:left).should be_nil
864
+ @ws.current_widget(:bottom).should be_nil
865
+ end
866
+
867
+ end
868
+
869
+ end