ruber 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGES +21 -0
  2. data/data/share/apps/ruber/ruberui.rc +3 -1
  3. data/lib/ruber/application/application.rb +22 -23
  4. data/lib/ruber/application/plugin.yaml +7 -2
  5. data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
  6. data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
  7. data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
  8. data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
  9. data/lib/ruber/application/ui/project_files_widget.rb +117 -0
  10. data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
  11. data/lib/ruber/component_manager.rb +14 -9
  12. data/lib/ruber/editor/document.rb +35 -5
  13. data/lib/ruber/kde_sugar.rb +16 -0
  14. data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
  15. data/lib/ruber/main_window/main_window.rb +131 -193
  16. data/lib/ruber/main_window/main_window_actions.rb +157 -58
  17. data/lib/ruber/main_window/main_window_internal.rb +145 -54
  18. data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
  19. data/lib/ruber/main_window/plugin.yaml +3 -6
  20. data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
  21. data/lib/ruber/main_window/workspace.rb +62 -32
  22. data/lib/ruber/output_widget.rb +20 -16
  23. data/lib/ruber/pane.rb +11 -5
  24. data/lib/ruber/project.rb +27 -12
  25. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
  26. data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
  27. data/lib/ruber/utils.rb +37 -4
  28. data/lib/ruber/version.rb +1 -1
  29. data/lib/ruber/world/document_factory.rb +121 -0
  30. data/lib/ruber/world/document_list.rb +396 -0
  31. data/lib/ruber/world/environment.rb +470 -0
  32. data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
  33. data/lib/ruber/world/plugin.yaml +11 -0
  34. data/lib/ruber/world/project_factory.rb +131 -0
  35. data/lib/ruber/world/project_list.rb +265 -0
  36. data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
  37. data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
  38. data/lib/ruber/world/world.rb +307 -0
  39. data/plugins/auto_end/auto_end.rb +135 -9
  40. data/plugins/autosave/autosave.rb +4 -4
  41. data/plugins/find_in_files/find_in_files.rb +5 -5
  42. data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
  43. data/plugins/project_browser/project_browser.rb +4 -4
  44. data/plugins/rake/rake.rb +4 -4
  45. data/plugins/rake/rake_extension.rb +1 -1
  46. data/plugins/rspec/rspec.rb +4 -4
  47. data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
  48. data/plugins/ruby_development/ruby_development.rb +3 -3
  49. data/plugins/ruby_runner/ruby_runner.rb +2 -2
  50. data/plugins/state/plugin.yaml +6 -8
  51. data/plugins/state/state.rb +201 -391
  52. data/plugins/state/ui/config_widget.rb +5 -5
  53. data/plugins/state/ui/config_widget.ui +3 -3
  54. data/plugins/syntax_checker/syntax_checker.rb +4 -0
  55. data/spec/annotation_model_spec.rb +1 -1
  56. data/spec/auto_end_spec.rb +98 -47
  57. data/spec/component_manager_spec.rb +80 -21
  58. data/spec/document_factory_spec.rb +115 -0
  59. data/spec/document_list_spec.rb +560 -450
  60. data/spec/document_spec.rb +143 -55
  61. data/spec/editor_view_spec.rb +2 -2
  62. data/spec/environment_spec.rb +1900 -0
  63. data/spec/hint_solver_spec.rb +5 -5
  64. data/spec/kde_sugar_spec.rb +16 -0
  65. data/spec/output_widget_spec.rb +177 -51
  66. data/spec/pane_spec.rb +29 -5
  67. data/spec/plugin_spec.rb +1 -1
  68. data/spec/project_factory_spec.rb +104 -0
  69. data/spec/project_list_spec.rb +352 -447
  70. data/spec/project_spec.rb +34 -33
  71. data/spec/qt_sugar_spec.rb +2 -2
  72. data/spec/state_spec.rb +508 -811
  73. data/spec/utils_spec.rb +149 -98
  74. data/spec/workspace_spec.rb +120 -9
  75. data/spec/world_spec.rb +1219 -0
  76. metadata +23 -14
  77. data/lib/ruber/documents/document_list.rb +0 -412
  78. data/lib/ruber/documents/plugin.yaml +0 -4
  79. data/lib/ruber/main_window/view_manager.rb +0 -431
  80. data/lib/ruber/projects/plugin.yaml +0 -11
  81. data/lib/ruber/projects/project_list.rb +0 -314
@@ -214,117 +214,168 @@ describe Ruber::Activable do
214
214
  @obj = @cls.new
215
215
  end
216
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
217
+ describe '#active?' do
218
+
219
+ it 'returns true if the object is active' do
220
+ @obj.instance_variable_set(:@active, true)
221
+ @obj.should be_active
222
+ end
223
+
224
+ it 'returns false if the the object is not active' do
225
+ @obj.instance_variable_set(:@active, false)
226
+ @obj.should_not be_active
227
+ end
230
228
 
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
229
  end
260
230
 
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
231
+ describe '#deactivate' do
232
+
233
+ it 'calls #active= with false as argument' do
234
+ flexmock(@obj).should_receive(:active=).with(false).once
235
+ @obj.deactivate
236
+ end
237
+
268
238
  end
269
239
 
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
240
+ describe '#activate' do
241
+
242
+ it 'calls #active= with true as argument' do
243
+ flexmock(@obj).should_receive(:active=).with(true).once
244
+ @obj.activate
245
+ end
246
+
275
247
  end
276
248
 
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
249
+ describe '#active=' do
250
+
251
+ it 'sets the @active instance value to the argument converted to a boolean' do
252
+ @obj.active = 'x'
253
+ @obj.instance_variable_get(:@active).should == true
254
+ @obj.active = nil
255
+ @obj.instance_variable_get(:@active).should == false
256
+ end
257
+
258
+ context 'when the argument is a false value' do
259
+
260
+ context 'if the object was active' do
261
+
262
+ before do
263
+ @obj.instance_variable_set :@active, true
264
+ end
265
+
266
+ it 'calls the object\'s do_deactivation method after changing the @active instance variable' do
267
+ $do_deactivation_called = false
268
+ $object_active = true
269
+ def @obj.do_deactivation
270
+ $object_active = self.active?
271
+ $do_deactivation_called = true
272
+ end
273
+ @obj.active = false
274
+ $object_active.should be_false
275
+ $do_deactivation_called.should be_true
276
+ end
277
+
278
+ end
279
+
280
+ context 'if the object was already inactive' do
281
+
282
+ before do
283
+ @obj.instance_variable_set :@active, false
284
+ end
285
+
286
+ it 'doesn\'t call the do_deactivation method' do
287
+ flexmock(@obj).should_receive(:do_deactivation).never
288
+ @obj.active = false
289
+ end
290
+
291
+ end
292
+
293
+ end
294
+
295
+ context 'when the argument is a true value' do
296
+
297
+ context 'if the object was inactive' do
298
+
299
+ before do
300
+ @obj.instance_variable_set :@active, false
301
+ end
302
+
303
+ it 'calls the object\'s do_activation method after changing the @active instance variable' do
304
+ $do_activation_called = false
305
+ $object_active = true
306
+ def @obj.do_activation
307
+ $object_active = self.active?
308
+ $do_activation_called = true
309
+ end
310
+ @obj.active = true
311
+ $object_active.should be_true
312
+ $do_activation_called.should be_true
313
+ end
314
+
315
+ end
316
+
317
+ context 'if the object was already active' do
318
+
319
+ before do
320
+ @obj.instance_variable_set :@active, true
321
+ end
322
+
323
+ it 'doesn\'t call the do_activation method' do
324
+ flexmock(@obj).should_receive(:do_activation).never
325
+ @obj.active = true
326
+ end
327
+
328
+ end
329
+
330
+ end
331
+
286
332
  end
287
333
 
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
334
+ describe '#do_deactivation' do
335
+
336
+ it 'emits the deactivated signal if the class including the module has that signal' do
337
+ mk = flexmock{|m| m.should_receive(:deactivated).once}
338
+ @obj.connect(SIGNAL(:deactivated)){mk.deactivated}
339
+ @obj.send :do_deactivation
340
+ end
341
+
342
+ it 'doesn\'t emit the signal if the including class doesn\'t have the deactivated signal' do
343
+ class << @obj
344
+ undef_method :deactivated
345
+ end
346
+ lambda{@obj.send :do_deactivation}.should_not raise_error
347
+ end
348
+
349
+ it 'doesn\'t emit the signal if the including class doesn\'t inherit from Qt::Object' do
350
+ obj = Object.new
351
+ obj.extend Ruber::Activable
352
+ lambda{obj.send :do_deactivation}.should_not raise_error
353
+ end
298
354
 
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
355
  end
313
356
 
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
357
+ describe '#do_activation' do
358
+
359
+ it 'emits the activated signal if the class including the module has that signal' do
360
+ mk = flexmock{|m| m.should_receive(:activated).once}
361
+ @obj.connect(SIGNAL(:activated)){mk.activated}
362
+ @obj.send :do_activation
363
+ end
364
+
365
+ it 'doesn\'t emit the signal if the including class doesn\'t have the activated signal' do
366
+ class << @obj
367
+ undef_method :activated
368
+ end
369
+ lambda{@obj.send :do_activation}.should_not raise_error
370
+ end
371
+
372
+ it 'doesn\'t emit the signal if the including class doesn\'t inherit from Qt::Object' do
373
+ obj = Object.new
374
+ obj.extend Ruber::Activable
375
+ lambda{obj.send :do_activation}.should_not raise_error
376
+ end
377
+
326
378
  end
327
-
328
379
 
329
380
  end
330
381
 
@@ -45,19 +45,16 @@ describe 'Ruber::Workspace, when created' do
45
45
  hsplit.widget(2).should be_a(Qt::StackedWidget)
46
46
  end
47
47
 
48
- it 'should put a KDE::TabWidget in the middle of the horizontal splitter' do
48
+ it 'puts a stacked widget in the middle of the horizontal splitter' do
49
+ @ws = Ruber::Workspace.new
49
50
  hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
50
- hsplit.widget(1).should be_a(KDE::TabWidget)
51
+ hsplit.widget(1).should be_a(Qt::StackedWidget)
51
52
  end
52
53
 
53
54
  it 'should have all the stacks hidden' do
54
55
  [:left, :bottom, :right].each{|s| @ws.instance_variable_get(:@stacks)[s].should be_hidden}
55
56
  end
56
57
 
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
58
  end
62
59
 
63
60
  describe 'Ruber::Workspace#add_tool_widget' do
@@ -444,7 +441,7 @@ describe 'Ruber::Workspace#hide_tool' do
444
441
  @mw = flexmock{|m| m.should_receive(:focus_on_editor).by_default}
445
442
  flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
446
443
  flexmock(Ruber).should_receive(:[]).with(:main_window).and_return(@mw).by_default
447
- @ws = Ruber::Workspace.new
444
+ @ws = Ruber::Workspace.new
448
445
  @widgets = [Qt::LineEdit.new, Qt::GraphicsView.new]
449
446
  @ws.add_tool_widget :left, @widgets[0], Qt::Pixmap.new, 'Tool1'
450
447
  @ws.add_tool_widget :left, @widgets[1], Qt::Pixmap.new, 'Tool2'
@@ -673,14 +670,22 @@ describe 'Ruber::Workspace#resize_tool' do
673
670
  @ws.send :resize_tool, @widgets[:right]
674
671
  end
675
672
 
676
- it 'should resize the widget to 150 if there isn\'t an entry for the widget' do
673
+ it 'does nothing if there isn\'t an entry for the widget' do
677
674
  @sizes.delete 'Tool right'
678
675
  splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
679
676
  flexmock(splitter).should_receive(:sizes).and_return([70, 300, 30])
680
- flexmock(splitter).should_receive(:sizes=).with([70, 180, 150]).once
677
+ flexmock(splitter).should_receive(:sizes=).never
681
678
  @ws.send :resize_tool, @widgets[:right]
682
679
  end
683
680
 
681
+ # it 'should resize the widget to 150 if there isn\'t an entry for the widget' do
682
+ # @sizes.delete 'Tool right'
683
+ # splitter = @ws.instance_variable_get(:@splitters)[:horizontal]
684
+ # flexmock(splitter).should_receive(:sizes).and_return([70, 300, 30])
685
+ # flexmock(splitter).should_receive(:sizes=).with([70, 180, 150]).once
686
+ # @ws.send :resize_tool, @widgets[:right]
687
+ # end
688
+
684
689
  end
685
690
 
686
691
  describe 'Ruber::Workspace#store_tool_size' do
@@ -866,4 +871,110 @@ describe Ruber::Workspace do
866
871
 
867
872
  end
868
873
 
874
+ end
875
+
876
+ describe Ruber::Workspace do
877
+
878
+ before do
879
+ @config = flexmock{|m| m.should_receive(:[]).with(:workspace, :tools_sizes).and_return({}).by_default}
880
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(@config).by_default
881
+
882
+ # @main_widget = KDE::TabWidget.new
883
+ @ws = Ruber::Workspace.new
884
+ end
885
+
886
+ describe '#add_widget' do
887
+
888
+ it 'adds the argument to the main stacked widget' do
889
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
890
+ stack = hsplit.widget(1)
891
+ tab_widget = KDE::TabWidget.new
892
+ @ws.add_widget tab_widget
893
+ stack.should include(tab_widget)
894
+ end
895
+
896
+ end
897
+
898
+ describe '#remove_widget' do
899
+
900
+ it 'removes the widget from the stacked widget' do
901
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
902
+ stack = hsplit.widget(1)
903
+ tab_widget = KDE::TabWidget.new
904
+ @ws.add_widget tab_widget
905
+ @ws.remove_widget tab_widget
906
+ stack.should_not include(tab_widget)
907
+ end
908
+
909
+ it 'does nothing if the widget is not contained in the stacked widget' do
910
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
911
+ stack = hsplit.widget(1)
912
+ tab_widget = KDE::TabWidget.new
913
+ lambda{@ws.remove_widget tab_widget}.should_not raise_error
914
+ stack.should_not include(tab_widget)
915
+ end
916
+
917
+ end
918
+
919
+ describe '#main_widget=' do
920
+
921
+ it 'brings the given widget to the front of the main stacked widget' do
922
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
923
+ stack = hsplit.widget(1)
924
+ tabs = Array.new(3){|i| KDE::TabWidget.new}
925
+ tabs.each{|w| @ws.add_widget w}
926
+ stack.current_widget = tabs[1]
927
+ @ws.main_widget= tabs[0]
928
+ stack.current_widget.should == tabs[0]
929
+ end
930
+
931
+ it 'raises ArgumentError if the widget has not been added to the stacked widget' do
932
+ tabs = Array.new(3){|i| KDE::TabWidget.new}
933
+ tabs.each{|w| @ws.add_widget w}
934
+ @ws.main_widget= tabs[0]
935
+ lambda{@ws.main_widget = KDE::TabWidget.new}.should raise_error(ArgumentError, "a widget which has not been added to the workspace can\'t become the main widget")
936
+ @ws.main_widget.should == tabs[0]
937
+ end
938
+
939
+ end
940
+
941
+ describe '#main_widget' do
942
+
943
+ it 'returns the widget set with main_widget=' do
944
+ tabs = Array.new(3){|i| KDE::TabWidget.new}
945
+ tabs.each{|w| @ws.add_widget w}
946
+ @ws.main_widget= tabs[1]
947
+ @ws.main_widget.should == tabs[1]
948
+ end
949
+
950
+ it 'returns the first added widget if main_widget= was never called' do
951
+ tabs = Array.new(3){|i| KDE::TabWidget.new}
952
+ tabs.each{|w| @ws.add_widget w}
953
+ @ws.main_widget.should == tabs[0]
954
+ end
955
+
956
+ end
957
+
958
+ describe '#central_widget=' do
959
+
960
+ it 'removes the current central widget from the splitter' do
961
+ @ws.main_widget = Qt::Label.new
962
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
963
+ hsplit.widget(1).should_not == @main_widget
964
+ end
965
+
966
+ it 'makes the current central widget parentless' do
967
+ @ws.main_widget = Qt::Label.new
968
+ @main_widget.parent.should be_nil
969
+ end
970
+
971
+ it 'inserts the argument in the layout in the place of the current central widget' do
972
+ new = Qt::Label.new
973
+ @ws.main_widget = new
974
+ hsplit = @ws.layout.item_at_position(0,1).widget.widget(0)
975
+ hsplit.widget(1).should == new
976
+ end
977
+
978
+ end
979
+
869
980
  end
@@ -0,0 +1,1219 @@
1
+ require 'spec/framework'
2
+ require 'spec/common'
3
+
4
+ require 'ruber/world/world'
5
+
6
+ require 'tmpdir'
7
+ require 'tempfile'
8
+ require 'fileutils'
9
+
10
+ describe Ruber::World::World do
11
+
12
+ before :all do
13
+ class KDE::TabWidget
14
+ def show
15
+ end
16
+ end
17
+ end
18
+
19
+ after :all do
20
+ class KDE::TabWidget
21
+ remove_method :show
22
+ end
23
+ end
24
+
25
+ before do
26
+ #needed because otherwise the config manager would complain when running the
27
+ #next test because the option had already been added
28
+ Ruber[:config].remove_setting :workspace, :close_buttons
29
+ @psf = Ruber::PluginSpecification.full File.expand_path('lib/ruber/world/plugin.yaml')
30
+ @world = Ruber::World::World.new Ruber[:components], @psf
31
+ #remove the default document from the game
32
+ @world.default_environment.documents[0].close
33
+ end
34
+
35
+ it 'includes Ruber::PluginLike' do
36
+ Ruber::World::World.ancestors.should include(Ruber::PluginLike)
37
+ end
38
+
39
+ it 'derives from Qt::Object' do
40
+ Ruber::World::World.ancestors.should include(Qt::Object)
41
+ end
42
+
43
+ describe 'when created' do
44
+
45
+ before do
46
+ @psf = Ruber::PluginSpecification.full File.expand_path('lib/ruber/world/plugin.yaml')
47
+ flexmock(Ruber[:components]).should_receive(:add).by_default
48
+ end
49
+
50
+ it 'sets the application as parent' do
51
+ @world.parent.should == Ruber[:app]
52
+ end
53
+
54
+ it 'registers itself with the component manager' do
55
+ Ruber[:components][:world].should be_an_instance_of(Ruber::World::World)
56
+ end
57
+
58
+ it 'creates a default environment associated with no project' do
59
+ env = @world.default_environment
60
+ env.should be_a(Ruber::World::Environment)
61
+ env.project.should be_nil
62
+ end
63
+
64
+ end
65
+
66
+ describe '#new_document' do
67
+
68
+ it 'returns a new pristine document' do
69
+ doc1 = @world.new_document
70
+ doc2 = @world.new_document
71
+ doc1.should_not == doc2
72
+ doc1.should be_pristine
73
+ end
74
+
75
+ it 'makes the document child of the world' do
76
+ @world.new_document.parent.should == @world
77
+ end
78
+
79
+ it 'emits the document_created signal passing the document as argument' do
80
+ doc = Ruber::Document.new
81
+ flexmock(Ruber::Document).should_receive(:new).once.and_return doc
82
+ mk = flexmock{|m| m.should_receive(:test).once.with(doc)}
83
+ @world.connect(SIGNAL('document_created(QObject*)')){|doc| mk.test doc}
84
+ @world.new_document
85
+ end
86
+
87
+ it 'add the document to the list of documents' do
88
+ docs = Array.new{@world.new_document}
89
+ list = @world.documents
90
+ docs.each{|d| list.should include(d)}
91
+ end
92
+
93
+ end
94
+
95
+ describe '#document' do
96
+
97
+ it 'returns a new document for the given file or URL, if no other document for it exists' do
98
+ doc = @world.document __FILE__
99
+ doc.path.should == __FILE__
100
+ end
101
+
102
+ it 'makes the document child of self' do
103
+ @world.document(__FILE__).parent.should == @world
104
+ end
105
+
106
+ it 'returns an existing document for the same file, if it already exists' do
107
+ old = @world.document __FILE__
108
+ new = @world.document __FILE__
109
+ new.should == old
110
+ end
111
+
112
+ it 'emits the document_created signal passing the document as argument if a new document has been created' do
113
+ doc = Ruber::Document.new __FILE__
114
+ flexmock(Ruber::Document).should_receive(:new).once.with(__FILE__, @world).and_return doc
115
+ mk = flexmock{|m| m.should_receive(:test).once.with(doc)}
116
+ @world.connect(SIGNAL('document_created(QObject*)')){|doc| mk.test doc}
117
+ @world.document __FILE__
118
+ end
119
+
120
+ it 'returns the existing file even if of the two calls to document one was passed a string and the other an URL' do
121
+ old = @world.document KDE::Url.new(__FILE__)
122
+ new = @world.document __FILE__
123
+ new.should == old
124
+ end
125
+
126
+ it 'does not attempt to return a document which has been closed' do
127
+ old = @world.document __FILE__
128
+ old.close
129
+ new = @world.document __FILE__
130
+ new.should_not == old
131
+ end
132
+
133
+ it 'returns an existing document even if it was created without a file and saved with the new name later' do
134
+ old = @world.document nil
135
+ url = KDE::Url.new __FILE__
136
+ flexmock(old).should_receive(:url).and_return url
137
+ old.instance_eval{emit document_url_changed(self)}
138
+ new = @world.document __FILE__
139
+ new.should == old
140
+ end
141
+
142
+ it 'returns an existing document even if it was created for another file then
143
+ saved with the new name later' do
144
+ old = @world.document File.join File.dirname(__FILE__), 'common.rb'
145
+ url = KDE::Url.new __FILE__
146
+ flexmock(old).should_receive(:url).and_return url
147
+ old.instance_eval{emit document_url_changed(self)}
148
+ new = @world.document __FILE__
149
+ new.should == old
150
+ end
151
+
152
+ it 'doesn\'t return a document which was created for the same file but was saved with another name later' do
153
+ old = @world.document __FILE__
154
+ url = KDE::Url.new File.join(File.dirname(__FILE__), 'common.rb')
155
+ flexmock(old).should_receive(:url).and_return url
156
+ old.instance_eval{emit document_url_changed(self)}
157
+ new = @world.document __FILE__
158
+ new.should_not == old
159
+ end
160
+
161
+ it 'returns nil if the file is a local file and it doesn\'t exist' do
162
+ @world.document('/xyz').should be_nil
163
+ @world.document(KDE::Url.new('/xyz')).should be_nil
164
+ end
165
+
166
+ end
167
+
168
+ context 'when a document is closed' do
169
+
170
+ it 'emits the closing_document signal passing the document as argument' do
171
+ doc = @world.new_document
172
+ mk = flexmock{|m| m.should_receive(:test).with(doc.object_id).once}
173
+ @world.connect(SIGNAL('closing_document(QObject*)')){|d| mk.test d.object_id}
174
+ doc.close
175
+ end
176
+
177
+ end
178
+
179
+ context 'when the active editor changes' do
180
+
181
+ context 'if the editor associated with the new document is different from the one associated with the previously active environment' do
182
+
183
+ before do
184
+ @env = @world.default_environment
185
+ @world.active_environment = @env
186
+ @docs = Array.new(2){@world.new_document}
187
+ @views = @docs.map{|doc| @env.editor_for! doc}
188
+ @env.activate_editor @views[1]
189
+ end
190
+
191
+ it 'changes the active document' do
192
+ @env.activate_editor @views[0]
193
+ @world.active_document.should == @docs[0]
194
+ end
195
+
196
+ it 'emits the active_editor_changed signal passing the new active editor as argument' do
197
+ mk = flexmock{|m| m.should_receive(:test).with(@views[0].object_id).once}
198
+ @world.connect(SIGNAL('active_editor_changed(QWidget*)')) do |view|
199
+ mk.test view.object_id
200
+ end
201
+ @env.activate_editor @views[0]
202
+
203
+ end
204
+
205
+ it 'emits the active_document_changed signal passing the new active document as argument' do
206
+ mk = flexmock{|m| m.should_receive(:test).with(@docs[0].object_id).once}
207
+ @world.connect(SIGNAL('active_document_changed(QObject*)')) do |doc|
208
+ mk.test doc.object_id
209
+ end
210
+ @env.activate_editor @views[0]
211
+ end
212
+
213
+ end
214
+
215
+ context 'if the editor associated with the new document is already active' do
216
+
217
+ before do
218
+ @env = @world.default_environment
219
+ @world.active_environment = @env
220
+ @docs = Array.new(2){@world.new_document}
221
+ @views = Array.new(2){@env.editor_for! @docs[0], :existing => :never}
222
+ @env.activate_editor @views[1]
223
+ end
224
+
225
+ it 'emits the active_editor_changed signal passing the new active editor as argument' do
226
+ mk = flexmock{|m| m.should_receive(:test).with(@views[0].object_id).once}
227
+ @world.connect(SIGNAL('active_editor_changed(QWidget*)')) do |view|
228
+ mk.test view.object_id
229
+ end
230
+ @env.activate_editor @views[0]
231
+ end
232
+
233
+ it 'does not emit the active_document_changed signal' do
234
+ mk = flexmock{|m| m.should_receive(:test).never}
235
+ @world.connect(SIGNAL('active_document_changed(QObject*)')) do |doc|
236
+ mk.test doc.object_id
237
+ end
238
+ @env.activate_editor @views[0]
239
+ end
240
+
241
+ end
242
+
243
+ context 'if there\'s no new active editor' do
244
+
245
+ before do
246
+ @env = @world.default_environment
247
+ @world.active_environment = @env
248
+ @docs = Array.new(2){@world.new_document}
249
+ @views = @docs.map{|doc| @env.editor_for! doc}
250
+ @env.activate_editor @views[1]
251
+ end
252
+
253
+ it 'sets the active document to nil' do
254
+ @env.activate_editor nil
255
+ @world.active_document.should be_nil
256
+ end
257
+
258
+ it 'emits the active_editor_changed signal passing nil as argument' do
259
+ mk = flexmock{|m| m.should_receive(:test).with(nil).once}
260
+ @world.connect(SIGNAL('active_editor_changed(QWidget*)')) do |view|
261
+ mk.test view
262
+ end
263
+ @env.activate_editor nil
264
+ end
265
+
266
+
267
+ it 'emits the the active_document_changed signal passing nil as argument' do
268
+ mk = flexmock{|m| m.should_receive(:test).with(nil)}
269
+ @world.connect(SIGNAL('active_document_changed(QObject*)')) do |doc|
270
+ mk.test doc
271
+ end
272
+ @env.activate_editor nil
273
+ end
274
+
275
+ end
276
+
277
+ end
278
+
279
+ describe '#project' do
280
+
281
+ context 'when called with a file name as argument' do
282
+
283
+ before do
284
+ @file = Tempfile.new ['project_factory_test', '.ruprj']
285
+ @file.write YAML.dump({:general => {:project_name => 'project_factory_test'}})
286
+ @file.flush
287
+ end
288
+
289
+ after do
290
+ path = @file.path
291
+ @file.close!
292
+ FileUtils.rm_f path
293
+ end
294
+
295
+ it 'returns a new project associated with the file if no other project is associated with it' do
296
+ prj = @world.project @file.path
297
+ prj.should be_a(Ruber::Project)
298
+ prj.project_file.should == @file.path
299
+ end
300
+
301
+ it 'returns an existing project associated with the same file, if that project exists' do
302
+ old = @world.project @file.path
303
+ new = @world.project @file.path
304
+ new.should == old
305
+ end
306
+
307
+ it 'doesn\'t return an existing project which has been closed' do
308
+ old = @world.project @file.path
309
+ old.close
310
+ new = @world.project @file.path
311
+ new.should_not == old
312
+ end
313
+
314
+ it 'emits the project_created signal passing the project as argument if a new project has been created' do
315
+ prj = Ruber::Project.new @file.path
316
+ flexmock(Ruber::Project).should_receive(:new).once.with(@file.path, nil).and_return prj
317
+ mk = flexmock{|m| m.should_receive(:test).once.with(prj)}
318
+ @world.connect(SIGNAL('project_created(QObject*)')){|pr| mk.test pr}
319
+ @world.project @file.path
320
+ end
321
+
322
+ it 'creates a new environment for the project if a new project has been created' do
323
+ prj = @world.project @file.path
324
+ @world.environments.find{|env| env.project == prj}.should_not be_nil
325
+ end
326
+
327
+ end
328
+
329
+ end
330
+
331
+ describe '#new_project' do
332
+
333
+ it 'returns a new project associated with the file if no other project is associated with it' do
334
+ file = File.join Dir.tmpdir, 'world_new_project_test.ruprj'
335
+ prj = @world.new_project file, 'world_new_project_test'
336
+ prj.should be_a(Ruber::Project)
337
+ prj.project_file.should == file
338
+ end
339
+
340
+ it 'returns the existing project associated with the file if there is such a project and the name of the project is equal to the second argument' do
341
+ file = File.join Dir.tmpdir, 'world_new_project_test.ruprj'
342
+ old = @world.new_project file, 'world_new_project_test'
343
+ prj = @world.new_project file, 'world_new_project_test'
344
+ prj.should == old
345
+ end
346
+
347
+ it 'adds the environment associated with the project to the environment list' do
348
+ file = File.join Dir.tmpdir, 'world_new_project_test.ruprj'
349
+ prj = @world.new_project file, 'world_new_project_test'
350
+ env = @world.environment prj
351
+ env.should be_a(Ruber::World::Environment)
352
+ env.project.should == prj
353
+ end
354
+
355
+ it 'emits the project_created_signal passing the project as argument' do
356
+ name = 'world_new_project_test'
357
+ file = File.join Dir.tmpdir, 'world_new_project_test.ruprj'
358
+ prj = Ruber::Project.new file, name
359
+ flexmock(Ruber::Project).should_receive(:new).once.with(file, name).and_return prj
360
+ mk = flexmock{|m| m.should_receive(:test).once.with(prj)}
361
+ @world.connect(SIGNAL('project_created(QObject*)')){|pr| mk.test pr}
362
+ @world.new_project file, name
363
+ end
364
+
365
+ it 'raises ExistingProjectFileError if the given project file already exists' do
366
+ file = File.join Dir.tmpdir, 'world_new_project_test.ruprj'
367
+ flexmock(File).should_receive(:exist?).with(file).and_return true
368
+ lambda{@world.new_project(file, "Test")}.should raise_error(Ruber::World::World::ExistingProjectFileError, "#{file} already exists")
369
+ end
370
+
371
+ end
372
+
373
+ describe 'when a project is being closed' do
374
+
375
+ it 'emits the closing_project signal passing the project as argument' do
376
+ file = File.join Dir.tmpdir, 'world_closing_project_test.ruprj'
377
+ prj = @world.new_project file, 'Test'
378
+ mk = flexmock{|m| m.should_receive(:test).once.with(prj.object_id)}
379
+ @world.connect(SIGNAL('closing_project(QObject*)')){|pr| mk.test pr.object_id}
380
+ prj.close(false)
381
+ end
382
+
383
+ it 'removes the project from the list of projects' do
384
+ file = File.join Dir.tmpdir, 'world_closing_project_test.ruprj'
385
+ prj = @world.new_project file, 'Test'
386
+ prj.close(false)
387
+ p @world.projects
388
+ end
389
+
390
+ end
391
+
392
+ describe '#environment' do
393
+
394
+ before do
395
+ @file = File.join Dir.tmpdir, 'world_environment_test.ruprj'
396
+ @prj = @world.new_project @file, 'Test'
397
+ end
398
+
399
+ after do
400
+ FileUtils.rm_f @file
401
+ end
402
+
403
+ context 'if an environment for the given project doesn\'t already exists' do
404
+
405
+ it 'returns nil' do
406
+ @world.environment('x').should be_nil
407
+ end
408
+
409
+ end
410
+
411
+ context 'if an environment for the given project already exists' do
412
+
413
+ it 'returns that environment' do
414
+ env = @world.environment @prj
415
+ new_env = @world.environment @prj
416
+ new_env.should equal(env)
417
+ end
418
+
419
+ it 'doesn\'t return an environment which has been closed' do
420
+ env = @world.environment @prj
421
+ env.close
422
+ new_env = @world.environment @prj
423
+ new_env.should_not == env
424
+ end
425
+
426
+ end
427
+
428
+ end
429
+
430
+ describe '#active_environment=' do
431
+
432
+ before do
433
+ @prjs = 2.times.map do |i|
434
+ file = File.join Dir.tmpdir, "world_current_environment_test_#{i}.ruprj"
435
+ @world.new_project file, "Test #{i}"
436
+ end
437
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
438
+ end
439
+
440
+ context 'if there is not an active environment' do
441
+
442
+ after do
443
+ @world.instance_variable_set :@active_environment, nil
444
+ end
445
+
446
+ context 'and the argument is an environment' do
447
+
448
+ it 'marks the given environment as active environment' do
449
+ @world.active_environment = @envs[1]
450
+ @world.active_environment.should == @envs[1]
451
+ end
452
+
453
+ it 'emits the active_environment_changed signal passing the new environment as argument' do
454
+ mk = flexmock{|m| m.should_receive(:active_environment_changed).once.with @envs[0]}
455
+ @world.connect(SIGNAL('active_environment_changed(QObject*)')){|e| mk.active_environment_changed e}
456
+ @world.active_environment = @envs[0]
457
+ end
458
+
459
+ it 'emits the active_environment_changed_2 signal passing the new environment and nil as arguments' do
460
+ mk = flexmock{|m| m.should_receive(:active_environment_changed).once.with @envs[0], nil}
461
+ @world.connect(SIGNAL('active_environment_changed_2(QObject*,QObject*)')){|e1, e2| mk.active_environment_changed e1, e2}
462
+ @world.active_environment = @envs[0]
463
+ end
464
+
465
+ it 'activates the given environment' do
466
+ flexmock(@envs[0]).should_receive(:activate).once
467
+ @world.active_environment = @envs[0]
468
+ end
469
+
470
+ end
471
+
472
+ end
473
+
474
+ context 'if there is an active environment' do
475
+
476
+ before do
477
+ @world.instance_variable_set :@active_environment, @envs[0]
478
+ end
479
+
480
+ after do
481
+ @world.instance_variable_set :@active_environment, @envs[0]
482
+ end
483
+
484
+ context 'and the argument is an environment' do
485
+
486
+ it 'deactivates the old active environment' do
487
+ flexmock(@envs[0]).should_receive(:deactivate).once
488
+ @world.active_environment = @envs[1]
489
+ end
490
+
491
+ it 'marks the given environment as active environment' do
492
+ @world.active_environment = @envs[1]
493
+ @world.active_environment.should == @envs[1]
494
+ end
495
+
496
+ it 'emits the active_environment_changed signal passing the new environment as argument' do
497
+ mk = flexmock{|m| m.should_receive(:active_environment_changed).once.with @envs[1]}
498
+ @world.connect(SIGNAL('active_environment_changed(QObject*)')){|e| mk.active_environment_changed e}
499
+ @world.active_environment = @envs[1]
500
+ end
501
+
502
+ it 'emits the active_environment_changed_2 signal passing the new environment and the old environment as arguments' do
503
+ mk = flexmock{|m| m.should_receive(:active_environment_changed).once.with @envs[1], @envs[0]}
504
+ @world.connect(SIGNAL('active_environment_changed_2(QObject*,QObject*)')){|e1, e2| mk.active_environment_changed e1, e2}
505
+ @world.active_environment = @envs[1]
506
+ end
507
+
508
+ it 'activates the given environment' do
509
+ flexmock(@envs[1]).should_receive(:activate).once
510
+ @world.active_environment = @envs[1]
511
+ end
512
+
513
+ end
514
+
515
+ context 'and the argument is an nil' do
516
+
517
+ it 'deactivates the old active environment' do
518
+ flexmock(@envs[0]).should_receive(:deactivate).once
519
+ @world.active_environment = nil
520
+ end
521
+
522
+ it 'sets the active environment to nil' do
523
+ @world.active_environment = nil
524
+ @world.active_environment.should be_nil
525
+ end
526
+
527
+ it 'emits the active_environment_changed signal passing nil as argument' do
528
+ mk = flexmock{|m| m.should_receive(:active_environment_changed).once.with nil}
529
+ @world.connect(SIGNAL('active_environment_changed(QObject*)')){|e| mk.active_environment_changed e}
530
+ @world.active_environment = nil
531
+ end
532
+
533
+ it 'emits the active_environment_changed_2 signal passing the nil and the old active environment as arguments' do
534
+ mk = flexmock{|m| m.should_receive(:active_environment_changed).once.with nil, @envs[0]}
535
+ @world.connect(SIGNAL('active_environment_changed_2(QObject*,QObject*)')){|e1, e2| mk.active_environment_changed e1, e2}
536
+ @world.active_environment = nil
537
+ end
538
+
539
+ it 'doesn\'t attempt to activate the new environment' do
540
+ lambda{@world.active_environment = nil}.should_not raise_error
541
+ end
542
+
543
+ end
544
+
545
+ it 'does nothing if the argument is the same as the active environment' do
546
+ @world.active_environment = nil
547
+ mk=flexmock{|m| m.should_receive(:test).never}
548
+ @world.connect(SIGNAL('active_environment_changed(QObject*)')){|e| mk.test e}
549
+ @world.active_environment = nil
550
+ @world.instance_variable_set :@active_environment, @envs[1]
551
+ @world.active_environment = @envs[1]
552
+ end
553
+
554
+ end
555
+
556
+ end
557
+
558
+ context 'when an environment is being closed' do
559
+
560
+ after do
561
+ FileUtils.rm_r File.join( Dir.tmpdir, "world_environment_closing_test.ruprj")
562
+ end
563
+
564
+ it 'sets the active environment to nil if the environment being closed is the active one' do
565
+ file = File.join Dir.tmpdir, "world_environment_closing_test.ruprj"
566
+ prj = @world.new_project file, "Test"
567
+ env = @world.environment prj
568
+ @world.active_environment = env
569
+ env.close
570
+ @world.active_environment.should be_nil
571
+ end
572
+
573
+ it 'does\'t change the active environment if the active project is not the one being closed' do
574
+ file = File.join Dir.tmpdir, "world_environment_closing_test.ruprj"
575
+ prj = @world.new_project file, "Test"
576
+ env = @world.environment prj
577
+ @world.active_environment = @world.default_environment
578
+ env.close
579
+ @world.active_environment.should == @world.default_environment
580
+ end
581
+
582
+ end
583
+
584
+ describe '#active_project=' do
585
+
586
+ before do
587
+ @prjs = 2.times.map do |i|
588
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
589
+ @world.new_project file, "Test #{i}"
590
+ end
591
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
592
+ end
593
+
594
+ context 'if there is not an active project' do
595
+
596
+ after do
597
+ @world.instance_variable_set :@active_environment, nil
598
+ end
599
+
600
+ context 'and the argument is a project' do
601
+
602
+ it 'calls the #active_environment= method with the environment associated with the project as argument' do
603
+ flexmock(@world).should_receive(:active_environment=).with(@envs[1]).once
604
+ @world.active_project = @prjs[1]
605
+ end
606
+
607
+ it 'emits the active_project_changed signal passing the new active project as argument' do
608
+ mk = flexmock{|m| m.should_receive(:active_project_changed).once.with @prjs[0]}
609
+ @world.connect(SIGNAL('active_project_changed(QObject*)')){|prj| mk.active_project_changed prj}
610
+ @world.active_project = @prjs[0]
611
+ end
612
+
613
+ it 'emits the active_project_changed_2 signal passing the new project and nil as arguments' do
614
+ mk = flexmock{|m| m.should_receive(:active_project_changed).once.with @prjs[0], nil}
615
+ @world.connect(SIGNAL('active_project_changed_2(QObject*,QObject*)')){|p1, p2| mk.active_project_changed p1, p2}
616
+ @world.active_project = @prjs[0]
617
+ end
618
+
619
+ it 'activates the given project' do
620
+ flexmock(@prjs[0]).should_receive(:activate).once
621
+ @world.active_project = @prjs[0]
622
+ end
623
+
624
+ end
625
+
626
+ end
627
+
628
+ context 'if there is an active project' do
629
+
630
+ before do
631
+ @world.instance_variable_set :@active_environment, @envs[0]
632
+ end
633
+
634
+ after do
635
+ @world.instance_variable_set :@active_environment, @envs[0]
636
+ end
637
+
638
+ context 'and the argument is a project' do
639
+
640
+ it 'calls the active_environment= method with the environment associated with the project' do
641
+ flexmock(@world).should_receive(:active_environment=).once.with @envs[1]
642
+ @world.active_project = @prjs[1]
643
+ end
644
+
645
+ it 'deactivates the old active projecy' do
646
+ flexmock(@prjs[0]).should_receive(:deactivate).once
647
+ @world.active_project = @prjs[1]
648
+ end
649
+
650
+ it 'emits the active_project_changed signal passing the new environment as argument' do
651
+ mk = flexmock{|m| m.should_receive(:active_project_changed).once.with @prjs[1]}
652
+ @world.connect(SIGNAL('active_project_changed(QObject*)')){|e| mk.active_project_changed e}
653
+ @world.active_project = @prjs[1]
654
+ end
655
+
656
+ it 'emits the active_project_changed_2 signal passing the new environment and the old environment as arguments' do
657
+ mk = flexmock{|m| m.should_receive(:active_project_changed).once.with @prjs[1], @prjs[0]}
658
+ @world.connect(SIGNAL('active_project_changed_2(QObject*,QObject*)')){|e1, e2| mk.active_project_changed e1, e2}
659
+ @world.active_project = @prjs[1]
660
+ end
661
+
662
+ it 'activates the given project' do
663
+ flexmock(@prjs[1]).should_receive(:activate).once
664
+ @world.active_project = @prjs[1]
665
+ end
666
+
667
+ end
668
+
669
+ context 'and the argument is an nil' do
670
+
671
+ it 'calls the active_environment= method with nil' do
672
+ flexmock(@world).should_receive(:active_environment=).once.with @world.default_environment
673
+ @world.active_project = nil
674
+ end
675
+
676
+ it 'deactivates the old active environment' do
677
+ flexmock(@prjs[0]).should_receive(:deactivate).once
678
+ @world.active_project = nil
679
+ end
680
+
681
+ it 'emits the active_project_changed signal passing nil as argument' do
682
+ mk = flexmock{|m| m.should_receive(:active_project_changed).once.with nil}
683
+ @world.connect(SIGNAL('active_project_changed(QObject*)')){|e| mk.active_project_changed e}
684
+ @world.active_project = nil
685
+ end
686
+
687
+ it 'emits the active_project_changed_2 signal passing the nil and the old active environment as arguments' do
688
+ mk = flexmock{|m| m.should_receive(:active_project_changed).once.with nil, @prjs[0]}
689
+ @world.connect(SIGNAL('active_project_changed_2(QObject*,QObject*)')){|e1, e2| mk.active_project_changed e1, e2}
690
+ @world.active_project = nil
691
+ end
692
+
693
+ it 'doesn\'t attempt to activate the new project' do
694
+ lambda{@world.active_project = nil}.should_not raise_error
695
+ end
696
+
697
+ end
698
+
699
+ it 'does nothing if the argument is the same as the active project' do
700
+ @world.active_project = nil
701
+ mk=flexmock{|m| m.should_receive(:test).never}
702
+ @world.connect(SIGNAL('active_project_changed(QObject*)')){|e| mk.test e}
703
+ @world.active_project = nil
704
+ @world.instance_variable_set :@active_environment, @envs[1]
705
+ @world.active_project = @prjs[1]
706
+ end
707
+
708
+ end
709
+
710
+ end
711
+
712
+ describe '#active_project' do
713
+
714
+ before do
715
+ @prjs = 2.times.map do |i|
716
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
717
+ @world.new_project file, "Test #{i}"
718
+ end
719
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
720
+ end
721
+
722
+ it 'returns the project associated with the active environment if it exists' do
723
+ @world.active_environment = @envs[1]
724
+ @world.active_project.should == @prjs[1]
725
+ @world.active_environment = @world.default_environment
726
+ @world.active_project.should be_nil
727
+ end
728
+
729
+ it 'returns nil if there\'s no active project' do
730
+ @world.active_project.should be_nil
731
+ end
732
+
733
+ end
734
+
735
+ describe '#active_document' do
736
+
737
+ before do
738
+ @prjs = 2.times.map do |i|
739
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
740
+ @world.new_project file, "Test #{i}"
741
+ end
742
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
743
+ end
744
+
745
+ it 'returns the document associated with the active editor' do
746
+ @world.active_environment = @envs[1]
747
+ doc = @world.new_document
748
+ ed = @envs[1].editor_for! doc
749
+ @envs[1].activate_editor ed
750
+ @world.active_document.should == doc
751
+ end
752
+
753
+ it 'returns nil if there\'s no active document' do
754
+ @world.active_document.should be_nil
755
+ end
756
+
757
+ end
758
+
759
+ describe '#environments' do
760
+
761
+ it 'returns an array containing all the environments, including the default one' do
762
+ prjs = 2.times.map do |i|
763
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
764
+ @world.new_project file, "Test #{i}"
765
+ end
766
+ envs = 2.times.map{|i| @world.environment prjs[i]}
767
+ @world.environments.should == [@world.default_environment] + envs
768
+ end
769
+
770
+ end
771
+
772
+ describe '#each_environment' do
773
+
774
+ before do
775
+ @prjs = 2.times.map do |i|
776
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
777
+ @world.new_project file, "Test #{i}"
778
+ end
779
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
780
+ end
781
+
782
+ context 'if called with a block' do
783
+
784
+ it 'calls the block once for each environment, passing the environment as argument' do
785
+ mk = flexmock do |m|
786
+ m.should_receive(:test).with(@world.default_environment).once
787
+ m.should_receive(:test).with(@envs[0]).once
788
+ m.should_receive(:test).with(@envs[1]).once
789
+ end
790
+ @world.each_environment{|e| mk.test e}
791
+ end
792
+
793
+ it 'returns self' do
794
+ @world.each_environment{}.should == @world
795
+ end
796
+
797
+ end
798
+
799
+ context 'if called without a block' do
800
+
801
+ it 'returns an enumerator which iterates on all the environments' do
802
+ mk = flexmock do |m|
803
+ m.should_receive(:test).with(@world.default_environment).once
804
+ m.should_receive(:test).with(@envs[0]).once
805
+ m.should_receive(:test).with(@envs[1]).once
806
+ end
807
+ enum = @world.each_environment
808
+ enum.should be_an(Enumerator)
809
+ enum.each{|e| mk.test e}
810
+ end
811
+
812
+ end
813
+
814
+ end
815
+
816
+ describe '#projects' do
817
+
818
+ before do
819
+ @prjs = 2.times.map do |i|
820
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
821
+ @world.new_project file, "Test #{i}"
822
+ end
823
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
824
+ end
825
+
826
+ it 'returns a ProjectList containing all the projects' do
827
+ list = @world.projects
828
+ list.should be_a(Ruber::World::ProjectList)
829
+ list.should == @prjs
830
+ end
831
+
832
+ end
833
+
834
+ describe '#each_project' do
835
+ before do
836
+ @prjs = 2.times.map do |i|
837
+ file = File.join Dir.tmpdir, "world_current_project_test_#{i}.ruprj"
838
+ @world.new_project file, "Test #{i}"
839
+ end
840
+ @envs = 2.times.map{|i| @world.environment @prjs[i]}
841
+ end
842
+
843
+ context 'if called with a block' do
844
+
845
+ it 'calls the block once for each project, passing the project as argument' do
846
+ mk = flexmock do |m|
847
+ m.should_receive(:test).with(@prjs[0]).once
848
+ m.should_receive(:test).with(@prjs[1]).once
849
+ end
850
+ @world.each_project{|prj| mk.test prj}
851
+ end
852
+
853
+ it 'returns self' do
854
+ @world.each_project{}.should == @world
855
+ end
856
+
857
+ end
858
+
859
+ context 'if called without a block' do
860
+
861
+ it 'returns an enumerator which iterates on all the projects' do
862
+ mk = flexmock do |m|
863
+ m.should_receive(:test).with(@prjs[0]).once
864
+ m.should_receive(:test).with(@prjs[1]).once
865
+ end
866
+ enum = @world.each_project
867
+ enum.should be_an(Enumerator)
868
+ enum.each{|e| mk.test e}
869
+ end
870
+
871
+ end
872
+
873
+ end
874
+
875
+ describe '#documents' do
876
+
877
+ before do
878
+ @docs = 8.times.map{@world.new_document}
879
+ end
880
+
881
+ it 'returns a DocumentList containing all the open documents' do
882
+ res = @world.documents
883
+ res.should be_instance_of(Ruber::World::DocumentList)
884
+ res.should == @docs
885
+ end
886
+
887
+ it 'doesn\'t include documents which have been closed in the list' do
888
+ @docs[1].close
889
+ @world.documents.should == [@docs[0]] + @docs[2..-1]
890
+ end
891
+
892
+ end
893
+
894
+ describe '#each_document' do
895
+
896
+ before do
897
+ @docs = 8.times.map{@world.new_document}
898
+ end
899
+
900
+ context 'if called with a block' do
901
+
902
+ it 'calls the block once for each document, passing the document as argument' do
903
+ mk = flexmock do |m|
904
+ @docs.each{|d| m.should_receive(:test).once.with d}
905
+ end
906
+ @world.each_document{|doc| mk.test doc}
907
+ end
908
+
909
+ it 'returns self' do
910
+ @world.each_document{}.should == @world
911
+ end
912
+
913
+ end
914
+
915
+ context 'if called without a block' do
916
+
917
+ it 'returns an enumerator which iterates on all the documents' do
918
+ mk = flexmock do |m|
919
+ @docs.each{|d| m.should_receive(:test).once.with d}
920
+ end
921
+ enum = @world.each_document
922
+ enum.should be_an(Enumerator)
923
+ enum.each{|doc| mk.test doc}
924
+ end
925
+
926
+ end
927
+
928
+ end
929
+
930
+ describe '#load_settings' do
931
+
932
+ it 'makes the tabs in the environments\' tab widgets closeable or not according to the workspace/close_buttons setting' do
933
+ file = File.join Dir.tmpdir, 'world_load_settings_test.ruprj'
934
+ prj = @world.new_project file, 'TEST'
935
+ flexmock(Ruber[:config]).should_receive(:[]).with(:workspace, :close_buttons).once.and_return true
936
+ @world.send(:load_settings)
937
+ @world.environments.each{|e| e.tab_widget.tabs_closable.should be_true}
938
+ flexmock(Ruber[:config]).should_receive(:[]).with(:workspace, :close_buttons).once.and_return false
939
+ @world.send(:load_settings)
940
+ @world.environments.each{|e| e.tab_widget.tabs_closable.should be_false}
941
+ end
942
+
943
+ end
944
+
945
+ describe '#save_settings' do
946
+
947
+ after do
948
+ Ruber[:world].projects.dup.each{|prj| prj.close false}
949
+ end
950
+
951
+ it 'calls the #save_settings method of each document' do
952
+ docs = Array.new(5){@world.new_document}
953
+ docs.each{|doc| flexmock(doc).should_receive(:save_settings).once}
954
+ @world.save_settings
955
+ end
956
+
957
+ it 'calls the #save method of each project' do
958
+ files = Array.new(5)do
959
+ file = Tempfile.new ['', '.ruprj']
960
+ file.write YAML.dump(:general => {:project_name => random_string(10)})
961
+ file.flush
962
+ file
963
+ end
964
+ projects = files.map do |f|
965
+ prj = Ruber[:world].project f.path
966
+ flexmock(prj).should_receive(:save).once
967
+ prj
968
+ end
969
+ @world.save_settings
970
+ end
971
+
972
+ end
973
+
974
+ describe '#query_close' do
975
+
976
+ before do
977
+ @docs = Array.new(5){@world.new_document}
978
+ @docs.each{|doc| flexmock(doc.own_project).should_receive(:query_close).by_default.and_return(true)}
979
+ flexmock(Ruber[:main_window]).should_receive(:save_documents).and_return(true).by_default
980
+ files = Array.new(5)do
981
+ file = Tempfile.new ['', '.ruprj']
982
+ file.write YAML.dump(:general => {:project_name => random_string(10)})
983
+ file.flush
984
+ file
985
+ end
986
+ @projects = files.map do |f|
987
+ prj = Ruber[:world].project f.path
988
+ flexmock(prj).should_receive(:query_close).by_default.and_return(:true)
989
+ prj
990
+ end
991
+ end
992
+
993
+ after do
994
+ #needed to avoid callinf main_window#save settings when closing projects
995
+ flexmock(Ruber[:main_window]).should_receive(:save_documents).and_return true
996
+ Ruber[:world].projects.dup.each{|prj| prj.close false}
997
+ end
998
+
999
+ it 'calls the query_close method of the project associated with each document' do
1000
+ @docs.each do |doc|
1001
+ flexmock(doc.own_project).should_receive(:query_close).once.and_return true
1002
+ end
1003
+ @world.query_close
1004
+ end
1005
+
1006
+ it 'returns false if the query_close method of a project associated with a document returns false' do
1007
+ @docs.each_with_index do |doc, i|
1008
+ res = (i !=3)
1009
+ flexmock(doc.own_project).should_receive(:query_close).and_return res
1010
+ end
1011
+ @world.query_close.should == false
1012
+ end
1013
+
1014
+ it 'calls the save_documents method of the main window' do
1015
+ flexmock(Ruber[:main_window]).should_receive(:save_documents).once.with(@docs).and_return false
1016
+ @world.query_close
1017
+ end
1018
+
1019
+ it 'returns false if the main window\'s save_documents method returns false' do
1020
+ flexmock(Ruber[:main_window]).should_receive(:save_documents).once.with(@docs).and_return false
1021
+ @world.query_close.should == false
1022
+ end
1023
+
1024
+ it 'calls the query_close method of each project' do
1025
+ @projects.each do |prj|
1026
+ flexmock(prj).should_receive(:query_close).once.and_return true
1027
+ end
1028
+ @world.query_close
1029
+ end
1030
+
1031
+ it 'returns false if the query_close method of a project returns false' do
1032
+ @projects.each_with_index do |prj, i|
1033
+ res = (i !=3)
1034
+ flexmock(prj).should_receive(:query_close).and_return res
1035
+ end
1036
+ @world.query_close.should == false
1037
+ end
1038
+
1039
+ it 'returns true if the documents\' and projects\' query_close method and the main window\'s save_documents methods all return true' do
1040
+ @world.query_close.should == true
1041
+ end
1042
+
1043
+ end
1044
+
1045
+ describe '#close_all' do
1046
+
1047
+ before do
1048
+ @projects = Array.new(3) do |i|
1049
+ @world.new_project File.join(Dir.tmpdir, "#{random_string}.ruprj"), "Test #{i}"
1050
+ end
1051
+ @docs = Array.new(5){@world.new_document}
1052
+ end
1053
+
1054
+ context 'when called the first argument is :all' do
1055
+
1056
+ context 'if the second argument is :save' do
1057
+
1058
+ before do
1059
+ @projects.each{|prj| flexmock(prj).should_receive(:close).by_default}
1060
+ @docs.each do |doc|
1061
+ flexmock(doc).should_receive(:close).by_default
1062
+ end
1063
+ end
1064
+
1065
+ it 'calls the close method of each project passing true as argument' do
1066
+ @projects.each do |prj|
1067
+ flexmock(prj).should_receive(:close).with(true).once
1068
+ end
1069
+ @world.close_all :all, :save
1070
+ end
1071
+
1072
+ it 'calls the close method of each document passing true as argument' do
1073
+ @docs.each do |doc|
1074
+ flexmock(doc).should_receive(:close).with(true).once
1075
+ end
1076
+ @world.close_all :all, :save
1077
+ end
1078
+
1079
+ end
1080
+
1081
+ context 'if the second argument is :discard' do
1082
+
1083
+ before do
1084
+ @projects.each{|prj| flexmock(prj).should_receive(:close).by_default}
1085
+ @docs.each do |doc|
1086
+ flexmock(doc).should_receive(:close).by_default
1087
+ end
1088
+ end
1089
+
1090
+ it 'calls the close method of each project passing false as argument' do
1091
+ @projects.each do |prj|
1092
+ flexmock(prj).should_receive(:close).with(false).once
1093
+ end
1094
+ @world.close_all :all, :discard
1095
+ end
1096
+
1097
+ it 'calls the close method of each document passing false as argument' do
1098
+ @docs.each do |doc|
1099
+ flexmock(doc).should_receive(:close).with(false).once
1100
+ end
1101
+ @world.close_all :all, :discard
1102
+ end
1103
+
1104
+ end
1105
+
1106
+ end
1107
+
1108
+ context 'when called the first argument is :projects' do
1109
+
1110
+ context 'if the second argument is :save' do
1111
+
1112
+ before do
1113
+ @projects.each{|prj| flexmock(prj).should_receive(:close).by_default}
1114
+ @docs.each do |doc|
1115
+ flexmock(doc).should_receive(:close).by_default
1116
+ end
1117
+ end
1118
+
1119
+ it 'calls the close method of each project passing true as argument' do
1120
+ @projects.each do |prj|
1121
+ flexmock(prj).should_receive(:close).with(true).once
1122
+ end
1123
+ @world.close_all :projects, :save
1124
+ end
1125
+
1126
+ it 'doesn\'t close the documents' do
1127
+ @docs.each do |doc|
1128
+ flexmock(doc).should_receive(:close).never
1129
+ end
1130
+ @world.close_all :projects, :save
1131
+ end
1132
+
1133
+ end
1134
+
1135
+ context 'if the second argument is :discard' do
1136
+
1137
+ before do
1138
+ @projects.each{|prj| flexmock(prj).should_receive(:close).by_default}
1139
+ @docs.each do |doc|
1140
+ flexmock(doc).should_receive(:close).by_default
1141
+ end
1142
+ end
1143
+
1144
+ it 'calls the close method of each project passing false as argument' do
1145
+ @projects.each do |prj|
1146
+ flexmock(prj).should_receive(:close).with(false).once
1147
+ end
1148
+ @world.close_all :projects, :discard
1149
+ end
1150
+
1151
+ it 'doesn\'t close the documents' do
1152
+ @docs.each do |doc|
1153
+ flexmock(doc).should_receive(:close).never
1154
+ end
1155
+ @world.close_all :projects, :discard
1156
+ end
1157
+
1158
+ end
1159
+
1160
+ end
1161
+
1162
+ context 'when called the first argument is :documents' do
1163
+
1164
+ context 'if the second argument is :save' do
1165
+
1166
+ before do
1167
+ @projects.each{|prj| flexmock(prj).should_receive(:close).by_default}
1168
+ @docs.each do |doc|
1169
+ flexmock(doc).should_receive(:close).by_default
1170
+ end
1171
+ end
1172
+
1173
+ it 'doesn\'t close projects' do
1174
+ @projects.each do |prj|
1175
+ flexmock(prj).should_receive(:close).never
1176
+ end
1177
+ @world.close_all :documents, :save
1178
+ end
1179
+
1180
+ it 'calls the close method of each document passing true as argument' do
1181
+ @docs.each do |doc|
1182
+ flexmock(doc).should_receive(:close).with(true).once
1183
+ end
1184
+ @world.close_all :documents, :save
1185
+ end
1186
+
1187
+ end
1188
+
1189
+ context 'if the second argument is :discard' do
1190
+
1191
+ before do
1192
+ @projects.each{|prj| flexmock(prj).should_receive(:close).by_default}
1193
+ @docs.each do |doc|
1194
+ flexmock(doc).should_receive(:close).by_default
1195
+ end
1196
+ end
1197
+
1198
+ it 'doesn\'t close the projects' do
1199
+ @projects.each do |prj|
1200
+ flexmock(prj).should_receive(:close).never
1201
+ end
1202
+ @world.close_all :documents, :discard
1203
+ end
1204
+
1205
+ it 'calls the close method of each document passing false as argument' do
1206
+ @docs.each do |doc|
1207
+ flexmock(doc).should_receive(:close).with(false).once
1208
+ end
1209
+ @world.close_all :documents, :discard
1210
+ end
1211
+
1212
+ end
1213
+
1214
+ end
1215
+
1216
+
1217
+ end
1218
+
1219
+ end