ruber 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGES +21 -0
  2. data/data/share/apps/ruber/ruberui.rc +3 -1
  3. data/lib/ruber/application/application.rb +22 -23
  4. data/lib/ruber/application/plugin.yaml +7 -2
  5. data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
  6. data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
  7. data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
  8. data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
  9. data/lib/ruber/application/ui/project_files_widget.rb +117 -0
  10. data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
  11. data/lib/ruber/component_manager.rb +14 -9
  12. data/lib/ruber/editor/document.rb +35 -5
  13. data/lib/ruber/kde_sugar.rb +16 -0
  14. data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
  15. data/lib/ruber/main_window/main_window.rb +131 -193
  16. data/lib/ruber/main_window/main_window_actions.rb +157 -58
  17. data/lib/ruber/main_window/main_window_internal.rb +145 -54
  18. data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
  19. data/lib/ruber/main_window/plugin.yaml +3 -6
  20. data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
  21. data/lib/ruber/main_window/workspace.rb +62 -32
  22. data/lib/ruber/output_widget.rb +20 -16
  23. data/lib/ruber/pane.rb +11 -5
  24. data/lib/ruber/project.rb +27 -12
  25. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
  26. data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
  27. data/lib/ruber/utils.rb +37 -4
  28. data/lib/ruber/version.rb +1 -1
  29. data/lib/ruber/world/document_factory.rb +121 -0
  30. data/lib/ruber/world/document_list.rb +396 -0
  31. data/lib/ruber/world/environment.rb +470 -0
  32. data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
  33. data/lib/ruber/world/plugin.yaml +11 -0
  34. data/lib/ruber/world/project_factory.rb +131 -0
  35. data/lib/ruber/world/project_list.rb +265 -0
  36. data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
  37. data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
  38. data/lib/ruber/world/world.rb +307 -0
  39. data/plugins/auto_end/auto_end.rb +135 -9
  40. data/plugins/autosave/autosave.rb +4 -4
  41. data/plugins/find_in_files/find_in_files.rb +5 -5
  42. data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
  43. data/plugins/project_browser/project_browser.rb +4 -4
  44. data/plugins/rake/rake.rb +4 -4
  45. data/plugins/rake/rake_extension.rb +1 -1
  46. data/plugins/rspec/rspec.rb +4 -4
  47. data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
  48. data/plugins/ruby_development/ruby_development.rb +3 -3
  49. data/plugins/ruby_runner/ruby_runner.rb +2 -2
  50. data/plugins/state/plugin.yaml +6 -8
  51. data/plugins/state/state.rb +201 -391
  52. data/plugins/state/ui/config_widget.rb +5 -5
  53. data/plugins/state/ui/config_widget.ui +3 -3
  54. data/plugins/syntax_checker/syntax_checker.rb +4 -0
  55. data/spec/annotation_model_spec.rb +1 -1
  56. data/spec/auto_end_spec.rb +98 -47
  57. data/spec/component_manager_spec.rb +80 -21
  58. data/spec/document_factory_spec.rb +115 -0
  59. data/spec/document_list_spec.rb +560 -450
  60. data/spec/document_spec.rb +143 -55
  61. data/spec/editor_view_spec.rb +2 -2
  62. data/spec/environment_spec.rb +1900 -0
  63. data/spec/hint_solver_spec.rb +5 -5
  64. data/spec/kde_sugar_spec.rb +16 -0
  65. data/spec/output_widget_spec.rb +177 -51
  66. data/spec/pane_spec.rb +29 -5
  67. data/spec/plugin_spec.rb +1 -1
  68. data/spec/project_factory_spec.rb +104 -0
  69. data/spec/project_list_spec.rb +352 -447
  70. data/spec/project_spec.rb +34 -33
  71. data/spec/qt_sugar_spec.rb +2 -2
  72. data/spec/state_spec.rb +508 -811
  73. data/spec/utils_spec.rb +149 -98
  74. data/spec/workspace_spec.rb +120 -9
  75. data/spec/world_spec.rb +1219 -0
  76. metadata +23 -14
  77. data/lib/ruber/documents/document_list.rb +0 -412
  78. data/lib/ruber/documents/plugin.yaml +0 -4
  79. data/lib/ruber/main_window/view_manager.rb +0 -431
  80. data/lib/ruber/projects/plugin.yaml +0 -11
  81. data/lib/ruber/projects/project_list.rb +0 -314
@@ -1,624 +1,734 @@
1
+ require './spec/framework'
1
2
  require './spec/common'
2
- require 'pathname'
3
3
 
4
- require 'ruber/utils'
5
- require 'ruber/documents/document_list'
6
- require 'ruber/plugin_specification'
4
+ require 'ruber/world/document_list'
5
+ require 'ruber/editor/document'
7
6
 
8
- describe Ruber::DocumentList do
7
+ describe Ruber::World::DocumentList do
9
8
 
10
- before do
11
- @app = KDE::Application.instance
12
- @pdf = Ruber::PluginSpecification.full({:name => :documents, :class => Ruber::DocumentList})
13
- @manager = flexmock("manager"){|m| m.should_ignore_missing}
14
- flexmock(Ruber).should_receive(:[]).with(:app).and_return @app
15
- flexmock(Ruber).should_receive(:[]).with(:components).and_return @manager
16
- flexmock(Ruber).should_receive(:[]).with(:config).and_return nil
17
- @mw = Qt::Widget.new
18
- flexmock(Ruber).should_receive(:[]).with(:main_window).and_return @mw
19
- @keeper = Ruber::DocumentList.new @manager, @pdf
20
- flexmock(Ruber).should_receive(:[]).with(:docs).and_return @keeper
21
- flexmock(Ruber).should_receive(:[]).with(:documents).and_return @keeper
9
+ def create_list docs
10
+ Ruber::World::DocumentList.new docs
22
11
  end
23
12
 
24
- after do
25
- @keeper.instance_variable_get(:@docs).each{|d| d.dispose rescue nil}
13
+ before do
14
+ @docs = 3.times.map{Ruber::Document.new}
26
15
  end
27
16
 
28
- it 'should be Enumerable' do
29
- Ruber::DocumentList.ancestors.include?(Enumerable).should be_true
30
- end
31
-
32
- it 'should have no documents when created' do
33
- @keeper.should be_empty
17
+ it 'includes the enumerable module' do
18
+ Ruber::World::DocumentList.ancestors.should include(Enumerable)
34
19
  end
35
20
 
36
- it 'should call the initialize_plugin method' do
37
- @keeper.plugin_description.should == @pdf
21
+ describe '.new' do
22
+
23
+ it 'takes a Ruber::Worl::dDocumentList or an array as parameters' do
24
+ list = Ruber::World::DocumentList.new @docs
25
+ list.should == @docs
26
+ other_list = Ruber::World::MutableDocumentList.new(@docs)
27
+ list = Ruber::World::DocumentList.new other_list
28
+ list.should == @docs
29
+ end
30
+
31
+ it 'doesn\'t create a duplicate of the argument if the argument is a DocumentList' do
32
+ other_list = Ruber::World::DocumentList.new(@docs)
33
+ list = Ruber::World::DocumentList.new other_list
34
+ list.send(:document_array).should equal(other_list.send(:document_array))
35
+ end
36
+
37
+ it 'creates a duplicate of the argument if the argument is not a DocumentList' do
38
+ list = Ruber::World::DocumentList.new @docs
39
+ new_doc = Ruber::Document.new
40
+ @docs << new_doc
41
+ list.size.should == 3
42
+ end
43
+
38
44
  end
39
-
40
- describe 'Ruber::DocumentList#[]' do
45
+
46
+ describe '#each' do
41
47
 
42
- context 'when called with an integer argument' do
43
-
44
- before do
45
- @docs = 4.times.map do
46
- doc = Ruber::Document.new Ruber[:main_window]
47
- @keeper.add_document doc
48
- doc
49
- end
50
- end
48
+ before do
49
+ @list = create_list @docs
50
+ end
51
+
52
+ context 'when called with a block' do
51
53
 
52
- it 'returns the document in the given position' do
54
+ it 'calls the block once for each document' do
53
55
  res = []
54
- 4.times{|i| res[i] = @keeper[i]}
56
+ @list.each{|d| res << d}
55
57
  res.should == @docs
56
58
  end
57
59
 
58
- it 'returns nil if the index is out of range' do
59
- @keeper[5].should be_nil
60
+ it 'returns self' do
61
+ @list.each{|d|}.should == @list
60
62
  end
61
-
63
+
62
64
  end
63
65
 
64
- context 'when called with a string representing an absolute path' do
66
+ context 'when called without a block' do
65
67
 
66
- it 'returns the document associated with the path' do
67
- doc = Ruber::Document.new Ruber[:main_window], __FILE__
68
- @keeper.add_document doc
69
- @keeper[File.expand_path(__FILE__)].should == doc
70
- end
71
-
72
- it 'returns nil if a document for that file doesn\'t exist' do
73
- @keeper[`which ruby`].should be_nil
68
+ it 'returns an enumerator which iterates on all documents' do
69
+ res = []
70
+ enum = @list.each
71
+ enum.should be_an(Enumerator)
72
+ enum.each{|d| res << d}
73
+ res.should == @docs
74
74
  end
75
75
 
76
76
  end
77
77
 
78
- context 'when called with a string which doensn\'t represent an absolute path' do
78
+ end
79
+
80
+ describe '#empty?' do
81
+
82
+ it 'returns true if the list doesn\'t contain any element' do
83
+ list = create_list []
84
+ list.should be_empty
85
+ end
86
+
87
+ it 'returns false if the list contains at least one element' do
88
+ list = create_list @docs
89
+ list.should_not be_empty
90
+ end
91
+
92
+ end
93
+
94
+ describe '#size' do
95
+
96
+ it 'returns the number of elements in the list' do
97
+ list = create_list []
98
+ list.size.should == 0
99
+ list = create_list [Ruber::Document.new]
100
+ list.size.should == 1
101
+ list = create_list @docs
102
+ list.size.should == 3
103
+ end
104
+
105
+ end
106
+
107
+ describe '#==' do
108
+
109
+ before do
110
+ @list = create_list @docs
111
+ end
112
+
113
+ context 'when the argument is a DocumentList' do
114
+
115
+ it 'returns true if the argument contains the same documents in the same order' do
116
+ other = create_list @docs
117
+ @list.should == other
118
+ end
79
119
 
80
- it 'returns the document with the given document_name' do
81
- doc = Ruber::Document.new Ruber[:main_window], __FILE__
82
- @keeper.add_document doc
83
- @keeper[doc.document_name].should == doc
120
+ it 'returns false if the argument contains different documents' do
121
+ other = create_list [@docs[1], @docs[2]]
122
+ @list.should_not == other
84
123
  end
85
124
 
86
- it 'returns nil if no document with the given document name exists' do
87
- @keeper['abcd'].should be_nil
125
+ it 'returns false if the argument contains the same documents in different order' do
126
+ other = create_list [@docs[1], @docs[2], @docs[0]]
127
+ @list.should_not == other
88
128
  end
89
129
 
90
130
  end
91
131
 
92
- context 'when called with a KDE::Url' do
132
+ context 'when the argument is an Array' do
93
133
 
94
- it 'returns the document associated with the url' do
95
- url = KDE::Url.new 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
96
- doc = Ruber::Document.new Ruber[:main_window], url
97
- @keeper.add_document doc
98
- @keeper[url].should == doc
134
+ it 'returns true if the argument contains the same documents in the same order' do
135
+ @list.should == @docs
99
136
  end
100
137
 
101
- it 'returns nil if no document is associated with the given url' do
102
- url = KDE::Url.new 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
103
- @keeper[url].should be_nil
138
+ it 'returns false if the argument contains different documents' do
139
+ @list.should_not == [@docs[1], @docs[2]]
104
140
  end
105
141
 
106
- end
107
-
108
- context 'when called with any other argument' do
109
-
110
- it 'raises TypeError' do
111
- doc = @keeper.document __FILE__
112
- lambda{@keeper[1.2]}.should raise_error(TypeError)
113
- lambda{@keeper[{}]}.should raise_error(TypeError)
114
- lambda{@keeper[:xyz]}.should raise_error(TypeError)
142
+ it 'returns false if the argument contains the same documents in different order' do
143
+ @list.should_not == [@docs[1], @docs[2], @docs[0]]
115
144
  end
145
+
146
+ end
116
147
 
148
+ context 'when the argument is neither a DocumentList nor an array' do
149
+
150
+ it 'returns false' do
151
+ @list.should_not == {}
152
+ end
153
+
117
154
  end
118
-
155
+
119
156
  end
120
-
121
- describe 'Ruber::Document#document_for_file' do
122
-
123
- it 'returns the document corresponding to the given absolute path or nil' do
124
- doc = @keeper.document __FILE__
125
- @keeper.document_for_file( File.expand_path(__FILE__)).should == doc
126
- @keeper.document_for_file('/test').should be_nil
157
+
158
+ describe '#eql?' do
159
+
160
+ before do
161
+ @list = create_list @docs
127
162
  end
128
-
129
- it 'returns the document corresponding to the given relative path (expanding it) or nil' do
130
- doc = @keeper.document __FILE__
131
- @keeper.document_for_file( __FILE__).should == doc
132
- @keeper.document_for_file('test').should be_nil
163
+
164
+ context 'when the argument is a DocumentList' do
165
+
166
+ it 'returns true if the argument contains the same documents in the same order' do
167
+ other = create_list @docs
168
+ @list.should eql(other)
169
+ end
170
+
171
+ it 'returns false if the argument contains different documents' do
172
+ other = create_list [@docs[1], @docs[2]]
173
+ @list.should_not eql(other)
174
+ end
175
+
176
+ it 'returns false if the argument contains the same documents in different order' do
177
+ other = create_list [@docs[1], @docs[2], @docs[0]]
178
+ @list.should_not eql(other)
179
+ end
180
+
133
181
  end
134
-
135
- end
136
-
137
- describe 'Ruber::Document#document_with_name' do
138
182
 
139
- it 'should return the document with the given document_name or nil' do
140
- doc = @keeper.document __FILE__
141
- @keeper.document_with_name( File.basename(__FILE__)).should == doc
142
- @keeper.document_for_file('test').should be_nil
183
+ context 'when the argument is not a DocumentList' do
184
+
185
+ it 'returns false' do
186
+ @list.should_not eql([])
187
+ @list.should_not eql({})
188
+ end
189
+
143
190
  end
144
-
191
+
145
192
  end
146
193
 
147
- describe '#document_for_url' do
194
+ describe '#hash' do
148
195
 
149
- it 'returns the document associated with the given KDE::Url' do
150
- url = KDE::Url.new 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
151
- doc = Ruber::Document.new Ruber[:main_window], url
152
- @keeper.add_document doc
153
- @keeper.document_for_url(url).should == doc
196
+ it 'returns the same value as an array contining the same arguments' do
197
+ list = create_list @docs
198
+ list.hash.should == @docs.hash
154
199
  end
155
200
 
156
- it 'converts the argoment to a KDE::Url if it\'s a string' do
157
- str = 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
158
- url = KDE::Url.new str
159
- doc = Ruber::Document.new Ruber[:main_window], url
160
- @keeper.add_document doc
161
- @keeper.document_for_url(str).should == doc
162
- end
201
+ end
202
+
203
+ describe '#[]' do
163
204
 
164
- it 'returns nil if no document corresponding to the url exists' do
165
- url = 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
166
- @keeper.document_for_url(KDE::Url.new(url)).should be_nil
167
- @keeper.document_for_url(url).should be_nil
205
+ context 'when called with an integer argument' do
206
+
207
+ before do
208
+ @list = create_list @docs
209
+ end
210
+
211
+ it 'returns the document at the given position' do
212
+ @list[1].should == @docs[1]
213
+ end
214
+
215
+ it 'counts backward if the argument is negative' do
216
+ @list[-1].should == @docs[2]
217
+ end
218
+
219
+ it 'returns nil if the argument is out of range' do
220
+ @list[5].should be_nil
221
+ end
222
+
168
223
  end
169
224
 
170
- end
171
-
172
- describe '#each' do
225
+ context 'when the argument is an integer range' do
226
+
227
+ before do
228
+ @list = create_list @docs
229
+ end
230
+
231
+ it 'returns the document with indexes in the given range' do
232
+ @list[0..1].should == [@docs[0], @docs[1]]
233
+ end
234
+
235
+ it 'returns only the documents corresponding to existing indexes if the argument is partially out of range' do
236
+ @list[0..5].should == @docs
237
+ end
238
+
239
+ it 'returns nil if the argument is out of range' do
240
+ @list[5..9].should be_nil
241
+ end
242
+
243
+ end
173
244
 
174
- context 'when called with a block' do
175
-
176
- it 'allows to iterate on all documents (in creation order)' do
177
- docs = 4.times.map{@keeper.new_document}
178
- res = []
179
- @keeper.each{|d| res << d}
180
- res.should == docs
245
+ context 'when called with a KDE::Url' do
246
+
247
+ before do
248
+ @docs << Ruber::Document.new(__FILE__)
249
+ @list = create_list @docs
181
250
  end
182
251
 
183
- it 'returns self' do
184
- docs = 4.times.map{@keeper.new_document}
185
- @keeper.each{|d| d}.should equal(@keeper)
252
+ it 'returns the document associated with the argument' do
253
+ @list[KDE::Url.new(__FILE__)].should == @docs[-1]
254
+ end
255
+
256
+ it 'returns the first of the documents associated with the argument if there is more than one document for the given URL' do
257
+ doc = Ruber::Document.new __FILE__
258
+ @list = create_list @docs + [doc]
259
+ @list[KDE::Url.new(__FILE__)].should == @docs[-1]
260
+ end
261
+
262
+ it 'returns nil if there\'s no document associated with the given URL' do
263
+ @list[KDE::Url.new('file:///xyz')].should be_nil
186
264
  end
265
+
266
+ end
187
267
 
268
+ context 'when called with a string starting with a slash' do
269
+
270
+ before do
271
+ @docs << Ruber::Document.new(__FILE__)
272
+ @list = create_list @docs
273
+ end
274
+
275
+ it 'returns the document associated with the file corresponding to the argument' do
276
+ @list[__FILE__].should == @docs[-1]
277
+ end
278
+
279
+ it 'returns the first of the documents associated with the argument if there is more than one document for the given URL' do
280
+ doc = Ruber::Document.new __FILE__
281
+ @list = create_list @docs + [doc]
282
+ @list[__FILE__].should == @docs[-1]
283
+ end
284
+
285
+ it 'doesn\'t return remote files' do
286
+ url = KDE::Url.new("http://xyz.it#{__FILE__}")
287
+ remote_doc = Ruber::Document.new url
288
+ @list = create_list @docs + [remote_doc]
289
+ @list[__FILE__].should == @docs[-1]
290
+ end
291
+
292
+ it 'returns nil if there\'s no local file associated with the given file' do
293
+ @docs.delete_at -1
294
+ @list = create_list @docs
295
+ @list[__FILE__].should be_nil
296
+ url = KDE::Url.new("http://xyz.it#{__FILE__}")
297
+ remote_doc = Ruber::Document.new url
298
+ @list = create_list @docs + [remote_doc]
299
+ @list[__FILE__].should be_nil
300
+ end
301
+
188
302
  end
189
303
 
190
- context 'when called without a block' do
304
+ context 'when called with a string not starting with a slash' do
191
305
 
192
- it 'returns an enumerator which allows to iterate on all documents in creation order and returns the list' do
193
- docs = 4.times.map{@keeper.new_document}
194
- e = @keeper.each
195
- e.should be_an(Enumerable)
196
- res = []
197
- obj = e.each{|d| res << d}
198
- res.should == docs
199
- obj.should == @keeper
306
+ before do
307
+ flexmock(@docs[1]).should_receive(:document_name).and_return('doc1')
308
+ flexmock(@docs[2]).should_receive(:document_name).and_return('doc2')
309
+ @list = create_list @docs
200
310
  end
201
-
311
+
312
+ it 'returns the document with having the argument as document name' do
313
+ @list['doc1'].should == @docs[1]
314
+ end
315
+
316
+ it 'returns the first of the documents with the given document name if there is more than one document with that document name' do
317
+ doc = Ruber::Document.new
318
+ flexmock(doc).should_receive(:document_name).and_return('doc1')
319
+ @list = create_list @docs + [doc]
320
+ @list['doc1'].should == @docs[1]
321
+ end
322
+
323
+ it 'returns nil if there\'s no document with the given document name' do
324
+ @list['xyz'].should be_nil
325
+ end
326
+
202
327
  end
203
-
204
-
328
+
205
329
  end
206
-
207
- describe 'Ruber::Document#each_document' do
208
330
 
209
- it 'should allow to iterate on all documents (in creation order) when called with a block' do
210
- docs = 4.times.map{@keeper.new_document}
211
- res = []
212
- @keeper.each_document{|d| res << d}
213
- res.should == docs
331
+ describe '#document_for_file' do
332
+
333
+ before do
334
+ @docs = [Ruber::Document.new, Ruber::Document.new(__FILE__), Ruber::Document.new]
335
+ @list = create_list @docs
214
336
  end
215
-
216
- it 'should return an enumerator which allows to iterate on all documents in creation order when called without a block' do
217
- docs = 4.times.map{@keeper.new_document}
218
- e = @keeper.each_document
219
- e.should be_an(Enumerable)
220
- res = []
221
- e.each{|d| res << d}
222
- res.should == docs
337
+
338
+ it 'returns the document associated with the given file' do
339
+ @list.document_for_file(__FILE__).should == @docs[1]
223
340
  end
224
-
225
- end
226
-
227
- describe 'Ruber::Document#documents' do
228
-
229
- it 'should return an array with all the documents, in an arbitrary order' do
230
- docs = 4.times.map{@keeper.new_document}
231
- res = @keeper.documents
232
- res.should be_kind_of(Array)
233
- res.should == docs
341
+
342
+ it 'returns nil if there\'s no document associated with the given file' do
343
+ @list.document_for_file('/xyz').should be_nil
234
344
  end
235
-
236
- end
237
-
238
- describe 'Ruber::Document#to_a' do
239
-
240
- it 'should return an array with all the documents, in an arbitrary order' do
241
- docs = 4.times.map{@keeper.new_document}
242
- res = @keeper.to_a
243
- res.should be_kind_of(Array)
244
- res.should == docs
345
+
346
+ it 'doesn\'t return remote files' do
347
+ @docs.delete_at 1
348
+ url = KDE::Url.new("http://www.xyz.org#{__FILE__}")
349
+ @list = create_list @docs + [Ruber::Document.new(url)]
350
+ @list.document_for_file(__FILE__).should be_nil
245
351
  end
246
-
247
- end
248
-
249
- describe 'Ruber::Document#document_for_file?' do
250
-
251
- it 'should tell whether there\'s a document for the given filename if called with an absolute filename' do
252
- @keeper.document __FILE__
253
- @keeper.document_for_file?( File.expand_path(__FILE__) ).should be_true
254
- @keeper.document_for_file?('/test').should be_false
352
+
353
+ it 'returns the first document associated with the given file, if more than one document is associated with it' do
354
+ @list = create_list @docs + [Ruber::Document.new(__FILE__)]
355
+ @list.document_for_file(__FILE__).should == @docs[1]
255
356
  end
256
-
257
- it 'should tell whether there\'s a document for the given filename if called with a relative filename (which will be expanded)' do
258
- @keeper.document __FILE__
259
- @keeper.document_for_file?( __FILE__ ).should be_true
260
- @keeper.document_for_file?('test').should be_false
357
+
358
+ it 'raises ArgumentError if the file name is relative' do
359
+ file = File.basename(__FILE__)
360
+ lambda{@list.document_for_file file}.should raise_error(ArgumentError, "#{file} is not an absolute path")
261
361
  end
262
-
362
+
263
363
  end
264
364
 
265
- describe '#document_for_url?' do
365
+ describe '#document_for_file?' do
266
366
 
267
- it 'returns true if a document associated with the given KDE::Url exists' do
268
- url = KDE::Url.new 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
269
- doc = Ruber::Document.new Ruber[:main_window], url
270
- @keeper.add_document doc
271
- @keeper.document_for_url?(url).should be_true
367
+ before do
368
+ @docs = [Ruber::Document.new, Ruber::Document.new(__FILE__), Ruber::Document.new]
369
+ @list = create_list @docs
272
370
  end
273
371
 
274
- it 'converts the argoment to a KDE::Url if it\'s a string' do
275
- str = 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
276
- url = KDE::Url.new str
277
- doc = Ruber::Document.new Ruber[:main_window], url
278
- @keeper.add_document doc
279
- @keeper.document_for_url?(str).should be_true
372
+ it 'returns true if there\'s a document associated with the given file' do
373
+ @list.document_for_file?(__FILE__).should == true
280
374
  end
281
375
 
282
- it 'returns false if no document corresponding to the url exists' do
283
- url = 'http://github.com/stcrocco/ruber/raw/master/ruber.gemspec'
284
- @keeper.document_for_url(KDE::Url.new(url)).should be_false
285
- @keeper.document_for_url(url).should be_false
376
+ it 'returns false if there\'s no document associated with the given file' do
377
+ @list.document_for_file?('/xyz').should == false
286
378
  end
287
-
288
- end
289
-
290
- describe 'Ruber::Document#document_with_name' do
291
-
292
- it 'should tell whether there\'s a document with the given document_name' do
293
- @keeper.document __FILE__
294
- @keeper.document_with_name?( File.basename(__FILE__ )).should be_true
295
- @keeper.document_with_name?('test').should be_false
379
+
380
+ it 'raises ArgumentError if the file name is relative' do
381
+ file = File.basename(__FILE__)
382
+ lambda{@list.document_for_file? file}.should raise_error(ArgumentError, "#{file} is not an absolute path")
296
383
  end
297
-
384
+
298
385
  end
299
-
300
- describe 'Ruber::Document#documents_with_file' do
386
+
387
+ describe '#document_for_url' do
301
388
 
302
389
  before do
303
- @all_docs = []
304
- @empty_docs = []
305
- @local_docs = []
306
- @remote_docs = []
307
- @empty_docs << Ruber::Document.new << Ruber::Document.new
308
- @local_docs << Ruber::Document.new(nil, __FILE__) << Ruber::Document.new(nil, File.join(File.dirname(__FILE__), 'common.rb'))
309
- @remote_docs << Ruber::Document.new(nil, KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/ruber.gemspec')) << Ruber::Document.new(nil,
310
- KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/bin/ruber'))
311
- @all_docs << @empty_docs[0] << @local_docs[0] << @remote_docs[0] << @remote_docs[1] << @local_docs[1] << @empty_docs[1]
312
- @all_docs.each{|d| @keeper.add_document d}
390
+ @docs = [Ruber::Document.new, Ruber::Document.new(__FILE__), Ruber::Document.new]
391
+ @list = create_list @docs
313
392
  end
314
393
 
315
- describe 'when called with the :local argument' do
316
- it 'returns an array containing only the documents associated with local files' do
317
- @keeper.documents_with_file(:local).should == @local_docs
318
- end
394
+ it 'returns the document associated with the given URL' do
395
+ @list.document_for_url(KDE::Url.new(__FILE__)).should == @docs[1]
319
396
  end
320
397
 
321
- describe 'when called with the :remote argument' do
322
- it 'returns an array containing only the documents associated with remote files' do
323
- @keeper.documents_with_file(:remote).should == @remote_docs
324
- end
398
+ it 'returns nil if there\'s no document associated with the given file' do
399
+ @list.document_for_url(KDE::Url.new('http://xyz.org/abc')).should be_nil
325
400
  end
326
401
 
327
- describe 'when called with the :any argument' do
328
- it 'returns an array containing the documents associated with any file' do
329
- @keeper.documents_with_file(:any).should == [@local_docs[0], @remote_docs[0], @remote_docs[1], @local_docs[1]]
330
- end
402
+ it 'works if the URL is specified as a string' do
403
+ @list.document_for_url('file://'+__FILE__).should == @docs[1]
331
404
  end
332
405
 
333
- describe 'when called with no arguments' do
334
- it 'returns an array containing the documents associated with any file' do
335
- @keeper.documents_with_file.should == [@local_docs[0], @remote_docs[0], @remote_docs[1], @local_docs[1]]
336
- end
406
+ it 'returns the first document associated with the given URL, if more than one document is associated with it' do
407
+ @list = create_list @docs + [Ruber::Document.new(__FILE__)]
408
+ @list.document_for_url(KDE::Url.new(__FILE__)).should == @docs[1]
337
409
  end
338
-
410
+
339
411
  end
340
-
341
- describe 'Ruber::DocumentList#close_all' do
412
+
413
+ describe '#document_for_url?' do
342
414
 
343
415
  before do
344
- flexmock(@mw).should_receive(:save_documents).by_default.and_return(true)
345
- pdf = Ruber::PluginSpecification.full({:name => :documents, :class => Ruber::DocumentList})
346
- @docs = Array.new(5){|i| flexmock("doc #{i}"){|m| m.should_receive(:close).and_return(true).by_default}}
347
- 5.times {|i| flexmock(Ruber::Document).should_receive(:new).and_return(@docs[i])}
348
- @keeper.instance_variable_set :@docs, @docs.dup
416
+ @docs = [Ruber::Document.new, Ruber::Document.new(__FILE__), Ruber::Document.new]
417
+ @list = create_list @docs
349
418
  end
350
-
351
- it 'should call Ruber[:main_window].save_documents passing it all the documents, if the argument is true' do
352
- @mw.should_receive(:save_documents).once.with(@docs).and_return true
353
- @keeper.close_all
419
+
420
+ it 'returns true if there\'s a document associated with the given URL' do
421
+ @list.document_for_url?(KDE::Url.new(__FILE__)).should == true
354
422
  end
355
-
356
- it 'should return immediately if the call Ruber[:main_window].save_documents returns false' do
357
- @mw.should_receive(:save_documents).once.with(@docs).and_return false
358
- @docs.each{|d| d.should_receive(:close).never}
359
- @keeper.close_all
423
+
424
+ it 'returns false if there\'s no document associated with the given URL' do
425
+ @list.document_for_url?(KDE::Url.new('/xyz')).should == false
426
+ end
427
+
428
+ it 'also works if the URL is specified as a string' do
429
+ @list.document_for_url?('file://'+__FILE__).should == true
430
+ end
431
+
432
+ end
433
+
434
+ describe '#document_with_name' do
435
+
436
+ before do
437
+ @docs = 3.times.map{Ruber::Document.new}
438
+ flexmock(@docs[0]).should_receive(:document_name).and_return 'doc0'
439
+ flexmock(@docs[2]).should_receive(:document_name).and_return 'doc2'
440
+ @list = create_list @docs
360
441
  end
361
442
 
362
- it 'shouldn\'t call Ruber[:main_window].save_documents if the argument is false' do
363
- @mw.should_receive(:save_documents).never
364
- @keeper.close_all false
443
+ it 'returns the document with the given document_name' do
444
+ @list.document_with_name('doc0').should == @docs[0]
365
445
  end
366
446
 
367
- it 'should close each document, passing false argument as argument' do
368
- @mw.should_receive(:save_documents).and_return true
369
- @docs.each{|d| d.should_receive(:close).once.and_return true}
370
- @keeper.close_all false
447
+ it 'returns nil if there\'s no document with the given document name' do
448
+ @list.document_with_name('doc3').should be_nil
371
449
  end
372
450
 
373
- it 'should return true if the documents where closed and false otherwise' do
374
- @mw.should_receive(:save_documents).once.with(@docs).and_return true
375
- @keeper.close_all.should be_true
376
- @mw.should_receive(:save_documents).once.with(@docs).and_return false
377
- @keeper.close_all.should_not be
451
+ it 'returns the first document with the given document name, if there is more than one document with that name' do
452
+ doc = Ruber::Document.new
453
+ flexmock(doc).should_receive(:document_name).and_return 'doc0'
454
+ @list = create_list @docs + [doc]
455
+ @list.document_with_name('doc0').should == @docs[0]
378
456
  end
379
457
 
380
458
  end
381
-
382
- describe 'Ruber::DocumentList, when a document is closed' do
383
-
459
+
460
+ describe '#document_with_name?' do
384
461
 
385
- it 'should emit the "document_closing(QObject*)" signal, passing the document as argument' do
386
- doc = @keeper.new_document
387
- exp = doc.object_id
388
- m = flexmock{|mk| mk.should_receive(:closing_document).once.with(exp)}
389
- @keeper.connect(SIGNAL('closing_document(QObject*)')){|d| m.closing_document d.object_id}
390
- doc.close
462
+ before do
463
+ @docs = 3.times.map{Ruber::Document.new}
464
+ flexmock(@docs[0]).should_receive(:document_name).and_return 'doc0'
465
+ flexmock(@docs[2]).should_receive(:document_name).and_return 'doc2'
466
+ @list = create_list @docs
391
467
  end
392
468
 
393
- it 'should remove the closed file from the list, without leaving a hole' do
394
- docs = 3.times.map{ @keeper.new_document}
395
- docs[1].close false
396
- @keeper.size.should == docs.size - 1
397
- @keeper[0].should == docs[0]
398
- @keeper[1].should == docs[2]
399
- @keeper.to_a.should == @keeper.to_a.compact
469
+ it 'returns true if there\'s a document with the given name' do
470
+ @list.document_with_name?('doc0').should == true
400
471
  end
401
-
472
+
473
+ it 'returns false if there\'s no document associated with the given URL' do
474
+ @list.document_with_name?('doc3').should == false
475
+ end
476
+
402
477
  end
403
-
404
- describe 'Ruber::DocumentList#new_document' do
478
+
479
+ describe 'Ruber::Document#documents_with_file' do
405
480
 
406
- it 'should create and return a new empty document' do
407
- doc = @keeper.new_document
408
- doc.should be_kind_of(Ruber::Document)
409
- doc.should be_pristine
481
+ before do
482
+ @all_docs = []
483
+ @empty_docs = []
484
+ @local_docs = []
485
+ @remote_docs = []
486
+ @empty_docs << Ruber::Document.new << Ruber::Document.new
487
+ @local_docs << Ruber::Document.new(__FILE__) << Ruber::Document.new( File.join(File.dirname(__FILE__), 'common.rb'))
488
+ @remote_docs << Ruber::Document.new( KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/ruber.gemspec')) << Ruber::Document.new(
489
+ KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/bin/ruber'))
490
+ @all_docs << @empty_docs[0] << @local_docs[0] << @remote_docs[0] << @remote_docs[1] << @local_docs[1] << @empty_docs[1]
491
+ @list = create_list @all_docs
410
492
  end
411
493
 
412
- it 'should add the new document to the list' do
413
- doc = @keeper.new_document
414
- @keeper.documents.should == [doc]
494
+ it 'returns an array containing only the documents associated with local files if called with the :local argument' do
495
+ @list.documents_with_file(:local).should == @local_docs
415
496
  end
416
497
 
417
- it 'should connect the "closing(QObject*)" signal of the document to the "close_document(QObject*) slot' do
418
- doc = Ruber::Document.new
419
- flexmock(Ruber::Document).should_receive(:new).with(@mw).once.and_return(doc)
420
- flexmock(@keeper).should_receive(:close_document).once
421
- @keeper.new_document
422
- doc.close
498
+ it 'returns an array containing only the documents associated with remote files if called with the :remote argument' do
499
+ @list.documents_with_file(:remote).should == @remote_docs
423
500
  end
424
501
 
425
- it 'should emit the "document_created(QObject*)" signal passing the document as argument' do
426
- doc = Ruber::Document.new
427
- exp = doc.object_id
428
- flexmock(Ruber::Document).should_receive(:new).with(@mw).once.and_return(doc)
429
- m = flexmock{|mk| mk.should_receive(:document_created).with(exp).once}
430
- @keeper.connect(SIGNAL('document_created(QObject*)')){|d| m.document_created d.object_id}
431
- @keeper.new_document
502
+ it 'returns an array containing the documents associated with any file when called with the :any argument' do
503
+ @list.documents_with_file(:any).should == [@local_docs[0], @remote_docs[0], @remote_docs[1], @local_docs[1]]
504
+ end
505
+
506
+ it 'returns an array containing the documents associated with any file when called with no arguments' do
507
+ @list.documents_with_file.should == [@local_docs[0], @remote_docs[0], @remote_docs[1], @local_docs[1]]
432
508
  end
433
509
 
434
510
  end
511
+
512
+ end
435
513
 
436
- describe '#document' do
437
-
438
- context 'when a document for the given file or url already exists' do
514
+ describe Ruber::World::MutableDocumentList do
515
+
516
+ before do
517
+ @list = Ruber::World::MutableDocumentList.new
518
+ end
519
+
520
+ it 'inherits from Ruber::World::DocumentList' do
521
+ Ruber::World::DocumentList.ancestors.should include(Ruber::World::DocumentList)
522
+ end
439
523
 
440
- it 'doesn\'t create a new document but return the existing one if a document for the given file or url already exists in the list' do
441
- url = KDE::Url.new 'http://github.com/stcrocco/ruber/raw/ruber.gemspec'
442
- doc1 = Ruber::Document.new nil, __FILE__
443
- doc2 = Ruber::Document.new nil, url
444
- @keeper.add_document doc1
445
- @keeper.add_document doc2
446
- flexmock(Ruber::Document).should_receive(:new).never
447
- @keeper.document(__FILE__).should equal(doc1)
448
- #Since the tests are run from the top directory, we need to prepend the spec directory
449
- @keeper.document(File.expand_path(File.join('spec', File.basename(__FILE__)))).should equal(doc1)
450
- @keeper.document(url).should equal(doc2)
524
+ describe '#initialize' do
525
+
526
+ context 'when called with no arguments' do
527
+
528
+ it 'creates an empty list' do
529
+ @list.should be_empty
451
530
  end
452
531
 
453
532
  end
454
533
 
455
- context 'when a document for the given file or url doesn\'t exist' do
534
+ context 'when called with an array as argument' do
456
535
 
457
- context 'and the second argument is false' do
458
-
459
- it 'returns nil' do
460
- @keeper.document( File.expand_path(__FILE__), false).should be_nil
461
- @keeper.document(KDE::Url.new('http://github.com/stcrocco/ruber/raw/ruber.gemspec'), false).should be_nil
462
- @keeper.documents.should == []
463
- end
464
-
536
+ it 'creates a list containing the same documents as the argument' do
537
+ docs = 3.times.map{Ruber::Document.new}
538
+ @list = Ruber::World::MutableDocumentList.new docs
539
+ @list.to_a.should == docs
465
540
  end
466
541
 
467
- context 'and the second argument is true' do
468
-
469
- it 'creates a new document for the given file or url' do
470
- url = KDE::Url.new 'http://github.com/stcrocco/ruber/raw/ruber.gemspec'
471
- doc = @keeper.document __FILE__
472
- doc.should be_kind_of( Ruber::Document)
473
- doc.path.should == __FILE__
474
- doc.text.should == File.read( __FILE__)
475
- doc = @keeper.document url
476
- doc.url.should == url
477
- end
478
-
479
- it 'raises ArgumentError if the argument is a string or local url and the corresponding file doesn\'t exist' do
480
- lambda{@keeper.document 'test'}.should raise_error(ArgumentError, "File #{File.expand_path 'test'} doesn't exist")
481
- lambda{@keeper.document File.expand_path('test')}.should raise_error(ArgumentError, "File #{File.expand_path 'test'} doesn't exist")
482
- lambda{@keeper.document KDE::Url.new('file:///test')}.should raise_error(ArgumentError, "File #{'/test'} doesn't exist")
483
- end
484
-
485
- it 'doesn\'t raise ArgumentError if the argument is a remote url which doesn\'t exist' do
486
- lambda{@keeper.document KDE::Url.new('http://xyz/abc.def')}.should_not raise_error
487
- end
488
-
489
- it 'adds the new document to the list of documents' do
490
- doc = @keeper.document __FILE__
491
- @keeper.documents.size.should == 1
492
- @keeper.documents.include?(doc).should be_true
493
- end
494
-
495
- it 'connects the "closing(QObject*)" signal of the new document to the "close_document(QObject*) slot' do
496
- file = File.expand_path(__FILE__)
497
- doc = Ruber::Document.new @keeper, file
498
- flexmock(Ruber::Document).should_receive(:new).with(@mw, file).once.and_return(doc)
499
- flexmock(@keeper).should_receive(:close_document).once
500
- @keeper.document __FILE__
501
- doc.close
502
- end
503
-
504
- it 'emits the "document_created(QObject*)" signal passing the new document as argument' do
505
- file = File.expand_path(__FILE__)
506
- doc = Ruber::Document.new nil, file
507
- exp = doc.object_id
508
- flexmock(Ruber::Document).should_receive(:new).with(@mw, file).once.and_return(doc)
509
- m = flexmock{|mk| mk.should_receive(:document_created).with(exp).once}
510
- @keeper.connect(SIGNAL('document_created(QObject*)')){|d| m.document_created d.object_id}
511
- @keeper.document __FILE__
512
- end
513
-
542
+ it 'creates a duplicate of the argument' do
543
+ docs = 3.times.map{Ruber::Document.new}
544
+ @list = Ruber::World::MutableDocumentList.new docs
545
+ new_doc = Ruber::Document.new
546
+ @list.add new_doc
547
+ docs.size.should == 3
514
548
  end
515
549
 
516
550
  end
517
551
 
518
- it 'expands the given file name relative to the current directory if the file name is relative' do
519
- flexmock(Ruber::Document).should_receive(:new).with(@mw, File.expand_path(__FILE__))
520
- doc = @keeper.document __FILE__
521
- # this is necessary because otherwise the 'after' block fails (because the document list contains nil)
522
- @keeper.instance_variable_get(:@docs).clear
552
+ context 'when called with a DocumentList as argument' do
553
+
554
+ it 'creates a list containing the same documents as the argument' do
555
+ docs = 3.times.map{Ruber::Document.new}
556
+ orig = Ruber::World::MutableDocumentList.new docs
557
+ @list = Ruber::World::MutableDocumentList.new orig
558
+ @list.to_a.should == docs
559
+ end
560
+
561
+ it 'creates a duplicate of the argument' do
562
+ docs = 3.times.map{Ruber::Document.new}
563
+ orig = Ruber::World::MutableDocumentList.new docs
564
+ @list = Ruber::World::MutableDocumentList.new orig
565
+ new_doc = Ruber::Document.new
566
+ @list.add new_doc
567
+ orig.size.should == 3
568
+ end
569
+
523
570
  end
524
571
 
525
- it 'treats strings containing URLs as URLs rather than as relative files' do
526
- url_str = 'http://xyz/abc.rb'
527
- flexmock(Ruber::Document).should_receive(:new).with(@mw, KDE::Url.new(url_str))
528
- doc = @keeper.document url_str
529
- # this is necessary because otherwise the 'after' block fails (because the document list contains nil)
530
- @keeper.instance_variable_get(:@docs).clear
572
+ end
573
+
574
+ describe '#dup' do
575
+
576
+ it 'duplicates the document list' do
577
+ docs = 3.times.map{Ruber::Document.new}
578
+ @list.add docs
579
+ new_list = @list.dup
580
+ new_list.remove docs[1]
581
+ @list.should == docs
531
582
  end
532
-
583
+
533
584
  end
534
-
535
- describe '#add_document' do
585
+
586
+ describe '#clone' do
536
587
 
537
- it 'adds the given document to the list of documents' do
538
- doc = Ruber::Document.new
539
- @keeper.add_document doc
540
- @keeper.documents.size.should == 1
541
- @keeper.documents.include?(doc).should be_true
588
+ it 'duplicates the document list' do
589
+ docs = 3.times.map{Ruber::Document.new}
590
+ @list.add docs
591
+ new_list = @list.clone
592
+ new_list.remove docs[1]
593
+ @list.should == docs
542
594
  end
543
595
 
544
- it 'connects the "closing(QObject*)" signal of the given document to the "close_document(QObject*) slot' do
545
- file = File.expand_path(__FILE__)
546
- doc = Ruber::Document.new @keeper, file
547
- flexmock(@keeper).should_receive(:close_document).once
548
- @keeper.add_document doc
549
- doc.close
596
+ it 'copies the frozen status of the document list' do
597
+ docs = 3.times.map{Ruber::Document.new}
598
+ @list.add docs
599
+ @list.freeze
600
+ new_list = @list.clone
601
+ new_list.should be_frozen
602
+ lambda{new_list.add Ruber::Document.new}.should raise_error(RuntimeError)
550
603
  end
551
604
 
552
605
  end
553
-
554
- describe '#save_documents' do
606
+
607
+ describe '#add' do
608
+
609
+ before do
610
+ @docs = 3.times.map{Ruber::Document.new}
611
+ end
612
+
613
+ it 'appends the given documents to the list' do
614
+ @list.add @docs[0]
615
+ @list.to_a.should == [@docs[0]]
616
+ @list.add *@docs[1..-1]
617
+ @list.to_a.should == @docs
618
+ end
619
+
620
+ it 'treats arrays of documents as if each document was an argument by itself' do
621
+ @list.add @docs
622
+ @list.to_a.should == @docs
623
+ end
624
+
625
+ it 'returns self' do
626
+ @list.add(@docs).should equal(@list)
627
+ end
628
+
629
+ end
630
+
631
+ describe '#uniq!' do
632
+
633
+ it 'removes all duplicate elements from the list' do
634
+ docs = [Ruber::Document.new, Ruber::Document.new(__FILE__)]
635
+ @list.add docs
636
+ @list.add docs[0]
637
+ @list.uniq!
638
+ @list.should == docs
639
+ end
640
+
641
+ it 'returns self' do
642
+ @list.uniq!.should == @list
643
+ end
644
+
645
+ end
646
+
647
+ describe '#merge!' do
555
648
 
556
649
  before do
557
- @docs = [@keeper.document(__FILE__), @keeper.new_document, @keeper.new_document]
650
+ @docs = 5.times.map{Ruber::Document.new}
651
+ @list.add @docs[3..4]
558
652
  end
559
653
 
560
- it 'saves all the documents passed as argument' do
561
- @docs.each{|d| flexmock(d).should_receive(:save).once}
562
- @keeper.save_documents @docs
654
+ it 'adds the contents of the argument to self' do
655
+ other = Ruber::World::MutableDocumentList.new @docs[0..2]
656
+ @list.merge!(other).should == @docs[3..4]+@docs[0..2]
563
657
  end
564
658
 
565
- it 'returns an empty array if all the documents were saved successfully' do
566
- @docs.each{|d| flexmock(d).should_receive(:save).once.and_return true}
567
- @keeper.save_documents( @docs).should == []
659
+ it 'also works with an array argument' do
660
+ @list.merge!(@docs[0..2]).should == @docs[3..4]+@docs[0..2]
568
661
  end
569
662
 
570
- it 'returns an array containing the documents for which save returned false, if the second argument is false' do
571
- flexmock(@docs[0]).should_receive(:save).once.and_return true
572
- flexmock(@docs[2]).should_receive(:save).once.and_return true
573
- flexmock(@docs[1]).should_receive(:save).once.and_return false
574
- @keeper.save_documents( @docs, false).should == [@docs[1]]
663
+ it 'returns self' do
664
+ @list.merge!(@docs[0..2]).should equal(@list)
575
665
  end
576
666
 
577
- it 'doesn\'t call the save method on all remaining documents if one fails, if the second argument is true' do
578
- flexmock(@docs[0]).should_receive(:save).once.and_return true
579
- flexmock(@docs[1]).should_receive(:save).once.and_return false
580
- flexmock(@docs[2]).should_receive(:save).never
581
- @keeper.save_documents( @docs, true)
667
+ it 'removes duplicate elements from the list if the second parameter is true' do
668
+ @list.merge!(@docs[0..3], true).should == @docs[3..4]+@docs[0..2]
582
669
  end
583
670
 
584
- it 'returns an array containing the first document for which save returned false and all the documents which weren\'t saved if the second argument is true' do
585
- flexmock(@docs[0]).should_receive(:save).once.and_return true
586
- flexmock(@docs[1]).should_receive(:save).once.and_return false
587
- flexmock(@docs[2]).should_receive(:save).never
588
- @keeper.save_documents( @docs, true).should == @docs[1..-1]
671
+ it 'doesn\'t remove duplicate elements from the list if the second parameter is false' do
672
+ @list.merge!(@docs[0..3], false).should == @docs[3..4]+@docs[0..3]
589
673
  end
590
674
 
591
675
  end
592
676
 
593
- describe '#save_settings' do
677
+ describe '#remove' do
678
+
679
+ before do
680
+ @docs = 3.times.map{Ruber::Document.new}
681
+ @list.add @docs
682
+ end
683
+
684
+ it 'removes the document from the list' do
685
+ @list.remove @docs[1]
686
+ @list.to_a.should == [@docs[0], @docs[2]]
687
+ end
688
+
689
+ it 'does nothing if the document is not in the list' do
690
+ @list.remove Ruber::Document.new
691
+ @list.to_a.should == @docs
692
+ end
693
+
694
+ it 'returns the removed document, if any' do
695
+ @list.remove(@docs[1]).should == @docs[1]
696
+ end
697
+
698
+ it 'returns nil if no document was removed' do
699
+ @list.remove(Ruber::Document.new).should be_nil
700
+ end
701
+
702
+ end
594
703
 
595
- it 'calls the save_settings method of each document\'s own project' do
596
- docs = [@keeper.document(__FILE__), @keeper.new_document, @keeper.new_document]
597
- docs.each{|d| flexmock(d).should_receive(:save_settings).once}
598
- @keeper.save_settings
704
+ describe '#clear' do
705
+
706
+ it 'removes all elements from the list' do
707
+ @list.add 3.times.map{Ruber::Document.new}
708
+ @list.clear
709
+ @list.should be_empty
710
+ end
711
+
712
+ it 'returns self' do
713
+ @list.clear.should equal(@list)
599
714
  end
600
715
 
601
716
  end
602
717
 
603
- describe '#query_close' do
718
+ describe '#delete_if' do
604
719
 
605
720
  before do
606
- @docs = [@keeper.document(__FILE__), @keeper.new_document, @keeper.new_document]
721
+ @docs = [Ruber::Document.new, Ruber::Document.new(__FILE__), Ruber::Document.new]
722
+ @list.add @docs
607
723
  end
608
724
 
609
- it 'calls the query_close method of each document\'s own project and returns false if one of them returns false' do
610
- flexmock(@docs[0].own_project).should_receive(:query_close).once.and_return true
611
- flexmock(@docs[1].own_project).should_receive(:query_close).once.and_return false
612
- flexmock(@docs[2].own_project).should_receive(:query_close).never.and_return(true)
613
- @keeper.query_close.should be_false
725
+ it 'removes all the elements for which the block returns true' do
726
+ @list.delete_if{|doc| !doc.has_file?}
727
+ @list.should == [@docs[1]]
614
728
  end
615
729
 
616
- it 'calls the main window\'s close_documents method and return its value' do
617
- @docs.each{|d| flexmock(d.own_project).should_receive(:query_close).twice.and_return true}
618
- flexmock(@mw).should_receive(:save_documents).once.with_no_args.and_return true
619
- flexmock(@mw).should_receive(:save_documents).once.with_no_args.and_return false
620
- @keeper.query_close.should be_true
621
- @keeper.query_close.should be_false
730
+ it 'returns self' do
731
+ @list.delete_if{|doc| !doc.has_file?}.should equal(@list)
622
732
  end
623
733
 
624
734
  end