ruber 0.0.8 → 0.0.9

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 (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