ruber 0.0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,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