ruber 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,401 @@
1
+ require 'spec/common'
2
+
3
+ require 'tempfile'
4
+ require 'fileutils'
5
+ require 'flexmock'
6
+ require 'forwardable'
7
+
8
+ require 'ruber/projects/project_files_list'
9
+ require 'ruber/project'
10
+
11
+
12
+ class SimpleProject < Qt::Object
13
+ signals 'option_changed(QString, QString)'
14
+ end
15
+
16
+ describe 'Ruber::ProjectFilesList' do
17
+
18
+ before do
19
+ @app = Qt::Object.new
20
+ @comp = Qt::Object.new do
21
+ class << self
22
+ extend Forwardable
23
+ def_delegators :@data, :[], :<<
24
+ def_delegator :@data, :each, :each_component
25
+ end
26
+ @data = []
27
+ end
28
+ @projects = Qt::Object.new
29
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(@app).by_default
30
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(@comp).by_default
31
+ flexmock(Ruber).should_receive(:[]).with(:projects).and_return(@projects).by_default
32
+ dir = File.dirname __FILE__
33
+ @prj = Ruber::Project.new File.join(dir, 'test.ruprj'), 'Test'
34
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => [], :exclude => [], :extensions => []} }))
35
+ @l = Ruber::ProjectFilesList.new @prj
36
+ @prj.add_extension :file_lister, @l
37
+ end
38
+
39
+ it 'should be an Enumerable' do
40
+ Ruber::ProjectFilesList.ancestors.should include(Enumerable)
41
+ end
42
+
43
+ it 'should not be up to date when created' do
44
+ @l.should_not be_up_to_date
45
+ end
46
+
47
+ it 'should not attempt to scan the project when created' do
48
+ flexmock(Find).should_receive(:find).never
49
+ l = Ruber::ProjectFilesList.new @prj
50
+ end
51
+
52
+ it 'should mark the list as not up to date when the project_files option changes' do
53
+ @prj.add_option(OS.new({:group => :general, :name => :xyz, :default => 3}))
54
+ @prj[:general, :project_files][:extensions] = ['*.rb']
55
+ @l.instance_variable_set :@up_to_date, true
56
+ @prj.instance_eval{emit option_changed('general', 'xyz')}
57
+ @prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => %w[*.rb *.ui]}
58
+ @l.should_not be_up_to_date
59
+ end
60
+
61
+ describe ', when a file or directory changes' do
62
+
63
+ before do
64
+ @files = YAML.load('[f1.rb, f1.yaml, README, COPYING, [d2, f21.rb, f22.rb, f21.yaml, f22.yaml, CHANGELOG], [d3, f31.rb, f32.rb]]')
65
+ @dir = make_dir_tree @files
66
+ @prj = Ruber::Project.new File.join(@dir, 'test.ruprj'), 'Test'
67
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => [], :exclude => [], :extensions => []} }))
68
+ @list = Ruber::ProjectFilesList.new @prj
69
+ @prj.add_extension :file_lister, @list
70
+ end
71
+
72
+ it 'should mark itself as not up to date' do
73
+ @list.instance_variable_set :@up_to_date, true
74
+ w = @list.instance_variable_get :@watcher
75
+ dir = @prj.project_directory
76
+ w.instance_eval{emit dirty(dir)}
77
+ @list.instance_variable_get(:@up_to_date).should be_false
78
+ end
79
+
80
+ it 'should stop the watcher' do
81
+ w = @list.instance_variable_get :@watcher
82
+ flexmock(w).should_receive(:stop_scan).once
83
+ dir = @prj.project_directory
84
+ w.instance_eval{emit dirty(dir)}
85
+ end
86
+
87
+ end
88
+
89
+ describe Ruber::ProjectFilesList, '#refresh' do
90
+
91
+ before do
92
+ dir = File.dirname __FILE__
93
+ @prj = Ruber::Project.new File.join(dir, 'test.ruprj'), 'Test'
94
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => [], :exclude => [], :extensions => []} }))
95
+ @list = Ruber::ProjectFilesList.new @prj
96
+ @prj.add_extension :file_lister, @list
97
+ end
98
+
99
+ it 'should call the scan_project method' do
100
+ flexmock(@list).should_receive(:scan_project).once
101
+ @list.refresh
102
+ end
103
+
104
+ it 'should set the file list as up to date' do
105
+ flexmock(@list).should_receive(:scan_project)
106
+ @list.refresh
107
+ @list.should be_up_to_date
108
+ end
109
+
110
+ it 'should restart the watcher' do
111
+ flexmock(@list).should_receive(:scan_project)
112
+ w = @list.instance_variable_get(:@watcher)
113
+ flexmock(w).should_receive(:start_scan).once
114
+ @list.refresh
115
+ end
116
+
117
+ end
118
+
119
+ describe 'Ruber::ProjectFilesList#project_files' do
120
+
121
+ before do
122
+ @files = YAML.load('[f1.rb, f1.yaml, README, COPYING, [d2, f21.rb, f22.rb, f21.yaml, f22.yaml, CHANGELOG], [d3, f31.rb, f32.rb]]')
123
+ @dir = make_dir_tree @files
124
+ @prj = Ruber::Project.new File.join(@dir, 'test.ruprj'), 'Test'
125
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => [], :exclude => [], :extensions => []} }))
126
+ @list = Ruber::ProjectFilesList.new @prj
127
+ @prj.add_extension :file_lister, @list
128
+ end
129
+
130
+ after do
131
+ FileUtils.rm_f @dir
132
+ end
133
+
134
+ it 'should update the cache if it\'s not up to date' do
135
+ @list.instance_variable_set :@up_to_date, false
136
+ flexmock(@list).should_receive(:refresh).once
137
+ @list.project_files
138
+ end
139
+
140
+ it 'should not update the cache if it\'s already up to date' do
141
+ @list.instance_variable_set :@up_to_date, true
142
+ flexmock(@list).should_receive(:refresh).never
143
+ @list.project_files
144
+ end
145
+
146
+ it 'should return an array containing all the files corresponding to include rules of type path unless they also correspond to an exclude rule of type path' do
147
+ @prj[:general, :project_files] = {:include => ['README', 'COPYING', 'f1.rb', 'd2/CHANGELOG', 'd2/f21.rb'], :exclude => ['COPYING', 'd2/f21.rb'], :extensions => []}
148
+ @list.project_files(false).should =~ %w[README f1.rb d2/CHANGELOG]
149
+ end
150
+
151
+ it 'should not include in the returned array files which don\'t exist' do
152
+ @prj[:general, :project_files] = {:include => ['README1', 'COPYING', 'f1.rb', 'd2/CHANGELOG', 'd2/f211.rb'], :exclude => ['COPYING'], :extensions => []}
153
+ @list.project_files(false).should =~ %w[f1.rb d2/CHANGELOG]
154
+ end
155
+
156
+ it 'should skip include rules of type path corresponding to directories' do
157
+ @prj[:general, :project_files] = {:include => ['README', 'COPYING', 'f1.rb', 'd2/CHANGELOG', 'd2/f21.rb', 'd3'], :exclude => ['COPYING', 'd2/f21.rb'], :extensions => []}
158
+ @list.project_files(false).should =~ %w[README f1.rb d2/CHANGELOG]
159
+ end
160
+
161
+ it 'should include all the files in the project directory which correspond to one of the extensions in the returned array, unless they match one of the exclude rule' do
162
+ @prj[:general, :project_files] = {:include => [], :exclude => ['COPYING', 'd2/f21.rb'], :extensions => %w[*.rb]}
163
+ @list.project_files(false).should =~ %w[f1.rb d2/f22.rb d3/f31.rb d3/f32.rb]
164
+ end
165
+
166
+ it 'should include all the files in the project directory which match one of the include rules of type regexp and don\'t match any exclude rule' do
167
+ @prj[:general, :project_files] = {:include => [%r{d3/.*}, %r{.*\.yaml}], :exclude => [%r{d3/.*2.*}, %r{.*1.*\.rb}], :extensions => []}
168
+ @list.project_files(false).should =~ %w[d2/f22.yaml f1.yaml d2/f21.yaml]
169
+ end
170
+
171
+ it 'should not include duplicate elements' do
172
+ @prj[:general, :project_files] = {:include => [%r{d2/.*}, 'f1.rb'], :exclude => [], :extensions => ['*.rb']}
173
+ @list.project_files(false).should =~ %w[f1.rb d2/f21.rb d2/f22.rb d2/f21.yaml d2/f22.yaml d2/CHANGELOG d3/f31.rb d3/f32.rb]
174
+ end
175
+
176
+ it 'should return a deep copy of the cache object' do
177
+ @prj[:general, :project_files] = {:include => [%r{d2/.*}, 'f1.rb'], :exclude => [], :extensions => ['*.rb']}
178
+ old_cache = @list.instance_variable_get(:@project_files).deep_copy
179
+ res = @list.project_files(false)
180
+ res.should == old_cache
181
+ res << 'x'
182
+ @list.instance_variable_get(:@project_files).should == old_cache
183
+ end
184
+
185
+ it 'should return full paths if the argument is true' do
186
+ @prj[:general, :project_files] = {:include => [%r{d2/.*}, 'f1.rb'], :exclude => [], :extensions => ['*.rb']}
187
+ @list.project_files(true).should =~ %w[f1.rb d2/f21.rb d2/f22.rb d2/f21.yaml d2/f22.yaml d2/CHANGELOG d3/f31.rb d3/f32.rb].map{|i| File.join @dir, i}
188
+ end
189
+
190
+ it 'should return the correct list if a file or directory is added or deleted after the file watcher has been created' do
191
+ @prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => ['*.rb']}
192
+ # Experiments show that KDE::DirWatch needs an event loop to work. Since we don't have one running, we'll have to make it emit the 'dirty' signal manually
193
+ watcher = @list.instance_variable_get(:@watcher)
194
+ `touch #@dir/f2.rb`
195
+ watcher.instance_eval{emit dirty( @dir)}
196
+ `touch #@dir/d2/f23.rb`
197
+ watcher.instance_eval{emit dirty( @dir)}
198
+ @list.project_files(false).should include('f2.rb')
199
+ @list.project_files(false).should include('d2/f23.rb')
200
+ FileUtils.mkdir("#@dir/d4")
201
+ watcher.instance_eval{emit dirty( @dir)}
202
+ `touch #@dir/d4/f41.rb`
203
+ watcher.instance_eval{emit dirty( @dir)}
204
+ `touch #@dir/d4/f42.rb`
205
+ watcher.instance_eval{emit dirty( @dir)}
206
+ @list.project_files(false).should include('d4/f41.rb')
207
+ @list.project_files(false).should include('d4/f42.rb')
208
+ FileUtils.rm_rf "#@dir/d2"
209
+ watcher.instance_eval{emit dirty( @dir)}
210
+ @list.project_files(false).should_not include("#@dir/d2/f21.rb")
211
+ @list.project_files(false).should_not include("#@dir/d2/f22.rb")
212
+ FileUtils.rm "#@dir/f1.rb"
213
+ watcher.instance_eval{emit dirty( @dir)}
214
+ @list.project_files(false).should_not include("f1.rb")
215
+ end
216
+
217
+ end
218
+
219
+ describe 'Ruber::ProjectFilesList#each' do
220
+
221
+ before do
222
+ @files = YAML.load('[f1.rb, f1.yaml, README, COPYING, [d2, f21.rb, f22.rb, f21.yaml, f22.yaml, CHANGELOG], [d3, f31.rb, f32.rb]]')
223
+ @dir = make_dir_tree @files
224
+ @prj = Ruber::Project.new File.join(@dir, 'test.ruprj'), 'Test'
225
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => %w[README f1.yaml], :exclude => %w[d2/f22.rb], :extensions => %w[*.rb]} }))
226
+ @list = Ruber::ProjectFilesList.new @prj
227
+ @prj.add_extension :file_lister, @list
228
+ end
229
+
230
+ it 'should update the cache if it\'s not up to date and a block is given' do
231
+ @list.instance_variable_set :@up_to_date, false
232
+ flexmock(@list).should_receive(:refresh).once
233
+ @list.each{}
234
+ end
235
+
236
+ it 'should not update the cache if it\'s already up to date and a block is given' do
237
+ @list.instance_variable_set :@up_to_date, true
238
+ flexmock(@list).should_receive(:refresh).never
239
+ @list.each{}
240
+ end
241
+
242
+ it 'should call the associated block passing the full file name of each project file if called with a block and the argument is true' do
243
+ exp = %w[f1.rb f1.yaml README d2/f21.rb d3/f31.rb d3/f32.rb].map{|f| File.join @dir, f}
244
+ m = flexmock do |mk|
245
+ exp.each{|f| mk.should_receive(:test).once.with(f)}
246
+ end
247
+ @list.each(true){|f| m.test f}
248
+ end
249
+
250
+ it 'should call the associated block passing the file name of each project file relative to the project directory if called with a block and the argument is false' do
251
+ exp = %w[f1.rb f1.yaml README d2/f21.rb d3/f31.rb d3/f32.rb]
252
+ m = flexmock do |mk|
253
+ exp.each{|f| mk.should_receive(:test).once.with(f)}
254
+ end
255
+ @list.each(false){|f| m.test f}
256
+ end
257
+
258
+ it 'should return an enumerator which yields the full file name of each project file if called without a block and the argument is true' do
259
+ enum = @list.each(true)
260
+ enum.should be_a(Enumerable)
261
+ exp = %w[f1.rb f1.yaml README d2/f21.rb d3/f31.rb d3/f32.rb].map{|f| File.join @dir, f}
262
+ m = flexmock do |mk|
263
+ exp.each{|f| mk.should_receive(:test).once.with(f)}
264
+ end
265
+ enum.each{|f| m.test f}
266
+ end
267
+
268
+ it 'should return an enumerator which yields the file name of each project file relative to the project directory if called without a block and the argument is false' do
269
+ enum = @list.each(false)
270
+ enum.should be_a(Enumerable)
271
+ exp = %w[f1.rb f1.yaml README d2/f21.rb d3/f31.rb d3/f32.rb]
272
+ m = flexmock do |mk|
273
+ exp.each{|f| mk.should_receive(:test).once.with(f)}
274
+ end
275
+ enum.each{|f| m.test f}
276
+ end
277
+
278
+ it 'should never update the cache if no block is given' do
279
+ @list.instance_variable_set :@up_to_date, false
280
+ flexmock(@list).should_receive(:refresh).never
281
+ @list.each
282
+ @list.instance_variable_set :@up_to_date, true
283
+ @list.each
284
+ end
285
+
286
+ end
287
+
288
+ describe 'Ruber::ProjectFilesList#rel' do
289
+
290
+ before do
291
+ @files = YAML.load('[f1.rb, f1.yaml, README, COPYING, [d2, f21.rb, f22.rb, f21.yaml, f22.yaml, CHANGELOG], [d3, f31.rb, f32.rb]]')
292
+ @dir = make_dir_tree @files
293
+ @prj = Ruber::Project.new File.join(@dir, 'test.ruprj'), 'Test'
294
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => %w[README f1.yaml], :exclude => %w[d2/f22.rb], :extensions => %w[*.rb]} }))
295
+ @list = Ruber::ProjectFilesList.new @prj
296
+ @prj.add_extension :file_lister, @list
297
+ end
298
+
299
+ it 'should work as the each method with no block and a false argument' do
300
+ enum = @list.rel
301
+ enum.should be_a(Enumerable)
302
+ exp = %w[f1.rb f1.yaml README d2/f21.rb d3/f31.rb d3/f32.rb]
303
+ m = flexmock do |mk|
304
+ exp.each{|f| mk.should_receive(:test).once.with(f)}
305
+ end
306
+ enum.each{|f| m.test f}
307
+ end
308
+
309
+ end
310
+
311
+ describe 'Ruber::ProjectFilesList#abs' do
312
+
313
+ before do
314
+ @files = YAML.load('[f1.rb, f1.yaml, README, COPYING, [d2, f21.rb, f22.rb, f21.yaml, f22.yaml, CHANGELOG], [d3, f31.rb, f32.rb]]')
315
+ @dir = make_dir_tree @files
316
+ @prj = Ruber::Project.new File.join(@dir, 'test.ruprj'), 'Test'
317
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => %w[README f1.yaml], :exclude => %w[d2/f22.rb], :extensions => %w[*.rb]} }))
318
+ @list = Ruber::ProjectFilesList.new @prj
319
+ @prj.add_extension :file_lister, @list
320
+ end
321
+
322
+ it 'should work as the each method with no block and a true argument' do
323
+ enum = @list.abs
324
+ enum.should be_a(Enumerable)
325
+ exp = %w[f1.rb f1.yaml README d2/f21.rb d3/f31.rb d3/f32.rb].map{|f| File.join @dir, f}
326
+ m = flexmock do |mk|
327
+ exp.each{|f| mk.should_receive(:test).once.with(f)}
328
+ end
329
+ enum.each{|f| m.test f}
330
+ end
331
+
332
+
333
+ end
334
+
335
+ describe Ruber::ProjectFilesList do
336
+
337
+ describe '#file_in_project?' do
338
+
339
+ before do
340
+ @dir = File.dirname __FILE__
341
+ @prj = Ruber::Project.new File.join(@dir, 'test.ruprj'), 'Test'
342
+ @prj.add_option(OS.new({:group => :general, :name => :project_files, :default => {:include => %w[], :exclude => %w[], :extensions => []} }))
343
+ @list = Ruber::ProjectFilesList.new @prj
344
+ @prj.add_extension :file_lister, @list
345
+ end
346
+
347
+ it 'should return true if the argument matches one of the exact include rules' do
348
+ @prj[:general, :project_files] = {:include => %w[./xyz ./abc ./123], :exclude => [], :extensions => ['*.rb']}
349
+ @list.file_in_project?(File.join(@prj.project_dir, 'abc')).should be_true
350
+ end
351
+
352
+ it 'should return true if the argument matches one of the regexp include rules' do
353
+ @prj[:general, :project_files] = {:include => [/a/, /x/], :exclude => [], :extensions => ['*.rb']}
354
+ @list.file_in_project?(File.join(@prj.project_dir, 'xyz')).should be_true
355
+ end
356
+
357
+ it 'should return true if the argument matches one of the include extensions' do
358
+ @prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => ['*.rb', '*.yaml']}
359
+ @list.file_in_project?(File.join(@prj.project_dir, 'abc.rb')).should be_true
360
+ end
361
+
362
+ it 'should return false if the file isn\'t in the project directory' do
363
+ @prj[:general, :project_files] = {:include => %w[xyz abc 123], :exclude => [], :extensions => ['*.rb']}
364
+ @list.file_in_project?('/usr/abc').should be_false
365
+ end
366
+
367
+ it 'should treat the argument as a path relative to the project directory if it isn\'t an absolute path' do
368
+ @prj[:general, :project_files] = {:include => %w[xyz abc 123], :exclude => [], :extensions => ['*.rb']}
369
+ @list.file_in_project?('abc').should be_true
370
+ end
371
+
372
+ it 'should return false if the file doesn\'t match any include rule' do
373
+ @list.file_in_project?(File.join(@prj.project_dir, 'abc.rb')).should be_false
374
+ end
375
+
376
+ it 'should return false if the file matches one of the file exclude rules' do
377
+ @prj[:general, :project_files] = {:include => %w[xyz abc 123], :exclude => ['abc'], :extensions => ['*.rb']}
378
+ @list.file_in_project?(File.join(@prj.project_dir, 'abc')).should be_false
379
+ end
380
+
381
+ it 'should return false if the file matches one of the exclude regexps' do
382
+ @prj[:general, :project_files] = {:include => [/a/], :exclude => [/a/], :extensions => []}
383
+ @list.file_in_project?(File.join(@prj.project_dir, 'abc')).should be_false
384
+ end
385
+
386
+ it 'it considers the whole path of the file, not just the filename' do
387
+ @prj[:general, :project_files] = {:include => [%r{a/.*}], :exclude => [%r{b/.*}], :extensions => ['*.rb']}
388
+ @list.file_in_project?(File.join(@prj.project_dir, 'a', 'xyz')).should be_true
389
+ @list.file_in_project?(File.join(@prj.project_dir, 'b', 'xyz.rb')).should be_false
390
+ end
391
+
392
+ it 'returns nil if the file name ends with a slash' do
393
+ @prj[:general, :project_files] = {:include => [%r{a/.*}], :exclude => [%r{b/.*}], :extensions => ['*.rb']}
394
+ @list.file_in_project?('xyz/').should be_nil
395
+ end
396
+
397
+ end
398
+
399
+ end
400
+
401
+ end
@@ -0,0 +1,511 @@
1
+ require 'spec/common'
2
+
3
+ require 'flexmock'
4
+
5
+ require 'ruber/projects/project_list'
6
+ require 'ruber/plugin_specification'
7
+
8
+ class Ruber::ProjectList::FakeProject < Qt::Object
9
+
10
+ signals 'closing(QObject*)'
11
+ attr_reader :project_name, :project_file
12
+ def initialize name = 'test', file = nil
13
+ super()
14
+ @project_file = file || Array.new(6){97 + rand(26)}.join
15
+ @project_name = name
16
+ end
17
+
18
+ def deactivate;end
19
+
20
+ def activate;end
21
+
22
+ def close
23
+ emit closing(self)
24
+ end
25
+ end
26
+
27
+ describe Ruber::ProjectList do
28
+
29
+ it 'should mix-in Enumerable' do
30
+ Ruber::ProjectList.ancestors.include?(Enumerable).should be_true
31
+ end
32
+
33
+ end
34
+
35
+ describe 'Ruber::ProjectList#project_for_file' do
36
+
37
+ before do
38
+ manager = flexmock('components'){|m| m.should_ignore_missing}
39
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(KDE::Application.instance).by_default
40
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil).by_default
41
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager).by_default
42
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
43
+ @projects = Ruber::ProjectList.new manager, pdf
44
+ end
45
+
46
+ it 'returns nil if there\'s no current project' do
47
+ flexmock(@projects).should_receive(:current).twice.and_return nil
48
+ @projects.project_for_file(__FILE__, :active).should be_nil
49
+ @projects.project_for_file(__FILE__, :all).should be_nil
50
+ end
51
+
52
+ it 'returns the current project if there\'s one and the file belongs to it' do
53
+ prj = flexmock{|m| m.should_receive('project_files.file_in_project?').twice.with(__FILE__).and_return true}
54
+ flexmock(@projects).should_receive(:current).twice.and_return prj
55
+ @projects.project_for_file(__FILE__, :active).should == prj
56
+ @projects.project_for_file(__FILE__, :all).should == prj
57
+ end
58
+
59
+ it 'returns nil if the file doesn\'t belong to the current project and the second argument is :active, even if the file belongs to another project' do
60
+ active_prj = flexmock{|m| m.should_receive('project_files.file_in_project?').once.with(__FILE__).and_return false}
61
+ prj = flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).and_return true}
62
+ flexmock(@projects).should_receive(:current).once.and_return(active_prj)
63
+ flexmock(@projects).should_receive(:each).and_yield(active_prj, prj)
64
+ @projects.project_for_file(__FILE__, :active).should be_nil
65
+ end
66
+
67
+ it 'returns the first project to which the file belongs, if it doesn\'t belong to the current one and the second argument is :all' do
68
+ active_prj = flexmock{|m| m.should_receive('project_files.file_in_project?').twice.with(__FILE__).and_return false}
69
+ prjs = [
70
+ flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).once.and_return false},
71
+ active_prj,
72
+ flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).once.and_return true},
73
+ flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).never}
74
+ ]
75
+ flexmock(@projects).should_receive(:current).once.and_return(active_prj)
76
+ projects = {
77
+ '0' => prjs[0],
78
+ '1' => prjs[1],
79
+ '2' => prjs[2],
80
+ '3' => prjs[3]
81
+ }
82
+ @projects.instance_variable_set(:@projects, projects)
83
+ @projects.project_for_file(__FILE__, :all).should equal(prjs[2])
84
+ end
85
+
86
+ it 'returns nil if the second argument is :all and the file doesn\'t belong to any project' do
87
+ active_prj = flexmock{|m| m.should_receive('project_files.file_in_project?').twice.with(__FILE__).and_return false}
88
+ prjs = [
89
+ flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).once.and_return false},
90
+ active_prj,
91
+ flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).once.and_return false},
92
+ flexmock{|m| m.should_receive('project_files.file_in_project?').with(__FILE__).once.and_return false}
93
+ ]
94
+ flexmock(@projects).should_receive(:current).once.and_return(active_prj)
95
+ projects = {
96
+ '0' => prjs[0],
97
+ '1' => prjs[1],
98
+ '2' => prjs[2],
99
+ '3' => prjs[3]
100
+ }
101
+ @projects.instance_variable_set(:@projects, projects)
102
+ @projects.project_for_file(__FILE__, :all).should be_nil
103
+ end
104
+
105
+ end
106
+
107
+ describe 'Ruber::ProjectList#each_project' do
108
+
109
+ before do
110
+ app = Qt::Object.new
111
+ manager = flexmock('components'){|m| m.should_ignore_missing}
112
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
113
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
114
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
115
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
116
+ @keeper = Ruber::ProjectList.new manager, pdf
117
+ end
118
+
119
+
120
+ it 'should yield all the projects in the list if called with a block' do
121
+ prjs = Array.new(3){|i| Ruber::ProjectList::FakeProject.new("test#{i}")}
122
+ prjs.each{|pr| @keeper.add_project pr}
123
+ res = []
124
+ @keeper.each_project{|pr| res << pr}
125
+ res.sort_by{|pr| pr.project_file}.should == prjs.sort_by{|pr| pr.project_file}
126
+ end
127
+
128
+ it 'should return an enumerable which yields all the projects in the list if called without a block' do
129
+ prjs = Array.new(3){|i| Ruber::ProjectList::FakeProject.new("test#{i}")}
130
+ prjs.each{|pr| @keeper.add_project pr}
131
+ m = flexmock do |mk|
132
+ prjs.each{|prj| mk.should_receive(:test).once.with prj}
133
+ end
134
+ en = @keeper.each_project
135
+ if RUBY_VERSION.match(/8/) then en.should be_an(Enumerable::Enumerator)
136
+ else en.should be_an(Enumerator)
137
+ end
138
+ en.each{|prj| m.test prj}
139
+ end
140
+
141
+ end
142
+
143
+ describe 'Ruber::ProjectList, when created' do
144
+
145
+ before do
146
+ app = Qt::Object.new
147
+ manager = flexmock('components'){|m| m.should_ignore_missing}
148
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
149
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
150
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
151
+ @pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
152
+ @keeper = Ruber::ProjectList.new manager, @pdf
153
+ end
154
+
155
+ it 'should call its initialize_plugin method' do
156
+ @keeper.plugin_description.should == @pdf
157
+ end
158
+
159
+ it 'should have no project' do
160
+ @keeper.projects.should be_empty
161
+ end
162
+
163
+ it 'should have no current project' do
164
+ @keeper.current_project.should be_nil
165
+ end
166
+
167
+ end
168
+
169
+ describe 'Ruber::Project#current_project=, when called with a non-nil argument' do
170
+
171
+ before do
172
+ app = Qt::Object.new
173
+ manager = flexmock('components'){|m| m.should_ignore_missing}
174
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
175
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
176
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
177
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
178
+ @keeper = Ruber::ProjectList.new manager, pdf
179
+ @prj = Ruber::ProjectList::FakeProject.new
180
+ @keeper.instance_variable_get(:@projects)[@prj.project_file] = @prj
181
+ @keeper.instance_variable_get(:@projects)['test'] = @prj
182
+ end
183
+
184
+ it 'should set the current project to its argument' do
185
+ @keeper.current_project = @prj
186
+ @keeper.current_project.should equal( @prj )
187
+ end
188
+
189
+ it 'should call the "deactivate" method of the old current project, if it\'s not nil' do
190
+ @keeper.instance_variable_set(:@current_project, @prj)
191
+ new_prj = Ruber::ProjectList::FakeProject.new 'Test1'
192
+ @keeper.add_project new_prj
193
+ flexmock(@prj).should_receive( :deactivate).once
194
+ @keeper.current_project = new_prj
195
+ @keeper.instance_variable_set :@current_project, nil
196
+ lambda{@keeper.current_project = @prj}.should_not raise_error
197
+ end
198
+
199
+ it 'should emit the "current_project_changed(QObject*)" signal with the project as argument' do
200
+ test = flexmock('test'){|m| m.should_receive(:current_project_changed).once.with(@prj)}
201
+ @keeper.connect(SIGNAL('current_project_changed(QObject*)')){|o| test.current_project_changed(o)}
202
+ @keeper.current_project = @prj
203
+ end
204
+
205
+ it 'should call the "activate" method of the new current project' do
206
+ @keeper.instance_variable_set(:@current_project, @prj)
207
+ new_prj = Ruber::ProjectList::FakeProject.new 'Test1'
208
+ @keeper.add_project new_prj
209
+ flexmock(new_prj).should_receive( :activate).once
210
+ @keeper.current_project = new_prj
211
+ end
212
+
213
+ it 'should raise ArgumentError if the project is not in the project list' do
214
+ @keeper.instance_variable_get(:@projects).clear
215
+ lambda{@keeper.current_project = @prj}.should raise_error(ArgumentError, "Tried to set an unknown as current project")
216
+ end
217
+
218
+ end
219
+
220
+ describe 'Ruber::Project#current_project=, when called with nil' do
221
+
222
+ before do
223
+ app = Qt::Object.new
224
+ manager = flexmock('components'){|m| m.should_ignore_missing}
225
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
226
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
227
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
228
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
229
+ @keeper = Ruber::ProjectList.new manager, pdf
230
+ end
231
+
232
+ it 'should set the current project to nil' do
233
+ @keeper.current_project = nil
234
+ @keeper.current_project.should be_nil
235
+ end
236
+
237
+ it 'should emit the "current_project_changed(QObject*)" signal with Qt::NilObject as argument' do
238
+ test = flexmock('test'){|m| m.should_receive(:current_project_changed).once.with(nil)}
239
+ @keeper.connect(SIGNAL('current_project_changed(QObject*)')){|o| test.current_project_changed(o)}
240
+ @keeper.current_project = nil
241
+ end
242
+
243
+ end
244
+
245
+ describe 'Ruber::ProjectList#add_project' do
246
+
247
+ before do
248
+ app = Qt::Object.new
249
+ manager = flexmock('components'){|m| m.should_ignore_missing}
250
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
251
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
252
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
253
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
254
+ @keeper = Ruber::ProjectList.new manager, pdf
255
+ end
256
+
257
+ it 'should add the project passed as argument to the list of projects' do
258
+ prj = Ruber::ProjectList::FakeProject.new 'Test'
259
+ @keeper.add_project prj
260
+ @keeper.instance_variable_get(:@projects)[prj.project_file].should equal(prj)
261
+ end
262
+
263
+ it 'should return the project' do
264
+ prj = Ruber::ProjectList::FakeProject.new 'Test'
265
+ @keeper.add_project( prj).should equal(prj)
266
+ end
267
+
268
+ it 'should emit the "project_added(QObject*)" signal passing the added project' do
269
+ prj = Ruber::ProjectList::FakeProject.new 'Test'
270
+ m = flexmock('test'){|mk| mk.should_receive(:project_added).once.with(prj)}
271
+ @keeper.connect(SIGNAL('project_added(QObject*)')){|o| m.project_added(o)}
272
+ @keeper.add_project prj
273
+ end
274
+
275
+ it 'should raise RuntimeError if the project is already in the list' do
276
+ prj_file = File.expand_path('test.ruprj')
277
+ prj1 = Ruber::ProjectList::FakeProject.new 'test1', prj_file
278
+ prj2 = Ruber::ProjectList::FakeProject.new 'test2', prj_file
279
+ @keeper.add_project prj1
280
+ lambda{@keeper.add_project prj2}.should raise_error(RuntimeError, "A project with project file #{prj_file} is already open")
281
+ end
282
+
283
+ end
284
+
285
+ describe 'Ruber::ProjectList, when a project in the list is closed' do
286
+
287
+ before do
288
+ app = Qt::Object.new
289
+ manager = flexmock('components'){|m| m.should_ignore_missing}
290
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
291
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
292
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
293
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
294
+ @keeper = Ruber::ProjectList.new manager, pdf
295
+ end
296
+
297
+ it 'should emit the "project_closing" signal, passing the project as argument' do
298
+ prj = Ruber::ProjectList::FakeProject.new
299
+ @keeper.add_project prj
300
+ m = flexmock{|mk| mk.should_receive(:project_closing).once}
301
+ @keeper.connect(SIGNAL('closing_project(QObject*)')){|o| m.project_closing(o)}
302
+ prj.close
303
+ end
304
+
305
+ it 'should set the current project to nil if the closed project was the current one' do
306
+ prj = Ruber::ProjectList::FakeProject.new
307
+ @keeper.add_project prj
308
+ @keeper.current_project = prj
309
+ prj.close
310
+ @keeper.current_project.should be_nil
311
+ end
312
+
313
+ end
314
+
315
+ describe 'Ruber::ProjectList#close_current_project' do
316
+
317
+ include FlexMock::ArgumentTypes
318
+
319
+ before do
320
+ app = Qt::Object.new
321
+ manager = flexmock('components'){|m| m.should_ignore_missing}
322
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
323
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
324
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
325
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
326
+ @keeper = Ruber::ProjectList.new manager, pdf
327
+ @prj = Ruber::ProjectList::FakeProject.new{self.object_name = 'project'}
328
+ @keeper.add_project = @prj
329
+ @keeper.current_project= @prj
330
+ end
331
+
332
+ it 'should set the current project to nil' do
333
+ flexmock(@keeper).should_receive(:current_project=).with(nil).once
334
+ @keeper.close_current_project
335
+ end
336
+
337
+ it 'should emit the "closing_project(QObject*)" signal after setting the current_project to nil, passing the project as argument' do
338
+ test = flexmock("test"){|m| m.should_receive(:project_closed).once.with(on{|a| a == @prj and !a.disposed?})}
339
+ flexmock(Ruber).should_receive(:[]).and_return(flexmock{|m| m.should_ignore_missing})
340
+ @keeper.connect(SIGNAL('closing_project(QObject*)')){|o| test.project_closed(o)}
341
+ @keeper.close_current_project
342
+ end
343
+
344
+ it 'should do nothing if the current project is nil' do
345
+ @keeper.instance_variable_set(:@current_project, nil)
346
+ lambda{@keeper.close_current_project}.should_not raise_error
347
+ end
348
+
349
+ end
350
+
351
+ describe 'Ruber::ProjectList#new_project' do
352
+
353
+ before do
354
+ app = Qt::Object.new
355
+ manager = flexmock('components'){|m| m.should_ignore_missing}
356
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
357
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
358
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
359
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
360
+ @keeper = Ruber::ProjectList.new manager, pdf
361
+ end
362
+
363
+ it 'should create a new empty project and return it' do
364
+ prj = Ruber::ProjectList::FakeProject.new 'test.ruprj', 'Test'
365
+ flexmock(Ruber::Project).should_receive(:new).once.with('test.ruprj', 'Test').and_return prj
366
+ res = @keeper.new_project 'test.ruprj', 'Test'
367
+ res.should equal(prj)
368
+ end
369
+
370
+ it 'should add the new project to the project list' do
371
+ prj = Ruber::ProjectList::FakeProject.new 'Test', 'test.ruprj'
372
+ flexmock(Ruber::Project).should_receive(:new).once.with('test.ruprj', 'Test').and_return prj
373
+ @keeper.new_project 'test.ruprj', 'Test'
374
+ @keeper.instance_variable_get(:@projects)['test.ruprj'].should equal(prj)
375
+ end
376
+
377
+ it 'should emit the "project_added(QObject*)" signal with the new project as argument' do
378
+ prj = Ruber::ProjectList::FakeProject.new 'Test', 'test.ruprj'
379
+ flexmock(Ruber::Project).should_receive(:new).once.with('test.ruprj', 'Test').and_return prj
380
+ m = flexmock('test'){|mk| mk.should_receive(:project_added).once.with(prj)}
381
+ @keeper.connect(SIGNAL('project_added(QObject*)')){|o| m.project_added(o)}
382
+ @keeper.new_project 'test.ruprj', 'Test'
383
+ end
384
+
385
+ end
386
+
387
+ describe 'Ruber::Project#project' do
388
+
389
+ before do
390
+ app = Qt::Object.new
391
+ manager = flexmock('components'){|m| m.should_ignore_missing}
392
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
393
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
394
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
395
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
396
+ @keeper = Ruber::ProjectList.new manager, pdf
397
+ end
398
+
399
+ it 'should return the project corresponding to the file passed as argument, if it is in the list' do
400
+ prj = Ruber::ProjectList::FakeProject.new 'Test', 'test.ruprj'
401
+ @keeper.instance_variable_get(:@projects)[prj.project_file] = prj
402
+ @keeper.project('test.ruprj').should equal(prj)
403
+ end
404
+
405
+ it 'should load the project from the file passed as argument if it isn\'t in the list' do
406
+ prj = Ruber::ProjectList::FakeProject.new 'Test', 'test.ruprj'
407
+ flexmock(Ruber::Project).should_receive(:new).once.with('test.ruprj').and_return prj
408
+ @keeper.project('test.ruprj').should equal(prj)
409
+ end
410
+
411
+ it 'should emit the "project_added(QObject*)" signal, passing the project as argument, if the project isn\'t in the list' do
412
+ prj = Ruber::ProjectList::FakeProject.new 'Test', 'test.ruprj'
413
+ flexmock(Ruber::Project).should_receive(:new).once.with('test.ruprj').and_return prj
414
+ m = flexmock{|mk| mk.should_receive(:project_added).once.with(prj)}
415
+ @keeper.connect(SIGNAL('project_added(QObject*)')){|o| m.project_added(o)}
416
+ @keeper.project 'test.ruprj'
417
+ end
418
+
419
+ end
420
+
421
+ describe 'Ruber::Project#[]' do
422
+
423
+ before do
424
+ app = Qt::Object.new
425
+ manager = flexmock('components'){|m| m.should_ignore_missing}
426
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
427
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
428
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
429
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
430
+ @keeper = Ruber::ProjectList.new manager, pdf
431
+ end
432
+
433
+ it 'should return the project corresponding to the given file, if the argument is a string starting with /, if such a project exists' do
434
+ prj = Ruber::ProjectList::FakeProject.new 'Test', '/test.ruprj'
435
+ @keeper.add_project prj
436
+ @keeper['/test.ruprj'].should equal(prj)
437
+ end
438
+
439
+ it 'should return the project with the given name if the argument is a string not starting with /, if such a project exists' do
440
+ prj = Ruber::ProjectList::FakeProject.new 'xyz', '/test.ruprj'
441
+ @keeper.add_project prj
442
+ @keeper['xyz'].should equal(prj)
443
+ end
444
+
445
+ it 'should return nil if the requested project doesn\'t exist' do
446
+ prj = Ruber::ProjectList::FakeProject.new 'xyz', '/test.ruprj'
447
+ @keeper.add_project prj
448
+ @keeper['abc'].should be_nil
449
+ @keeper['/xyz.ruprj'].should be_nil
450
+ end
451
+
452
+ end
453
+
454
+ describe 'Ruber::ProjectList#save_settings' do
455
+
456
+ before do
457
+ app = Qt::Object.new
458
+ manager = flexmock('components'){|m| m.should_ignore_missing}
459
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
460
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
461
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
462
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
463
+ @keeper = Ruber::ProjectList.new manager, pdf
464
+ end
465
+
466
+ it 'should call the save method of each open project' do
467
+ projects = @keeper.instance_variable_get(:@projects)
468
+ 5.times do |i|
469
+ projects[i] = flexmock(i.to_s){|m| m.should_receive(:save).once}
470
+ end
471
+ @keeper.save_settings
472
+ end
473
+
474
+ end
475
+
476
+ describe Ruber::ProjectList do
477
+
478
+ describe '#query_close' do
479
+
480
+ before do
481
+ app = Qt::Object.new
482
+ manager = flexmock('components'){|m| m.should_ignore_missing}
483
+ flexmock(Ruber).should_receive(:[]).with(:app).and_return(app)
484
+ flexmock(Ruber).should_receive(:[]).with(:components).and_return(manager)
485
+ flexmock(Ruber).should_receive(:[]).with(:config).and_return(nil)
486
+ pdf = Ruber::PluginSpecification.full({:name => :projects, :class => Ruber::ProjectList})
487
+ @keeper = Ruber::ProjectList.new manager, pdf
488
+ @values = 5.times.map{|i| flexmock(:project_name => i.to_s)}
489
+ prjs = @keeper.instance_variable_get(:@projects)
490
+ @values.each{|v| prjs[v.project_name] = v}
491
+ def prjs.values
492
+ super.sort_by{|p| p.project_name}
493
+ end
494
+ end
495
+
496
+ it 'calls the query_close method of all the projects and returns true if they all return true' do
497
+ @values.each{|pr| pr.should_receive(:query_close).once.and_return true}
498
+ @keeper.query_close.should be_true
499
+ end
500
+
501
+ it 'stops iterating through the projects and returns false if one of the project\'s query_close method returns false' do
502
+ @values[0].should_receive(:query_close).once.and_return true
503
+ @values[1].should_receive(:query_close).once.and_return true
504
+ @values[2].should_receive(:query_close).once.and_return false
505
+ @values[3].should_receive(:query_close).never
506
+ @values[4].should_receive(:query_close).never
507
+ @keeper.query_close.should be_false
508
+ end
509
+
510
+ end
511
+ end