ruber 0.0.5 → 0.0.7

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 (83) hide show
  1. data/CHANGES +25 -0
  2. data/bin/ruber +0 -0
  3. data/data/share/apps/ruber/ruberui.rc +15 -1
  4. data/data/share/icons/{ruber.png → ruber-old.pgn} +0 -0
  5. data/lib/ruber/application/application.rb +216 -73
  6. data/lib/ruber/application/plugin.yaml +2 -2
  7. data/lib/ruber/document_project.rb +25 -5
  8. data/lib/ruber/documents/document_list.rb +11 -15
  9. data/lib/ruber/editor/document.rb +106 -50
  10. data/lib/ruber/editor/editor_view.rb +4 -2
  11. data/lib/ruber/external_program_plugin.rb +8 -0
  12. data/lib/ruber/kde_config_option_backend.rb +12 -4
  13. data/lib/ruber/kde_sugar.rb +35 -1
  14. data/lib/ruber/main_window/choose_plugins_dlg.rb +10 -10
  15. data/lib/ruber/main_window/hint_solver.rb +263 -0
  16. data/lib/ruber/main_window/main_window.rb +462 -206
  17. data/lib/ruber/main_window/main_window_actions.rb +228 -62
  18. data/lib/ruber/main_window/main_window_internal.rb +169 -115
  19. data/lib/ruber/main_window/plugin.yaml +13 -3
  20. data/lib/ruber/main_window/save_modified_files_dlg.rb +1 -1
  21. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +1 -1
  22. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +1 -1
  23. data/lib/ruber/main_window/ui/new_project_widget.rb +1 -1
  24. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +1 -1
  25. data/lib/ruber/main_window/ui/output_color_widget.rb +1 -1
  26. data/lib/ruber/main_window/ui/workspace_settings_widget.rb +51 -0
  27. data/lib/ruber/main_window/ui/workspace_settings_widget.ui +28 -0
  28. data/lib/ruber/main_window/view_manager.rb +418 -0
  29. data/lib/ruber/main_window/workspace.png +0 -0
  30. data/lib/ruber/output_widget.rb +43 -37
  31. data/lib/ruber/pane.rb +621 -0
  32. data/lib/ruber/plugin_specification_reader.rb +8 -1
  33. data/lib/ruber/projects/project_files_list.rb +6 -0
  34. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +1 -1
  35. data/lib/ruber/projects/ui/project_files_widget.rb +1 -1
  36. data/lib/ruber/qt_sugar.rb +94 -4
  37. data/lib/ruber/utils.rb +16 -7
  38. data/lib/ruber/version.rb +2 -2
  39. data/plugins/autosave/autosave.rb +62 -1
  40. data/plugins/autosave/plugin.yaml +1 -0
  41. data/plugins/autosave/ui/autosave_config_widget.rb +37 -14
  42. data/plugins/autosave/ui/autosave_config_widget.ui +62 -12
  43. data/plugins/find_in_files/find_in_files_widgets.rb +1 -3
  44. data/plugins/find_in_files/ui/config_widget.rb +1 -1
  45. data/plugins/find_in_files/ui/find_in_files_widget.rb +1 -1
  46. data/plugins/rake/plugin.yaml +1 -1
  47. data/plugins/rake/ui/add_quick_task_widget.rb +1 -1
  48. data/plugins/rake/ui/choose_task_widget.rb +1 -1
  49. data/plugins/rake/ui/config_widget.rb +1 -1
  50. data/plugins/rake/ui/project_widget.rb +1 -1
  51. data/plugins/rspec/rspec.rb +14 -22
  52. data/plugins/rspec/ruber_rspec_formatter.rb +4 -1
  53. data/plugins/rspec/ui/rspec_project_widget.rb +1 -1
  54. data/plugins/ruby_development/plugin.yaml +7 -2
  55. data/plugins/ruby_development/ruby_development.rb +134 -13
  56. data/plugins/ruby_development/ui/config_widget.rb +66 -0
  57. data/plugins/ruby_development/ui/config_widget.ui +58 -0
  58. data/plugins/ruby_development/ui/project_widget.rb +1 -1
  59. data/plugins/ruby_runner/plugin.yaml +2 -2
  60. data/plugins/ruby_runner/ruby_runner.rb +15 -3
  61. data/plugins/ruby_runner/ui/config_widget.rb +1 -1
  62. data/plugins/ruby_runner/ui/project_widget.rb +1 -1
  63. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +1 -1
  64. data/plugins/state/plugin.yaml +6 -2
  65. data/plugins/state/state.rb +305 -81
  66. data/plugins/state/ui/config_widget.rb +1 -1
  67. data/spec/common.rb +11 -3
  68. data/spec/document_list_spec.rb +8 -8
  69. data/spec/document_project_spec.rb +98 -25
  70. data/spec/document_spec.rb +178 -152
  71. data/spec/editor_view_spec.rb +26 -5
  72. data/spec/framework.rb +5 -0
  73. data/spec/hint_solver_spec.rb +450 -0
  74. data/spec/kde_sugar_spec.rb +73 -6
  75. data/spec/output_widget_spec.rb +172 -156
  76. data/spec/pane_spec.rb +1165 -0
  77. data/spec/plugin_specification_reader_spec.rb +37 -1
  78. data/spec/project_files_list_spec.rb +30 -20
  79. data/spec/qt_sugar_spec.rb +269 -0
  80. data/spec/state_spec.rb +566 -353
  81. data/spec/utils_spec.rb +1 -1
  82. data/spec/view_manager_spec.rb +71 -0
  83. metadata +16 -4
@@ -1,7 +1,7 @@
1
1
  =begin
2
2
  ** Form generated from reading ui file 'config_widget.ui'
3
3
  **
4
- ** Created: ven ott 29 17:39:04 2010
4
+ ** Created: mar nov 16 11:52:49 2010
5
5
  ** by: Qt User Interface Compiler version 4.7.0
6
6
  **
7
7
  ** WARNING! All changes made in this file will be lost when recompiling ui file!
@@ -2,6 +2,7 @@ require 'fileutils'
2
2
  require 'yaml'
3
3
  require 'flexmock/argument_types'
4
4
  require 'korundum4'
5
+ # require 'ktexteditor'
5
6
  require 'kio'
6
7
  require 'ostruct'
7
8
  require 'facets/kernel/require_relative'
@@ -97,11 +98,11 @@ RSPEC::Matchers.define :have_entries do |hash|
97
98
  match do |obj|
98
99
  if obj.respond_to? :[]
99
100
  hash.each_pair do |k, v|
100
- return false unless obj[k] == v
101
+ break false unless obj[k] == v
101
102
  end
102
103
  else
103
104
  hash.each_pair do |k, v|
104
- return false unless obj.send(k) == v
105
+ break false unless obj.send(k) == v
105
106
  end
106
107
  end
107
108
  end
@@ -114,6 +115,13 @@ end
114
115
 
115
116
  data = KDE::AboutData.new "test", "", KDE::ki18n("test"), "0.0.0"
116
117
  KDE::CmdLineArgs.init [], data
117
- KDE::Application.new
118
+ opts = KDE::CmdLineOptions.new
119
+ opts.add("+[FILES]", KDE.ki18n("Open FILES. Files with extension .krprj will "\
120
+ "be opened as projects. Only the more recent "\
121
+ "project will be used"))
122
+ KDE::CmdLineArgs.add_cmd_line_options opts
123
+ if defined? init_ruber_core then init_ruber_core
124
+ else KDE::Application.new
125
+ end
118
126
  at_exit{Qt::Internal.application_terminated = true}
119
127
  GC.disable
@@ -511,14 +511,6 @@ describe Ruber::DocumentList do
511
511
  @keeper.document __FILE__
512
512
  end
513
513
 
514
- it 'closes the already-existing document when called with a path and the only existing document is pristine' do
515
- old = @keeper.new_document
516
- Qt::Object.connect old, SIGNAL('closing(QObject*)'), @keeper, SLOT('close_document(QObject*)')
517
- doc = @keeper.document __FILE__
518
- @keeper[0].should == doc
519
- @keeper.size.should == 1
520
- end
521
-
522
514
  end
523
515
 
524
516
  end
@@ -529,6 +521,14 @@ describe Ruber::DocumentList do
529
521
  # this is necessary because otherwise the 'after' block fails (because the document list contains nil)
530
522
  @keeper.instance_variable_get(:@docs).clear
531
523
  end
524
+
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
531
+ end
532
532
 
533
533
  end
534
534
 
@@ -194,12 +194,24 @@ describe Ruber::DocumentProject do
194
194
  Ruber::DocumentProject.ancestors.should include(Ruber::AbstractProject)
195
195
  end
196
196
 
197
- def create_doc path
197
+ def create_doc url, path = nil
198
198
  doc = Qt::Object.new
199
199
  class << doc
200
200
  attr_accessor :path
201
+ attr_reader :url
202
+
203
+ def has_file?
204
+ !path.empty?
205
+ end
206
+
207
+ def url= url
208
+ @url = KDE::Url.new url
209
+ @path = @url.empty? ? '' : @url.path
210
+ end
211
+
201
212
  end
202
- doc.path = path
213
+ doc.url = url
214
+ doc.path = path if path
203
215
  doc
204
216
  end
205
217
 
@@ -223,29 +235,61 @@ describe Ruber::DocumentProject do
223
235
  prj.parent.should equal(doc)
224
236
  end
225
237
 
226
- it 'uses Ruber::DocumentProject::Backend as backend and the file associated with the document as project name, if needed' do
238
+ it 'uses Ruber::DocumentProject::Backend as backend' do
227
239
  doc = create_doc __FILE__
228
240
  prj = Ruber::DocumentProject.new doc
229
241
  prj.instance_variable_get(:@backend).should be_a(Ruber::DocumentProject::Backend)
230
- prj.project_name.should == __FILE__
231
- file = '/home/stefano/xyz/document_project_spec_data_.rb'
232
- md5 = Digest::MD5.new
233
- md5 << file
234
- data_path = File.join ENV['HOME'], '.kde4/share/apps/test/documents', md5.hexdigest
235
- File.open(data_path, 'w'){|f| YAML.dump( {:general => {:project_name => file}}, f)}
236
- doc = create_doc file
237
- prj = Ruber::DocumentProject.new doc
238
- prj.project_name.should == file
239
- FileUtils.rm_rf data_path
240
242
  end
241
243
 
242
- it 'doesn\'t raise an error if the document isn\'t associated with a file' do
243
- doc = create_doc ''
244
- prj = nil
245
- lambda{prj = Ruber::DocumentProject.new doc}.should_not raise_error
246
- prj.project_name.should be_empty
244
+ context 'if the document is associated with a file' do
245
+
246
+ before do
247
+ @dir = File.dirname(__FILE__)
248
+ @file = File.join @dir, 'x y ^ z'
249
+ @encoded_url = "file://#{@dir}/x%20y%20%5E%20z"
250
+ end
251
+
252
+ it 'uses an encoded form of the document\'s URL as project name' do
253
+ doc = create_doc @file
254
+ prj = Ruber::DocumentProject.new doc
255
+ prj.project_name.should == @encoded_url
256
+ end
257
+
258
+ it 'passes the project name as argument to the backend' do
259
+ back = Ruber::DocumentProject::Backend.new @encoded_url
260
+ doc = create_doc @file
261
+ #twice because korundum executes the code before the initialize body twice,
262
+ #until the call to super
263
+ flexmock(Ruber::DocumentProject::Backend).should_receive(:new).twice.with(@encoded_url).and_return back
264
+ prj = Ruber::DocumentProject.new doc
265
+ end
266
+
247
267
  end
248
268
 
269
+ context 'if the document is not associated with a file' do
270
+
271
+ it 'uses an empty string as project name' do
272
+ doc = create_doc ''
273
+ prj = Ruber::DocumentProject.new doc
274
+ prj.project_name.should == ''
275
+ end
276
+
277
+ it 'passes an empty string as argument to the backend' do
278
+ back = Ruber::DocumentProject::Backend.new ''
279
+ doc = create_doc ''
280
+ #twice because korundum executes the code before the initialize body twice,
281
+ #until the call to super
282
+ flexmock(Ruber::DocumentProject::Backend).should_receive(:new).twice.with('').and_return back
283
+ prj = Ruber::DocumentProject.new doc
284
+ end
285
+
286
+ it 'doesn\'t raise an error if the document isn\'t associated with a file' do
287
+ doc = create_doc ''
288
+ lambda{Ruber::DocumentProject.new doc}.should_not raise_error
289
+ end
290
+
291
+ end
292
+
249
293
  it 'connects the document\s "document_url_changed(QObject*)" signal with its "change_file()" slot' do
250
294
  doc = create_doc File.join(ENV['HOME'], 'test.rb')
251
295
  prj = Ruber::DocumentProject.new doc
@@ -269,7 +313,7 @@ describe Ruber::DocumentProject do
269
313
  it 'returns false if the rule\'s scope doesn\'t include :document' do
270
314
  doc = create_doc __FILE__
271
315
  prj = Ruber::DocumentProject.new doc
272
- o1 = OS.new(:file_extension => [], :scope => [:global], :mimetype => [])
316
+ o1 = OS.new(:file_extension => [], :scope => [:global], :mimetype => [], :place => [:local])
273
317
  flexmock(doc).should_receive(:file_type_match?).with([], []).and_return true
274
318
  prj.match_rule?(o1).should be_false
275
319
  end
@@ -277,17 +321,38 @@ describe Ruber::DocumentProject do
277
321
  it 'returns false if the document\'s file_type_match? method returns false' do
278
322
  doc = create_doc __FILE__
279
323
  prj = Ruber::DocumentProject.new doc
280
- o1 = OS.new(:file_extension => ['*.rb'], :scope => [:document], :mimetype => [])
324
+ o1 = OS.new(:file_extension => ['*.rb'], :scope => [:document], :mimetype => [], :place => [:local])
281
325
  flexmock(doc).should_receive(:file_type_match?).once.with([], ['*.rb']).and_return false
282
326
  prj.match_rule?(o1).should be_false
283
327
  end
284
328
 
329
+ it 'returns false if the document is associated with a remote file and the rule\'s place entry doesn\'t include :remote' do
330
+ doc = create_doc 'http:///xyz/abc.rb'
331
+ prj = Ruber::DocumentProject.new doc
332
+ o1 = OS.new(:file_extension => [], :scope => [:document], :mimetype => [], :place => [:local])
333
+ flexmock(doc).should_receive(:file_type_match?).with([], []).and_return true
334
+ prj.match_rule?(o1).should be_false
335
+ end
336
+
337
+ it 'returns false if the document is associated with a local file and the rule\'s place entry doesn\'t include :local' do
338
+ doc = create_doc __FILE__
339
+ prj = Ruber::DocumentProject.new doc
340
+ o1 = OS.new(:file_extension => [], :scope => [:document], :mimetype => [], :place => [:remote])
341
+ flexmock(doc).should_receive(:file_type_match?).with([], []).and_return true
342
+ prj.match_rule?(o1).should be_false
343
+ end
344
+
285
345
  it 'returns true if both the mimetype and the file extension of the rule match those of the document and the rule\'s scope include :document' do
286
346
  doc = create_doc __FILE__
287
347
  prj = Ruber::DocumentProject.new doc
288
- o1 = OS.new(:file_extension => ['*.rb'], :scope => [:document], :mimetype => [])
348
+ o1 = OS.new(:file_extension => ['*.rb'], :scope => [:document], :mimetype => [], :place => [:local])
289
349
  flexmock(doc).should_receive(:file_type_match?).once.with([], ['*.rb']).and_return true
290
350
  prj.match_rule?(o1).should be_true
351
+ doc = create_doc 'http:///xyz/abc.rb'
352
+ prj = Ruber::DocumentProject.new doc
353
+ o2 = OS.new(:file_extension => ['*.rb'], :scope => [:document], :mimetype => [], :place => [:remote])
354
+ flexmock(doc).should_receive(:file_type_match?).once.with([], ['*.rb']).and_return true
355
+ prj.match_rule?(o2).should be_true
291
356
  end
292
357
 
293
358
  end
@@ -295,12 +360,14 @@ describe Ruber::DocumentProject do
295
360
  describe '#change_file' do
296
361
 
297
362
  it 'changes the filename associated with the backend' do
298
- file = File.join ENV['HOME'], 'test.rb'
299
- new_file = File.join ENV['HOME'], 'test.rb1'
363
+ dir = File.join '/', 'home', 'user'
364
+ file = File.join dir, 'test.rb'
365
+ new_file = File.join dir, 'nuovo test.rb'
366
+ enc_url = 'file://' + File.join(dir, 'nuovo%20test.rb')
300
367
  doc = create_doc file
301
368
  prj = Ruber::DocumentProject.new doc
302
- flexmock(prj.instance_variable_get(:@backend)).should_receive(:document_path=).once.with new_file
303
- doc.path = new_file
369
+ flexmock(prj.instance_variable_get(:@backend)).should_receive(:document_path=).once.with enc_url
370
+ doc.url = new_file
304
371
  prj.send :change_file
305
372
  end
306
373
 
@@ -362,6 +429,12 @@ describe Ruber::DocumentProject do
362
429
  prj.files.should == [__FILE__]
363
430
  end
364
431
 
432
+ it 'returns the encoded URL if the document is associated with a remote file' do
433
+ doc = create_doc 'http://xyz/a bc.rb'
434
+ prj = Ruber::DocumentProject.new doc
435
+ prj.files.should == ['http://xyz/a%20bc.rb']
436
+ end
437
+
365
438
  it 'returns an empty array if the document isn\'t associated with a path' do
366
439
  doc = create_doc ''
367
440
  prj = Ruber::DocumentProject.new doc
@@ -1,4 +1,4 @@
1
- require 'spec/common'
1
+ require './spec/common'
2
2
 
3
3
  require 'tempfile'
4
4
  require 'fileutils'
@@ -34,7 +34,7 @@ describe Ruber::Document do
34
34
 
35
35
  describe ', when created' do
36
36
 
37
- it 'should load a KTextEditor::Document' do
37
+ it 'loads a KTextEditor::Document' do
38
38
  @doc.instance_variable_get(:@doc).should be_instance_of(KTextEditor::Document)
39
39
  end
40
40
 
@@ -42,11 +42,11 @@ describe Ruber::Document do
42
42
  @doc.interface('annotation_interface').annotation_model.should_not be_nil
43
43
  end
44
44
 
45
- it 'should not have a view' do
46
- @doc.view.should be_nil
45
+ it 'doesn\'t have a view' do
46
+ @doc.views.should be_empty
47
47
  end
48
48
 
49
- it 'should open a given file if new is called with a string or KDE::Url second argument' do
49
+ it 'opens a given file if new is called with a string or KDE::Url second argument' do
50
50
  doc = Ruber::Document.new @app, __FILE__
51
51
  doc.text.should == File.read(__FILE__)
52
52
  doc.url.path.should == __FILE__
@@ -63,22 +63,85 @@ describe Ruber::Document do
63
63
  doc = Ruber::Document.new @app, __FILE__
64
64
  prj = doc.instance_variable_get(:@project)
65
65
  prj.should be_a(Ruber::DocumentProject)
66
- prj.project_name.should == __FILE__
66
+ prj.project_name.should == KDE::Url.new(__FILE__).to_encoded.to_s
67
67
  end
68
68
 
69
-
70
- it 'should not be active' do
69
+ it 'isn\'t active' do
71
70
  doc = Ruber::Document.new @app, __FILE__
72
71
  doc.should_not be_active
73
72
  end
74
73
 
75
74
  end
76
75
 
76
+ describe "#has_file?" do
77
+
78
+ context 'when called with :local' do
79
+
80
+ it 'returns true if the document is associated with a local file' do
81
+ doc = Ruber::Document.new nil, __FILE__
82
+ doc.should have_file(:local)
83
+ end
84
+
85
+ it 'returns false if the document is associated with a remote file' do
86
+ doc = Ruber::Document.new nil, KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/ruber.gemspec')
87
+ doc.should_not have_file(:local)
88
+ end
89
+
90
+ it 'returns false if the document isn\'t associated with any file' do
91
+ doc = Ruber::Document.new
92
+ doc.should_not have_file(:local)
93
+ end
94
+
95
+ end
96
+
97
+ context 'when called with :remote' do
98
+
99
+ it 'returns false if the document is associated with a local file' do
100
+ doc = Ruber::Document.new nil, __FILE__
101
+ doc.should_not have_file(:remote)
102
+ end
103
+
104
+ it 'returns true if the document is associated with a remote file' do
105
+ doc = Ruber::Document.new nil, KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/ruber.gemspec')
106
+ doc.should have_file(:remote)
107
+ end
108
+
109
+ it 'returns false if the document isn\'t associated with any file' do
110
+ doc = Ruber::Document.new
111
+ doc.should_not have_file(:remote)
112
+ end
113
+
114
+ end
115
+
116
+ context 'when called with :any or no arguments' do
117
+
118
+ it 'returns true if the document is associated with a local file' do
119
+ doc = Ruber::Document.new nil, __FILE__
120
+ doc.should have_file(:any)
121
+ doc.should have_file
122
+ end
123
+
124
+ it 'returns true if the document is associated with a remote file' do
125
+ doc = Ruber::Document.new nil, KDE::Url.new('http://github.com/stcrocco/ruber/raw/master/ruber.gemspec')
126
+ doc.should have_file(:any)
127
+ doc.should have_file
128
+ end
129
+
130
+ it 'returns false if the document isn\'t associated with any file' do
131
+ doc = Ruber::Document.new
132
+ doc.should_not have_file(:any)
133
+ doc.should_not have_file
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+
77
140
  describe '#own_project' do
78
141
 
79
142
  it 'returns the DocumentProject associated with the document' do
80
143
  doc = Ruber::Document.new @app, __FILE__
81
- doc.own_project.project_name.should == __FILE__
144
+ doc.own_project.project_name.should == KDE::Url.new(__FILE__).url
82
145
  end
83
146
 
84
147
  end
@@ -94,12 +157,12 @@ describe Ruber::Document do
94
157
  end
95
158
 
96
159
  it 'returns the current project if one exists and the document belongs to it' do
97
- flexmock(@list).should_receive(:file_in_project?).with(__FILE__).and_return true
160
+ flexmock(@list).should_receive(:file_in_project?).with("file://#{__FILE__}").and_return true
98
161
  @doc.project.should == @prj
99
162
  end
100
163
 
101
164
  it 'returns the document project if the file associated with the document doesn\'t belong to the current project' do
102
- flexmock(@list).should_receive(:file_in_project?).with(__FILE__).and_return false
165
+ flexmock(@list).should_receive(:file_in_project?).with("file://#{__FILE__}").and_return false
103
166
  @doc.project.should be_a(Ruber::DocumentProject)
104
167
  end
105
168
 
@@ -122,14 +185,6 @@ describe Ruber::Document do
122
185
  flexmock(@doc).should_receive(:document_save_as).once.and_return(false)
123
186
  @doc.save.should be_true
124
187
  @doc.save.should be_false
125
- # tmp_file = File.join Dir.tmpdir, "ruber_document_test" + 3.times.map{rand(10)}.join.to_s
126
- # flexmock(KDE::FileDialog).should_receive(:get_save_file_name).times(2).and_return(nil, tmp_file)
127
- # @doc.text = 'test'
128
- # @doc.save.should be_false
129
- # @doc.save.should be_true
130
- # File.exists?(tmp_file).should be_true
131
- # File.read(tmp_file).should == 'test'
132
- # FileUtils.rm tmp_file
133
188
  end
134
189
 
135
190
  describe ', when the document is associated with a file' do
@@ -172,35 +227,40 @@ describe Ruber::Document do
172
227
 
173
228
  end
174
229
 
175
- it 'should allow to create a view if none exists' do
176
- @doc.create_view(Qt::Widget.new).should_not be_nil
230
+ it 'allows to create a view if none exists' do
231
+ view = @doc.create_view(Qt::Widget.new)
232
+ view.should be_a(Ruber::EditorView)
233
+ @doc.views[0].should == view
177
234
  end
178
-
179
- it 'should not allow to create a view if one already exists' do
180
- @doc.create_view(Qt::Widget.new)
181
- lambda{@doc.create_view(Qt::Widget.new)}.should raise_error(RuntimeError)
235
+
236
+ it 'allows to create a view if other views already exist' do
237
+ old_view = @doc.create_view
238
+ new_view = @doc.create_view
239
+ @doc.views.should == [old_view, new_view]
182
240
  end
183
241
 
184
- it 'should allow to get and change the text' do
242
+ it 'allows to get and change the text' do
185
243
  txt="test text"
186
244
  lambda{@doc.text="test text"}.should_not raise_error
187
245
  @doc.text.should == txt
188
246
  end
189
247
 
190
- it 'should return the mimetype of the document' do
248
+ it 'returns the mimetype of the document' do
191
249
  @doc.mime_type.should == 'text/plain'
192
250
  @doc.open_url KDE::Url.from_path(__FILE__)
193
251
  @doc.mime_type.should == 'application/x-ruby'
194
252
  end
195
253
 
196
- it 'should return the view attached to it (or nil) with the view method' do
197
- @doc.view.should be_nil
198
- @doc.create_view nil
199
- @doc.view.should be_instance_of Ruber::EditorView
200
- @doc.view.close
254
+ it 'returns a list of the views associated with it' do
255
+ @doc.views.should be_empty
256
+ old_view = @doc.create_view nil
257
+ @doc.views[0].should == old_view
258
+ new_view = @doc.create_view nil
259
+ @doc.views[1].should == new_view
260
+ @doc.views.should == [old_view, new_view]
201
261
  end
202
262
 
203
- it 'should emit the "modified_changed(QObject*, bool)" signal when the modified status changes' do
263
+ it 'emits the "modified_changed(QObject*, bool)" signal when the modified status changes' do
204
264
  m = flexmock
205
265
  m.should_receive(:test).ordered.with(true, @doc)
206
266
  m.should_receive(:test).ordered.with(false, @doc)
@@ -215,9 +275,9 @@ describe Ruber::Document do
215
275
 
216
276
  end
217
277
 
218
- it 'should emit the "document_name_changed(QString, QObject*)" signal when the document name changes' do
278
+ it 'emits the "document_name_changed(QString, QObject*)" signal when the document name changes' do
219
279
  m = flexmock
220
- m.should_receive(:document_name_changed).twice
280
+ m.should_receive(:document_name_changed).once
221
281
  @doc.connect(SIGNAL('document_name_changed(QString, QObject*)')) do |str, obj|
222
282
  obj.should == @doc
223
283
  str.should == @doc.document_name
@@ -226,22 +286,17 @@ describe Ruber::Document do
226
286
  @doc.open_url KDE::Url.from_path( __FILE__)
227
287
  end
228
288
 
229
- it 'should return the path of the file usgin the "path" method or an empty string if the document is not associated with a file' do
289
+ it 'returns the path of the file usgin the "path" method or an empty string if the document is not associated with a file' do
230
290
  @doc.path.should == ''
231
291
  @doc.open_url KDE::Url.from_path( __FILE__ )
232
292
  @doc.path.should == __FILE__
233
293
  end
234
294
 
235
- it 'should return an empty string if the document is empty' do
295
+ it 'returns an empty string if the document is empty' do
236
296
  @doc.text.should_not be_nil
237
297
  end
238
298
 
239
- it 'should tell whether it\'s associated with a file or not' do
240
- @doc.should_not have_file
241
- Ruber::Document.new(nil, __FILE__).should have_file
242
- end
243
-
244
- it 'should tell whether it\'s a pristine document' do
299
+ it 'tells whether it\'s a pristine document' do
245
300
  @doc.should be_pristine
246
301
  @doc.text = "a"
247
302
  @doc.should_not be_pristine
@@ -265,7 +320,7 @@ describe Ruber::Document do
265
320
  sig_name = sig[0...sig.index('(')]
266
321
  o_sig_name = sig_name.camelcase(false)
267
322
  o_sig = sig.camelcase(false).sub('(QObject*','(KTextEditor::Document*')
268
- it "should emit the \"#{sig}\" signal in response to the underlying KTextEditor::Document \"#{o_sig}\" signal" do
323
+ it "emits the \"#{sig}\" signal in response to the underlying KTextEditor::Document \"#{o_sig}\" signal" do
269
324
  m = flexmock
270
325
  m.should_receive( sig_name.to_sym).once.with(@doc.object_id)
271
326
  @doc.connect(SIGNAL(sig)){|o| m.send(sig_name.to_sym, o.object_id)}
@@ -274,21 +329,21 @@ describe Ruber::Document do
274
329
  end
275
330
  end
276
331
 
277
- it 'should emit the "mode_changed(QObject*)" signal in response to the underlying KTextEditor::Document "modeChanged(KTextEditor::Document)" signal' do
332
+ it 'emits the "mode_changed(QObject*)" signal in response to the underlying KTextEditor::Document "modeChanged(KTextEditor::Document)" signal' do
278
333
  m = flexmock
279
334
  m.should_receive( :mode_changed).once.with(@doc.object_id)
280
335
  @doc.connect(SIGNAL('mode_changed(QObject*)')){|o| m.mode_changed o.object_id}
281
336
  @doc.mode = "Ruby"
282
337
  end
283
338
 
284
- it 'should emit the "highlighting_mode_changed(QObject*)" signal in response to the underlying KTextEditor::Document "highlightingModeChanged(KTextEditor::Document)" signal' do
339
+ it 'emits the "highlighting_mode_changed(QObject*)" signal in response to the underlying KTextEditor::Document "highlightingModeChanged(KTextEditor::Document)" signal' do
285
340
  m = flexmock
286
341
  m.should_receive( :h_mode_changed).once.with(@doc.object_id)
287
342
  @doc.connect(SIGNAL('highlighting_mode_changed(QObject*)')){|o| m.h_mode_changed o.object_id}
288
343
  @doc.highlighting_mode = "Ruby"
289
344
  end
290
345
 
291
- it 'should emit the "text_modified(KTextEditor::Range, KTextEditor::Range, QObject*)" signal in response to the underlying KTextEditor::Document "textChanged(KTextEditor::Document*, KTextEditor::Range, KTextEditor::Range)" signal' do
346
+ it 'emits the "text_modified(KTextEditor::Range, KTextEditor::Range, QObject*)" signal in response to the underlying KTextEditor::Document "textChanged(KTextEditor::Document*, KTextEditor::Range, KTextEditor::Range)" signal' do
292
347
  m = flexmock
293
348
  m.should_receive( :text_modified).once.with(@doc.object_id)
294
349
  @doc.connect(SIGNAL('text_modified(KTextEditor::Range, KTextEditor::Range, QObject*)')){|_r1, _r2, o| m.text_modified o.object_id}
@@ -304,7 +359,7 @@ describe Ruber::Document do
304
359
  d.instance_eval{emit textInserted(self, KTextEditor::Range.new(0,0,0,5))}
305
360
  end
306
361
 
307
- it 'should emit the "text_removed(KTextEditor::Range, QObject*)" signal in response to the underlying KTextEditor::Document "textRemoved(KTextEditor::Document*, KTextEditor::Range)" signal' do
362
+ it 'emits the "text_removed(KTextEditor::Range, QObject*)" signal in response to the underlying KTextEditor::Document "textRemoved(KTextEditor::Document*, KTextEditor::Range)" signal' do
308
363
  m = flexmock
309
364
  m.should_receive( :text_removed).once.with(@doc.object_id)
310
365
  @doc.connect(SIGNAL('text_removed(KTextEditor::Range, QObject*)')){|_, o| m.text_removed o.object_id}
@@ -314,19 +369,12 @@ describe Ruber::Document do
314
369
 
315
370
  it 'emits the "view_created(QObject*, QObject*)" signal after creating a view' do
316
371
  m = flexmock
317
- m.should_receive( :view_created).once.with(@doc.object_id)
372
+ m.should_receive(:view_created).once.with(@doc.object_id)
318
373
  @doc.connect(SIGNAL('view_created(QObject*, QObject*)'))do |_, o|
319
374
  m.view_created o.object_id
320
- @doc.view.should be_a(Ruber::EditorView)
375
+ @doc.views[0].should be_a(Ruber::EditorView)
321
376
  end
322
377
  @doc.create_view nil
323
- @doc.view.close
324
- end
325
-
326
- it 'should return nil with the view method when a view has been closed' do
327
- view = @doc.create_view
328
- view.close
329
- @doc.view.should be_nil
330
378
  end
331
379
 
332
380
  it 'should return true when close_url succeeds' do
@@ -334,16 +382,16 @@ describe Ruber::Document do
334
382
  doc.close_url(false).should be_true
335
383
  end
336
384
 
337
- it 'should call the update_project method of each component, passing it its project, when the name of the document changes, but before emitting the document_name_changed signal' do
385
+ it 'should call the update_project method of each component, passing it its project, when the url of the document changes, but before emitting the document_url_changed signal' do
338
386
  3.times{@comp << flexmock{|m| m.should_receive(:update_project).once.with(Ruber::DocumentProject).globally.ordered} }
339
- name_changed_rec = flexmock{|m| m.should_receive(:name_changed).once.globally.ordered}
387
+ url_changed_rec = flexmock{|m| m.should_receive(:url_changed).once.globally.ordered}
340
388
  internal = @doc.send :internal
341
- @doc.connect(SIGNAL('document_name_changed(QString,QObject*)')){name_changed_rec.name_changed}
342
- internal.instance_eval{emit documentNameChanged(self)}
389
+ @doc.connect(SIGNAL('document_url_changed(QObject*)')){url_changed_rec.url_changed}
390
+ internal.instance_eval{emit documentUrlChanged(self)}
343
391
  end
344
392
 
345
393
  after do
346
- @doc.view.close if @doc.view
394
+ @doc.views.each{|v| v.close}
347
395
  @doc.instance_variable_get(:@doc).closeUrl false
348
396
  @doc.dispose
349
397
  end
@@ -361,7 +409,7 @@ describe 'Ruber::Document#close' do
361
409
  flexmock(@doc.instance_variable_get(:@project)).should_receive(:save).by_default
362
410
  end
363
411
 
364
- it 'should return immediately if ask is true and query_close returns false' do
412
+ it 'returns immediately if ask is true and query_close returns false' do
365
413
  doc = Ruber::Document.new nil, __FILE__
366
414
  exp = doc.object_id
367
415
  m = flexmock('test'){|mk| mk.should_receive(:document_closing).never}
@@ -408,12 +456,12 @@ describe 'Ruber::Document#close' do
408
456
  doc.close false
409
457
  end
410
458
 
411
- it 'should close the view, if there\'s one, after emitting the closing signal, if closing is confirmed' do
459
+ it 'closes the views, if any, after emitting the closing signal, if closing is confirmed' do
412
460
  doc = Ruber::Document.new nil, __FILE__
413
- v = doc.create_view
461
+ views = 3.times.map{doc.create_view}
414
462
  exp = doc.object_id
415
463
  m = flexmock('test'){|mk| mk.should_receive(:document_closing).once.with(exp).globally.ordered}
416
- flexmock(v).should_receive(:close).once.globally.ordered
464
+ views.each{|v| flexmock(v).should_receive(:close).once.globally.ordered}
417
465
  flexmock(doc).should_receive(:close_url).and_return true
418
466
  doc.connect(SIGNAL('closing(QObject*)')){|d| m.document_closing d.object_id}
419
467
  flexmock(doc).should_receive(:query_close).and_return true
@@ -456,11 +504,11 @@ end
456
504
  doc.close false
457
505
  end
458
506
 
459
- it 'should dispose of itself after emitting the closing signal, if closing is confirmed' do
460
- doc = Ruber::Document.new nil, __FILE__
461
- doc.close false
462
- doc.should be_disposed
463
- end
507
+ # it 'should dispose of itself after emitting the closing signal, if closing is confirmed' do
508
+ # doc = Ruber::Document.new nil, __FILE__
509
+ # doc.close false
510
+ # doc.should be_disposed
511
+ # end
464
512
 
465
513
  it 'should return true, if closing is confirmed and successful and false otherwise' do
466
514
  doc = Ruber::Document.new nil, __FILE__
@@ -475,27 +523,6 @@ end
475
523
 
476
524
  end
477
525
 
478
- describe 'Ruber::Document#close_view' do
479
-
480
- before do
481
- @app = KDE::Application.instance
482
- @w = Qt::Widget.new
483
- @comp = DocumentSpecComponentManager.new
484
- flexmock(Ruber).should_receive(:[]).with(:components).and_return(@comp)
485
- @doc = Ruber::Document.new @app
486
- @view = @doc.create_view
487
- end
488
-
489
- it 'should call the "close" method' do
490
- flexmock(@doc).should_receive(:close).once.with(true)
491
- flexmock(@doc).should_receive(:close).once.with(false)
492
- @doc.close_view @view, true
493
- @doc.close_view @view, false
494
- end
495
-
496
- end
497
-
498
-
499
526
  describe 'Ruber::Document#extension' do
500
527
 
501
528
  before do
@@ -715,65 +742,64 @@ describe Ruber::Document do
715
742
 
716
743
  end
717
744
 
718
- # describe '#shutdown' do
719
- #
720
- # before do
721
- # @app = KDE::Application.instance
722
- # @w = Qt::Widget.new
723
- # @comp = DocumentSpecComponentManager.new
724
- # flexmock(Ruber).should_receive(:[]).with(:components).and_return(@comp)
725
- # @doc = Ruber::Document.new @app
726
- # end
727
- #
728
- # it 'calls the close_url method passing false' do
729
- # doc = Ruber::Document.new nil, __FILE__
730
- # flexmock(doc).should_receive(:close_url).once.with(false)
731
- # doc.shutdown
732
- # end
733
- #
734
- # it 'emits the "closing(QObject*)" signal' do
735
- # doc = Ruber::Document.new nil, __FILE__
736
- # exp = doc.object_id
737
- # m = flexmock('test'){|mk| mk.should_receive(:document_closing).once.with(exp)}
738
- # doc.connect(SIGNAL('closing(QObject*)')){|d| m.document_closing d.object_id}
739
- # doc.shutdown
740
- # end
741
- #
742
- # it 'closes the view, if there\'s one, after emitting the closing signal' do
743
- # doc = Ruber::Document.new nil, __FILE__
744
- # v = doc.create_view
745
- # exp = doc.object_id
746
- # m = flexmock('test'){|mk| mk.should_receive(:document_closing).once.with(exp).ordered}
747
- # flexmock(v).should_receive(:close).once.globally.ordered
748
- # doc.connect(SIGNAL('closing(QObject*)')){|d| m.document_closing d.object_id}
749
- # doc.shutdown
750
- # end
751
- #
752
- # it 'calls the #shutdown method of the project' do
753
- # doc = Ruber::Document.new nil
754
- # exp = doc.object_id
755
- # flexmock(doc).should_receive(:close_url)
756
- # flexmock(doc.own_project).should_receive(:shutdown).once
757
- # doc.shutdown
758
- # end
759
- #
760
- #
761
- # it 'disconnects any slot/block connected to it after emitting the closing signal' do
762
- # doc = Ruber::Document.new nil, __FILE__
763
- # exp = doc.object_id
764
- # def doc.disconnect *args;end
765
- # m = flexmock{|mk| mk.should_receive(:document_closing).with(exp).once.ordered}
766
- # doc.connect(SIGNAL('closing(QObject*)')){|d| m.document_closing d.object_id}
767
- # flexmock(doc).should_receive(:disconnect).with_no_args.once.ordered
768
- # doc.shutdown
769
- # end
770
- #
771
- # it 'disposes of itself after emitting the closing signal' do
772
- # doc = Ruber::Document.new nil, __FILE__
773
- # doc.shutdown
774
- # doc.should be_disposed
775
- # end
776
- #
777
- # end
745
+ describe 'when a view is closed' do
746
+
747
+ it 'removes the view from the list' do
748
+ doc = Ruber::Document.new nil
749
+ views = 3.times.map{doc.create_view}
750
+ views[1].close
751
+ new_views = doc.views
752
+ new_views.size.should == 2
753
+ new_views.should == [views[0], views[2]]
754
+ end
755
+
756
+ it 'emits the closing_view(QWidget*, QObject*) signal before removing the view from the list' do
757
+ doc = Ruber::Document.new nil
758
+ views = 3.times.map{doc.create_view}
759
+ test = flexmock{|m| m.should_receive(:closing_view).once.with(doc, views[1])}
760
+ doc.connect(SIGNAL('closing_view(QWidget*, QObject*)')) do |v, d|
761
+ test.closing_view d, v
762
+ doc.views.should include(views[1])
763
+ end
764
+ views[1].close
765
+ end
766
+
767
+ end
768
+
769
+ describe '#has_view?' do
770
+
771
+ it 'returns true if there\'s at least one view associated with the document' do
772
+ doc = Ruber::Document.new nil
773
+ doc.create_view
774
+ doc.should have_view
775
+ doc.create_view
776
+ doc.should have_view
777
+ end
778
+
779
+ it 'returns false if there are no views associated with the document' do
780
+ doc = Ruber::Document.new nil
781
+ doc.should_not have_view
782
+ end
783
+
784
+ end
785
+
786
+ describe '#active_view' do
787
+
788
+ it 'returns the active view if any' do
789
+ doc = Ruber::Document.new
790
+ views = 3.times.map{doc.create_view}
791
+ flexmock(doc.send(:internal)).should_receive(:active_view).once.and_return(views[2].send(:internal))
792
+ doc.active_view.should == views[2]
793
+ end
794
+
795
+ it 'returns nil if there isn\'t an active view associated with the document' do
796
+ doc = Ruber::Document.new
797
+ doc.active_view.should be_nil
798
+ views = 3.times.map{doc.create_view}
799
+ flexmock(doc.send(:internal)).should_receive(:active_view).once.and_return(nil)
800
+ doc.active_view.should be_nil
801
+ end
802
+
803
+ end
778
804
 
779
805
  end