ruber 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +21 -0
- data/data/share/apps/ruber/ruberui.rc +3 -1
- data/lib/ruber/application/application.rb +22 -23
- data/lib/ruber/application/plugin.yaml +7 -2
- data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
- data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
- data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
- data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
- data/lib/ruber/application/ui/project_files_widget.rb +117 -0
- data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
- data/lib/ruber/component_manager.rb +14 -9
- data/lib/ruber/editor/document.rb +35 -5
- data/lib/ruber/kde_sugar.rb +16 -0
- data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
- data/lib/ruber/main_window/main_window.rb +131 -193
- data/lib/ruber/main_window/main_window_actions.rb +157 -58
- data/lib/ruber/main_window/main_window_internal.rb +145 -54
- data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
- data/lib/ruber/main_window/plugin.yaml +3 -6
- data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
- data/lib/ruber/main_window/workspace.rb +62 -32
- data/lib/ruber/output_widget.rb +20 -16
- data/lib/ruber/pane.rb +11 -5
- data/lib/ruber/project.rb +27 -12
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
- data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
- data/lib/ruber/utils.rb +37 -4
- data/lib/ruber/version.rb +1 -1
- data/lib/ruber/world/document_factory.rb +121 -0
- data/lib/ruber/world/document_list.rb +396 -0
- data/lib/ruber/world/environment.rb +470 -0
- data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
- data/lib/ruber/world/plugin.yaml +11 -0
- data/lib/ruber/world/project_factory.rb +131 -0
- data/lib/ruber/world/project_list.rb +265 -0
- data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
- data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
- data/lib/ruber/world/world.rb +307 -0
- data/plugins/auto_end/auto_end.rb +135 -9
- data/plugins/autosave/autosave.rb +4 -4
- data/plugins/find_in_files/find_in_files.rb +5 -5
- data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
- data/plugins/project_browser/project_browser.rb +4 -4
- data/plugins/rake/rake.rb +4 -4
- data/plugins/rake/rake_extension.rb +1 -1
- data/plugins/rspec/rspec.rb +4 -4
- data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
- data/plugins/ruby_development/ruby_development.rb +3 -3
- data/plugins/ruby_runner/ruby_runner.rb +2 -2
- data/plugins/state/plugin.yaml +6 -8
- data/plugins/state/state.rb +201 -391
- data/plugins/state/ui/config_widget.rb +5 -5
- data/plugins/state/ui/config_widget.ui +3 -3
- data/plugins/syntax_checker/syntax_checker.rb +4 -0
- data/spec/annotation_model_spec.rb +1 -1
- data/spec/auto_end_spec.rb +98 -47
- data/spec/component_manager_spec.rb +80 -21
- data/spec/document_factory_spec.rb +115 -0
- data/spec/document_list_spec.rb +560 -450
- data/spec/document_spec.rb +143 -55
- data/spec/editor_view_spec.rb +2 -2
- data/spec/environment_spec.rb +1900 -0
- data/spec/hint_solver_spec.rb +5 -5
- data/spec/kde_sugar_spec.rb +16 -0
- data/spec/output_widget_spec.rb +177 -51
- data/spec/pane_spec.rb +29 -5
- data/spec/plugin_spec.rb +1 -1
- data/spec/project_factory_spec.rb +104 -0
- data/spec/project_list_spec.rb +352 -447
- data/spec/project_spec.rb +34 -33
- data/spec/qt_sugar_spec.rb +2 -2
- data/spec/state_spec.rb +508 -811
- data/spec/utils_spec.rb +149 -98
- data/spec/workspace_spec.rb +120 -9
- data/spec/world_spec.rb +1219 -0
- metadata +23 -14
- data/lib/ruber/documents/document_list.rb +0 -412
- data/lib/ruber/documents/plugin.yaml +0 -4
- data/lib/ruber/main_window/view_manager.rb +0 -431
- data/lib/ruber/projects/plugin.yaml +0 -11
- data/lib/ruber/projects/project_list.rb +0 -314
@@ -0,0 +1,1900 @@
|
|
1
|
+
require 'spec/framework'
|
2
|
+
require 'spec/common'
|
3
|
+
|
4
|
+
require 'ruber/world/environment'
|
5
|
+
|
6
|
+
require 'tmpdir'
|
7
|
+
|
8
|
+
describe Ruber::World::Environment do
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
#the following line is only needed until world is added to the list of
|
12
|
+
#components loaded by the application
|
13
|
+
Ruber[:components].load_component 'world' unless Ruber[:world]
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
Ruber[:world].close_all(:documents, :discard)
|
18
|
+
@env = Ruber::World::Environment.new nil
|
19
|
+
#without this, the tab widgets become visible, slowing down tests noticeably
|
20
|
+
flexmock(@env.tab_widget).should_receive(:show).by_default
|
21
|
+
@env.activate
|
22
|
+
end
|
23
|
+
|
24
|
+
after do
|
25
|
+
@env.dispose
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'inherits from Qt::Object' do
|
29
|
+
Ruber::World::Environment.ancestors.should include(Qt::Object)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'includes the Activable module' do
|
33
|
+
Ruber::World::Environment.ancestors.should include(Ruber::Activable)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has a plugin instance method' do
|
37
|
+
Ruber::World::Environment.instance_methods.should include(:plugin)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'has a save_settings method' do
|
41
|
+
Ruber::World::Environment.instance_methods.should include(:save_settings)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has a shutdown method' do
|
45
|
+
Ruber::World::Environment.instance_methods.should include(:shutdown)
|
46
|
+
end
|
47
|
+
|
48
|
+
shared_examples_for 'when adding a view' do
|
49
|
+
|
50
|
+
before do
|
51
|
+
@doc = Ruber[:world].new_document
|
52
|
+
@view = @doc.create_view
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'inserts the view in the list of views contained in the environment' do
|
56
|
+
@add_view_proc.call @view
|
57
|
+
@env.views.should include(@view)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'adds the document to the list of documents associated with the environment' do
|
61
|
+
@add_view_proc.call @view
|
62
|
+
@env.documents.should include(@view.document)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'doesn\'t add the document to the list if the list already includes it' do
|
66
|
+
@env.editor_for! @doc
|
67
|
+
@add_view_proc.call @view
|
68
|
+
@env.documents.select{|doc| doc == @doc}.count.should == 1
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'sets the text of the label associated with the view to the path of the document, if the document is associated with a file' do
|
72
|
+
@doc = Ruber[:world].document __FILE__
|
73
|
+
@view = @doc.create_view
|
74
|
+
@add_view_proc.call @view
|
75
|
+
@view.parent.label.should == @doc.path
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'sets the text of the label associated with the view to the documen name of the document, if the document is associated with a file' do
|
79
|
+
@add_view_proc.call @view
|
80
|
+
@view.parent.label.should == @doc.document_name
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'uses the URL of the document as label for the view if the document is associated with a remote file' do
|
84
|
+
url = KDE::Url.new 'http://xyz.org/abc'
|
85
|
+
flexmock(@doc).should_receive(:url).and_return url
|
86
|
+
@add_view_proc.call @view
|
87
|
+
@view.parent.label.should == @doc.url.pretty_url
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'updates the tool tip of the tab containing the view' do
|
91
|
+
doc = Ruber[:world].new_document
|
92
|
+
@add_view_proc.call @view
|
93
|
+
@env.editor_for! doc, :new => @view
|
94
|
+
exp = @doc.document_name + "\n" + doc.document_name
|
95
|
+
@env.tab_widget.tab_tool_tip(0).should == exp
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'doesn\'t repeat a document multiple times in the tool tip of the tab' do
|
99
|
+
Ruber[:world].close_all :documents, :discard
|
100
|
+
doc = Ruber[:world].new_document
|
101
|
+
view = @env.editor_for! doc, :new => :current_tab
|
102
|
+
@add_view_proc.call @view
|
103
|
+
@env.editor_for! @doc, :existing => :never, :new => :current_tab
|
104
|
+
exp = [doc, @doc].map{|d| d.document_name}.join "\n"
|
105
|
+
@env.tab_widget.tab_tool_tip(0).should == exp
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'reacts to the view getting focus' do
|
109
|
+
@add_view_proc.call @view
|
110
|
+
@view.instance_eval{emit focus_in(self)}
|
111
|
+
@env.active_editor.should == @view
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '.new' do
|
117
|
+
|
118
|
+
context 'when the first argument is a Project' do
|
119
|
+
|
120
|
+
before do
|
121
|
+
@file = File.join Dir.tmpdir, 'environment_new_test'
|
122
|
+
@project = Ruber::Project.new @file, "Environment New Test"
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'makes the new environment child of the second argument' do
|
126
|
+
obj = Qt::Object.new
|
127
|
+
env = Ruber::World::Environment.new @project, obj
|
128
|
+
env.parent.should == obj
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'doesn\'t create empty documents' do
|
132
|
+
env = Ruber::World::Environment.new @project
|
133
|
+
env.views.should be_empty
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when the first argument is nil' do
|
139
|
+
|
140
|
+
it 'makes the new enviroment child of the second argument' do
|
141
|
+
obj = Qt::Object.new
|
142
|
+
env = Ruber::World::Environment.new nil, obj
|
143
|
+
env.parent.should == obj
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'creates an environment having no project associated with it' do
|
147
|
+
env = Ruber::World::Environment.new nil
|
148
|
+
env.project.should be_nil
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'associates a parentless tab widget with the environment' do
|
154
|
+
env = Ruber::World::Environment.new nil
|
155
|
+
env.tab_widget.should be_a(KDE::TabWidget)
|
156
|
+
env.tab_widget.parent.should be_nil
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'swtiches the document mode of the tab widget on' do
|
160
|
+
env = Ruber::World::Environment.new nil
|
161
|
+
env.tab_widget.document_mode.should be_true
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'creates an hint solver' do
|
165
|
+
env = Ruber::World::Environment.new nil
|
166
|
+
hint_solver = env.instance_variable_get(:@hint_solver)
|
167
|
+
hint_solver.should be_a(Ruber::World::HintSolver)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'deactivates the environment' do
|
171
|
+
env = Ruber::World::Environment.new nil
|
172
|
+
env.should_not be_active
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'hides the tab widget' do
|
176
|
+
env = Ruber::World::Environment.new nil
|
177
|
+
env.tab_widget.should be_hidden
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'creates a view for a new, empty document with object name default_document' do
|
181
|
+
env = Ruber::World::Environment.new nil
|
182
|
+
env.views.count.should == 1
|
183
|
+
env.views[0].document.text.should == ''
|
184
|
+
env.views[0].document.object_name.should == 'default_document'
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '#editor_for!' do
|
190
|
+
|
191
|
+
before do
|
192
|
+
@solver = @env.instance_variable_get :@hint_solver
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'uses the Ruber::World::Environment::DEFAULT_HINTS as default hints argument' do
|
196
|
+
doc = Ruber[:world].new_document
|
197
|
+
view = doc.create_view
|
198
|
+
flexmock(@solver).should_receive(:find_editor).with(doc, Ruber::World::Environment::DEFAULT_HINTS).once.and_return(view)
|
199
|
+
@env.editor_for!(doc)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'merges the given hints with the default ones' do
|
203
|
+
doc = Ruber[:world].new_document
|
204
|
+
view = doc.create_view
|
205
|
+
exp_hints = Ruber::World::Environment::DEFAULT_HINTS.merge(:create_if_needed => false)
|
206
|
+
flexmock(@solver).should_receive(:find_editor).with(doc, exp_hints).once.and_return(view)
|
207
|
+
@env.editor_for!(doc, :create_if_needed => false)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'closes the default document if it\'s pristine' do
|
211
|
+
@env.editor_for! __FILE__
|
212
|
+
Ruber[:world].documents.find{|d| d.object_name == 'default_document'}.should be_nil
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'doesn\'t close the default environment if the first argument is the default document itself' do
|
216
|
+
@env.editor_for! Ruber[:world].documents.find{|d| d.object_name == "default_document"}
|
217
|
+
Ruber[:world].documents.find{|d| d.object_name == "default_document"}.should_not be_nil
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'doesn\'t close the default document if it is not pristine' do
|
221
|
+
flexmock(@env.documents[0]).should_receive(:pristine?).and_return false
|
222
|
+
@env.editor_for! __FILE__
|
223
|
+
Ruber[:world].documents.find{|d| d.object_name == 'default_document'}.should_not be_nil
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'doesn\'t close the default document if it has no view associated with it' do
|
227
|
+
default_doc = Ruber[:world].documents.find{|d| d.object_name == 'default_document'}
|
228
|
+
default_doc.views[0].close
|
229
|
+
@env.editor_for! __FILE__
|
230
|
+
Ruber[:world].documents.should include(default_doc)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'doesn\'t close the default document if it has more than one view associated with it' do
|
234
|
+
default_doc = Ruber[:world].documents.find{|d| d.object_name == 'default_document'}
|
235
|
+
default_doc.create_view
|
236
|
+
@env.editor_for! __FILE__
|
237
|
+
Ruber[:world].documents.should include(default_doc)
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'when the first argument is a document' do
|
241
|
+
|
242
|
+
before do
|
243
|
+
@doc = Ruber[:world].new_document
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'when the tab widget contains an editor for the given document matching the given hints' do
|
247
|
+
|
248
|
+
it 'returns that editor' do
|
249
|
+
view = @doc.create_view
|
250
|
+
flexmock(@solver).should_receive(:find_editor).with(@doc, Hash).once.and_return(view)
|
251
|
+
@env.editor_for!(@doc, {}).should == view
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
context 'when the tab widget does not contain an editor for the given document matching the given hints' do
|
257
|
+
|
258
|
+
context 'if the create_if_needed hint is false' do
|
259
|
+
|
260
|
+
it 'returns nil' do
|
261
|
+
flexmock(@solver).should_receive(:find_editor).with(@doc, Hash).and_return nil
|
262
|
+
@env.editor_for!(@doc, {:create_if_needed => false}).should be_nil
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'if the create_if_needed hint is true' do
|
268
|
+
|
269
|
+
before do
|
270
|
+
@add_view_proc = lambda do |view|
|
271
|
+
flexmock(view.document).should_receive(:create_view).and_return view
|
272
|
+
@env.editor_for! view.document, :existing => :never, :new => :new_tab
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'creates and returns a new editor' do
|
277
|
+
@env.editor_for!(@doc, :create_if_needed => true).should be_a(Ruber::EditorView)
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'places the new editor in the position returned by the hint solver #place_editor method if it is not nil' do
|
281
|
+
old_editor = @doc.create_view
|
282
|
+
pane = @env.send :create_tab, old_editor
|
283
|
+
@env.send :add_editor, old_editor, pane
|
284
|
+
# pane = Ruber::Pane.new old_editor
|
285
|
+
tabs = @env.tab_widget
|
286
|
+
tabs.add_tab pane, 'Tab'
|
287
|
+
tabs.current_index = 0
|
288
|
+
editor = @env.editor_for! @doc, {:existing => :never, :create_if_needed => true, :new => :current_tab}
|
289
|
+
pane.splitter.widget(1).view.should == editor
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'respects the :split hint' do
|
293
|
+
old_editor = @doc.create_view
|
294
|
+
pane = @env.send :create_tab, old_editor
|
295
|
+
@env.send :add_editor, old_editor, pane
|
296
|
+
tabs = @env.tab_widget
|
297
|
+
tabs.add_tab pane, 'Tab'
|
298
|
+
tabs.current_index = 0
|
299
|
+
editor = @env.editor_for! @doc, {:existing => :never, :create_if_needed => true, :new => :current_tab, :split => :vertical}
|
300
|
+
pane.splitter.orientation.should == Qt::Vertical
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'places the new editor in a new tab if the hint solver\'s #place_editor method returns nil' do
|
304
|
+
old_editor = @doc.create_view
|
305
|
+
pane = @env.send :create_tab, old_editor
|
306
|
+
@env.send :add_editor, old_editor, pane
|
307
|
+
tabs = @env.tab_widget
|
308
|
+
tabs.add_tab pane, 'Tab'
|
309
|
+
tabs.current_index = 0
|
310
|
+
editor = @env.editor_for! @doc, {:existing => :never, :create_if_needed => true, :new => :newt_tab}
|
311
|
+
new_pane = tabs.widget(1)
|
312
|
+
new_pane.view.should == editor
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'uses the document name as tab\'s caption when placing the editor in a new tab' do
|
316
|
+
editor = @env.editor_for! @doc, {:existing => :never, :create_if_needed => true, :new => :newt_tab}
|
317
|
+
@env.tab_widget.tab_text(0).should == @doc.document_name
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'uses the document icon as tab\'s icon when placing the editor in a new tab' do
|
321
|
+
doc = Ruber[:world].document __FILE__
|
322
|
+
editor = @env.editor_for! @doc, {:existing => :never, :create_if_needed => true, :new => :newt_tab}
|
323
|
+
exp_image = @doc.icon.pixmap(Qt::Size.new(16,16)).to_image
|
324
|
+
@env.tab_widget.tab_icon(0).pixmap(Qt::Size.new(16,16)).to_image.should == exp_image
|
325
|
+
end
|
326
|
+
|
327
|
+
it_behaves_like 'when adding a view'
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
context 'when the first argument is a string' do
|
336
|
+
|
337
|
+
after do
|
338
|
+
@doc.close if @doc
|
339
|
+
end
|
340
|
+
|
341
|
+
context 'and the world contains a document associated with the given file' do
|
342
|
+
|
343
|
+
it 'returns an editor for the document' do
|
344
|
+
@doc = Ruber[:world].document __FILE__
|
345
|
+
editor = @env.editor_for! __FILE__
|
346
|
+
editor.document.path.should == __FILE__
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'doesn\'t create a new document' do
|
350
|
+
@doc = Ruber[:world].document __FILE__
|
351
|
+
editor = @env.editor_for! __FILE__
|
352
|
+
editor.document.should == @doc
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
|
357
|
+
context 'and the world doesn\'t contain a document associated with the given file' do
|
358
|
+
|
359
|
+
it 'returns an editor for the document' do
|
360
|
+
editor = @env.editor_for! __FILE__
|
361
|
+
editor.document.path.should == __FILE__
|
362
|
+
@doc = editor.document
|
363
|
+
end
|
364
|
+
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
context 'when the first argument is an URL' do
|
370
|
+
|
371
|
+
after do
|
372
|
+
@doc.close if @doc
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'and the world contains a document associated with the given file' do
|
376
|
+
|
377
|
+
it 'returns an editor for the document' do
|
378
|
+
@doc = Ruber[:world].document __FILE__
|
379
|
+
editor = @env.editor_for! KDE::Url.new(__FILE__)
|
380
|
+
editor.document.path.should == __FILE__
|
381
|
+
end
|
382
|
+
|
383
|
+
it 'doesn\'t create a new document' do
|
384
|
+
@doc = Ruber[:world].document __FILE__
|
385
|
+
editor = @env.editor_for! KDE::Url.new(__FILE__)
|
386
|
+
editor.document.should == @doc
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
context 'and the world doesn\'t contain a document associated with the given file' do
|
392
|
+
|
393
|
+
it 'returns an editor for the document' do
|
394
|
+
editor = @env.editor_for! KDE::Url.new(__FILE__)
|
395
|
+
editor.document.path.should == __FILE__
|
396
|
+
@doc = editor.document
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|
400
|
+
|
401
|
+
end
|
402
|
+
|
403
|
+
end
|
404
|
+
|
405
|
+
describe '#tab' do
|
406
|
+
|
407
|
+
before do
|
408
|
+
@views = [
|
409
|
+
@env.editor_for!(__FILE__),
|
410
|
+
@env.editor_for!(__FILE__, :existing => :never, :new => :current_tab),
|
411
|
+
@env.editor_for!(__FILE__, :existing => :never, :new => :new_tab)
|
412
|
+
]
|
413
|
+
end
|
414
|
+
|
415
|
+
context 'when the argument is a Pane' do
|
416
|
+
|
417
|
+
it 'returns the toplevel pane containing the argument' do
|
418
|
+
view = @env.editor_for! __FILE__, :existing => :never, :new => @views[1],
|
419
|
+
:split => :vertical
|
420
|
+
pane = view.parent
|
421
|
+
@env.tab(pane).should == @env.tab_widget.widget(0)
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'returns the pane itself if it is a toplevel pane' do
|
425
|
+
toplevel = @views[2].parent
|
426
|
+
@env.tab(toplevel).should == toplevel
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'returns nil if the toplevel pane doesn\'t belong to the tab widget associated with the environment' do
|
430
|
+
doc = Ruber[:world].document __FILE__
|
431
|
+
view = doc.create_view
|
432
|
+
pane = Ruber::Pane.new view
|
433
|
+
@env.tab(pane).should be_nil
|
434
|
+
end
|
435
|
+
|
436
|
+
end
|
437
|
+
|
438
|
+
context 'when the argument is a view' do
|
439
|
+
|
440
|
+
it 'returns the toplevel pane containing the argument' do
|
441
|
+
view = @env.editor_for! __FILE__, :existing => :never, :new => @views[1],
|
442
|
+
:split => :vertical
|
443
|
+
@env.tab(view).should == @env.tab_widget.widget(0)
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'returns the parent of the view if it is a toplevel pane' do
|
447
|
+
toplevel = @views[2].parent
|
448
|
+
@env.tab(@views[2]).should == toplevel
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'returns nil if the toplevel pane doesn\'t belong to the tab widget associated with the environment' do
|
452
|
+
doc = Ruber[:world].document __FILE__
|
453
|
+
view = doc.create_view
|
454
|
+
pane = Ruber::Pane.new view
|
455
|
+
@env.tab(view).should be_nil
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'returns nil if the view isn\'t in a pane' do
|
459
|
+
doc = Ruber[:world].document __FILE__
|
460
|
+
view = doc.create_view
|
461
|
+
@env.tab(view).should be_nil
|
462
|
+
end
|
463
|
+
|
464
|
+
end
|
465
|
+
|
466
|
+
end
|
467
|
+
|
468
|
+
describe '#tabs' do
|
469
|
+
|
470
|
+
it 'returns an array containing all the toplevel tabs contained in the environment in order' do
|
471
|
+
doc = Ruber[:world].new_document
|
472
|
+
3.times{@env.editor_for! doc, :existing => :never}
|
473
|
+
tab_widget = @env.tab_widget
|
474
|
+
@env.tabs.should == 3.times.map{|i| tab_widget.widget i}
|
475
|
+
end
|
476
|
+
|
477
|
+
it 'returns an empty array if there is no tab in the tab widget' do
|
478
|
+
@env.documents[0].close false
|
479
|
+
@env.tabs.should be_empty
|
480
|
+
end
|
481
|
+
|
482
|
+
end
|
483
|
+
|
484
|
+
describe '#documents' do
|
485
|
+
|
486
|
+
before do
|
487
|
+
@docs = [Ruber::Document.new, Ruber[:world].document(__FILE__)]
|
488
|
+
@env.editor_for! @docs[0]
|
489
|
+
@env.editor_for! @docs[1], :existing => :never
|
490
|
+
end
|
491
|
+
|
492
|
+
it 'returns DocumentList' do
|
493
|
+
@env.documents.should be_a(Ruber::World::DocumentList)
|
494
|
+
end
|
495
|
+
|
496
|
+
it 'returns a list containing all the documents associated with a view in the environment' do
|
497
|
+
@env.documents.should == [@docs[0], @docs[1]]
|
498
|
+
end
|
499
|
+
|
500
|
+
it 'returns a list which doesn\'t contain documents which have been closed' do
|
501
|
+
@docs[1].close
|
502
|
+
@env.documents.should == [@docs[0]]
|
503
|
+
end
|
504
|
+
|
505
|
+
end
|
506
|
+
|
507
|
+
describe '#views' do
|
508
|
+
|
509
|
+
before do
|
510
|
+
@docs = 3.times.map{Ruber::Document.new}
|
511
|
+
@editors = []
|
512
|
+
@editors << @env.editor_for!(@docs[0])
|
513
|
+
@editors << @env.editor_for!(@docs[1], :new => :current_tab)
|
514
|
+
@editors << @env.editor_for!(@docs[2], :new => :current_tab)
|
515
|
+
@editors << @env.editor_for!(@docs[0], :existing => :never, :new => :new_tab)
|
516
|
+
@editors << @env.editor_for!(@docs[2], :existing => :never, :new => :new_tab)
|
517
|
+
end
|
518
|
+
|
519
|
+
context 'when called without arguments' do
|
520
|
+
|
521
|
+
it 'returns a list containing all the views in the environment' do
|
522
|
+
@env.views.sort_by{|v| v.object_id}.should == @editors.sort_by{|v| v.object_id}
|
523
|
+
end
|
524
|
+
|
525
|
+
it 'returns a list containing the views in activation order, from most recently activated to
|
526
|
+
least recently activated' do
|
527
|
+
@env.activate_editor @editors[1]
|
528
|
+
@env.activate_editor @editors[4]
|
529
|
+
@env.activate_editor @editors[2]
|
530
|
+
exp = [@editors[2], @editors[4], @editors[1], @editors[0], @editors[3]]
|
531
|
+
@env.views.should == exp
|
532
|
+
end
|
533
|
+
|
534
|
+
it 'returns a list which doesn\'t contain duplicate arguments if a view is created by splitting another one' do
|
535
|
+
@env.views.select{|v| v == @editors[1]}.count.should == 1
|
536
|
+
end
|
537
|
+
|
538
|
+
end
|
539
|
+
|
540
|
+
context 'when called with a document as argument' do
|
541
|
+
|
542
|
+
it 'returns a list containing all the views in the environment which are associated with the given document' do
|
543
|
+
exp = @editors.select{|v| v.document == @docs[0]}.sort_by{|v| v.object_id}
|
544
|
+
@env.views(@docs[0]).sort_by{|v| v.object_id}.should == exp
|
545
|
+
end
|
546
|
+
|
547
|
+
it 'returns a list containing the views in activation order, from most recently activated to
|
548
|
+
least recently activated' do
|
549
|
+
@env.activate_editor @editors[3]
|
550
|
+
@env.views(@docs[0]).should == [@editors[3], @editors[0]]
|
551
|
+
end
|
552
|
+
|
553
|
+
end
|
554
|
+
|
555
|
+
end
|
556
|
+
|
557
|
+
describe '#activate_editor' do
|
558
|
+
|
559
|
+
before do
|
560
|
+
clients = Ruber[:main_window].gui_factory.clients
|
561
|
+
clients.each{|c| Ruber[:main_window].gui_factory.remove_client c unless c.is_a? Ruber::MainWindow}
|
562
|
+
@env.activate
|
563
|
+
@docs = 3.times.map{Ruber::Document.new}
|
564
|
+
@editors = []
|
565
|
+
@editors << @env.editor_for!(@docs[0])
|
566
|
+
@editors << @env.editor_for!(@docs[1], :new => :current_tab)
|
567
|
+
@editors << @env.editor_for!(@docs[2], :new => :current_tab)
|
568
|
+
@editors << @env.editor_for!(@docs[0], :existing => :never, :new => :new_tab)
|
569
|
+
@editors << @env.editor_for!(@docs[2], :existing => :never, :new => :new_tab)
|
570
|
+
end
|
571
|
+
|
572
|
+
context 'when there\'s no active editor' do
|
573
|
+
|
574
|
+
it 'merges the editor\'s GUI with the main window\'s' do
|
575
|
+
factory = Ruber[:main_window].gui_factory
|
576
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
577
|
+
#we can't set a mock on it.
|
578
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
579
|
+
flexmock(factory).should_receive(:add_client).with(@editors[2].send(:internal)).once
|
580
|
+
@env.activate_editor @editors[2]
|
581
|
+
end
|
582
|
+
|
583
|
+
it 'marks the view as last activated' do
|
584
|
+
@env.activate_editor @editors[4]
|
585
|
+
@env.views[0].should == @editors[4]
|
586
|
+
@env.activate_editor @editors[2]
|
587
|
+
@env.views[0].should == @editors[2]
|
588
|
+
end
|
589
|
+
|
590
|
+
it 'changes the label and icon of the tab to match those of the document corresponding to the activated editor' do
|
591
|
+
@env.activate_editor @editors[2]
|
592
|
+
@env.tab_widget.tab_text(0).should == @editors[2].document.document_name
|
593
|
+
exp_image = @editors[2].document.icon.pixmap(Qt::Size.new(16,16)).to_image
|
594
|
+
@env.tab_widget.tab_icon(0).pixmap(Qt::Size.new(16,16)).to_image.should
|
595
|
+
end
|
596
|
+
|
597
|
+
it 'activates the document associated with the activate editor' do
|
598
|
+
flexmock(@editors[2].document).should_receive(:activate).once
|
599
|
+
@env.activate_editor @editors[2]
|
600
|
+
end
|
601
|
+
|
602
|
+
it 'emits the active_editor_changed signal passing the new active view as argument' do
|
603
|
+
test = flexmock{|m| m.should_receive(:active_editor_changed).with(@editors[2]).once}
|
604
|
+
@env.connect(SIGNAL('active_editor_changed(QWidget*)')){|w| test.active_editor_changed w}
|
605
|
+
@env.activate_editor @editors[2]
|
606
|
+
end
|
607
|
+
|
608
|
+
it 'makes the tab containing the ativated editor current' do
|
609
|
+
@env.activate_editor @editors[2]
|
610
|
+
@env.tab_widget.current_index.should == 0
|
611
|
+
@env.activate_editor @editors[4]
|
612
|
+
@env.tab_widget.current_index.should == 2
|
613
|
+
end
|
614
|
+
|
615
|
+
it 'returns the new active editor' do
|
616
|
+
@env.activate_editor(@editors[2]).should == @editors[2]
|
617
|
+
end
|
618
|
+
|
619
|
+
it 'does nothing if the argument is nil' do
|
620
|
+
factory = Ruber[:main_window].gui_factory
|
621
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
622
|
+
#we can't set a mock on it.
|
623
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
624
|
+
flexmock(factory).should_receive(:add_client).never
|
625
|
+
flexmock(@editors[2].document).should_receive(:activate).never
|
626
|
+
@env.activate_editor nil
|
627
|
+
end
|
628
|
+
|
629
|
+
end
|
630
|
+
|
631
|
+
context 'when there\'s an active editor' do
|
632
|
+
|
633
|
+
before do
|
634
|
+
@env.activate_editor @editors[3]
|
635
|
+
end
|
636
|
+
|
637
|
+
it 'deactivates the currently active editor' do
|
638
|
+
factory = Ruber[:main_window].gui_factory
|
639
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
640
|
+
#we can't set a mock on it.
|
641
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
642
|
+
flexmock(factory).should_receive(:remove_client).with(@editors[3].send(:internal)).once
|
643
|
+
@env.activate_editor @editors[2]
|
644
|
+
end
|
645
|
+
|
646
|
+
it 'deactivates the document corresponding to the previously active editor' do
|
647
|
+
flexmock(@editors[3].document).should_receive(:deactivate).once
|
648
|
+
@env.activate_editor @editors[2]
|
649
|
+
end
|
650
|
+
|
651
|
+
it 'merges the editor\'s GUI with the main window\'s' do
|
652
|
+
factory = Ruber[:main_window].gui_factory
|
653
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
654
|
+
#we can't set a mock on it.
|
655
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
656
|
+
flexmock(factory).should_receive(:add_client).with(@editors[2].send(:internal)).once
|
657
|
+
@env.activate_editor @editors[2]
|
658
|
+
end
|
659
|
+
|
660
|
+
it 'marks the view as last activated' do
|
661
|
+
@env.activate_editor @editors[4]
|
662
|
+
@env.views[0].should == @editors[4]
|
663
|
+
@env.activate_editor @editors[2]
|
664
|
+
@env.views[0].should == @editors[2]
|
665
|
+
end
|
666
|
+
|
667
|
+
it 'changes the label and icon of the tab to match those of the document corresponding to the activated editor' do
|
668
|
+
@env.activate_editor @editors[2]
|
669
|
+
@env.tab_widget.tab_text(0).should == @editors[2].document.document_name
|
670
|
+
exp_image = @editors[2].document.icon.pixmap(Qt::Size.new(16,16)).to_image
|
671
|
+
@env.tab_widget.tab_icon(0).pixmap(Qt::Size.new(16,16)).to_image.should
|
672
|
+
end
|
673
|
+
|
674
|
+
it 'activates the document associated with the activate editor' do
|
675
|
+
flexmock(@editors[2].document).should_receive(:activate).once
|
676
|
+
@env.activate_editor @editors[2]
|
677
|
+
end
|
678
|
+
|
679
|
+
it 'makes the tab containing the ativated editor current' do
|
680
|
+
@env.activate_editor @editors[2]
|
681
|
+
@env.tab_widget.current_index.should == 0
|
682
|
+
@env.activate_editor @editors[4]
|
683
|
+
@env.tab_widget.current_index.should == 2
|
684
|
+
end
|
685
|
+
|
686
|
+
it 'emits the active_editor_changed signal passing the new active view as argument' do
|
687
|
+
test = flexmock{|m| m.should_receive(:active_editor_changed).with(@editors[2]).once}
|
688
|
+
@env.connect(SIGNAL('active_editor_changed(QWidget*)')){|w| test.active_editor_changed w}
|
689
|
+
@env.activate_editor @editors[2]
|
690
|
+
end
|
691
|
+
|
692
|
+
it 'returns the new active editor' do
|
693
|
+
@env.activate_editor(@editors[2]).should == @editors[2]
|
694
|
+
end
|
695
|
+
|
696
|
+
it 'does nothing if the given editor was already active' do
|
697
|
+
@env.activate_editor @editors[2]
|
698
|
+
factory = Ruber[:main_window].gui_factory
|
699
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
700
|
+
#we can't set a mock on it.
|
701
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
702
|
+
flexmock(@env).should_receive(:deactivate_editor).never
|
703
|
+
flexmock(factory).should_receive(:add_client).never
|
704
|
+
flexmock(@editors[3].document).should_receive(:deactivate).never
|
705
|
+
flexmock(@editors[2].document).should_receive(:activate).never
|
706
|
+
flexmock(@env).should_receive(:emit).never
|
707
|
+
@env.activate_editor @editors[2]
|
708
|
+
end
|
709
|
+
|
710
|
+
it 'doesn\'t attempt to merge the argument\'s GUI if the argument is nil' do
|
711
|
+
@env.activate_editor @editors[2]
|
712
|
+
factory = Ruber[:main_window].gui_factory
|
713
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
714
|
+
#we can't set a mock on it.
|
715
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
716
|
+
flexmock(factory).should_receive(:remove_client).with(@editors[2].send(:internal)).once
|
717
|
+
flexmock(factory).should_receive(:add_client).never
|
718
|
+
flexmock(@editors[2].document).should_receive(:deactivate).once
|
719
|
+
mk = flexmock{|m| m.should_receive(:active_editor_changed).once.with(nil)}
|
720
|
+
@env.connect(SIGNAL('active_editor_changed(QWidget*)')){|v| mk.active_editor_changed v}
|
721
|
+
@env.activate_editor nil
|
722
|
+
end
|
723
|
+
|
724
|
+
end
|
725
|
+
|
726
|
+
context 'if the environment is not active' do
|
727
|
+
|
728
|
+
before do
|
729
|
+
@env.deactivate
|
730
|
+
end
|
731
|
+
|
732
|
+
it 'doesn\'t attempt to merge the view\'s GUI with the main window\'s' do
|
733
|
+
factory = Ruber[:main_window].gui_factory
|
734
|
+
#MainWindow#gui_factory returns a different ruby object each time, so
|
735
|
+
#we can't set a mock on it.
|
736
|
+
flexmock(Ruber[:main_window]).should_receive(:gui_factory).and_return factory
|
737
|
+
flexmock(factory).should_receive(:add_client).never
|
738
|
+
@env.activate_editor @editors[1]
|
739
|
+
end
|
740
|
+
|
741
|
+
it 'doesn\'t change the active editor' do
|
742
|
+
@env.activate_editor @editors[1]
|
743
|
+
@env.active_editor.should be_nil
|
744
|
+
end
|
745
|
+
|
746
|
+
it 'marks the view as last activated' do
|
747
|
+
@env.activate_editor @editors[2]
|
748
|
+
@env.views[0].should == @editors[2]
|
749
|
+
end
|
750
|
+
|
751
|
+
it 'changes the current tab index' do
|
752
|
+
@env.tab_widget.current_index = 0
|
753
|
+
@env.activate_editor @editors[3]
|
754
|
+
@env.tab_widget.current_index.should == 1
|
755
|
+
end
|
756
|
+
|
757
|
+
it 'changes the text and icon of the tab to match those of the editor' do
|
758
|
+
@env.tab_widget.set_tab_icon 0, Qt::Icon.new
|
759
|
+
@env.tab_widget.set_tab_text 0, "Test"
|
760
|
+
@env.activate_editor @editors[1]
|
761
|
+
@env.tab_widget.tab_text(0).should == @editors[1].document.document_name
|
762
|
+
exp_icon = @editors[1].document.icon.pixmap(Qt::Size.new(16,16)).to_image
|
763
|
+
icon = @env.tab_widget.tab_icon(0).pixmap(Qt::Size.new(16,16)).to_image
|
764
|
+
exp_icon.should == icon
|
765
|
+
end
|
766
|
+
|
767
|
+
it 'doesn\'t emit the active_editor_changed signal' do
|
768
|
+
mk = flexmock{|m| m.should_receive(:active_editor_changed).never}
|
769
|
+
@env.connect(SIGNAL('active_editor_changed(QWidget*)')){mk.active_editor_changed}
|
770
|
+
@env.activate_editor @editors[3]
|
771
|
+
end
|
772
|
+
|
773
|
+
it 'doesn\'t activate the document associated with the editor' do
|
774
|
+
flexmock(@editors[2].document).should_receive(:activate).never
|
775
|
+
@env.activate_editor @editors[2]
|
776
|
+
end
|
777
|
+
|
778
|
+
end
|
779
|
+
|
780
|
+
it 'gives focus to the editor if #focus_on_editors? returns true' do
|
781
|
+
flexmock(@env).should_receive(:focus_on_editors?).and_return(true)
|
782
|
+
flexmock(@editors[2]).should_receive(:set_focus).once
|
783
|
+
@env.activate_editor @editors[2]
|
784
|
+
end
|
785
|
+
|
786
|
+
it 'doesn\'t give focus to the editor if #focus_on_editors? returns false' do
|
787
|
+
flexmock(@env).should_receive(:focus_on_editors?).and_return(false)
|
788
|
+
flexmock(@editors[2]).should_receive(:set_focus).never
|
789
|
+
@env.activate_editor @editors[2]
|
790
|
+
end
|
791
|
+
|
792
|
+
end
|
793
|
+
|
794
|
+
describe '#deactivate' do
|
795
|
+
|
796
|
+
before do
|
797
|
+
@doc = Ruber[:world].new_document
|
798
|
+
@editor = @env.editor_for! @doc
|
799
|
+
@env.activate
|
800
|
+
end
|
801
|
+
|
802
|
+
it 'deactivates the active editor if it exists' do
|
803
|
+
@env.activate_editor @editor
|
804
|
+
flexmock(@env).should_receive(:deactivate_editor).with(@editor).once
|
805
|
+
@env.deactivate
|
806
|
+
end
|
807
|
+
|
808
|
+
it 'behaves like Activable#deactivate' do
|
809
|
+
mk = flexmock{|m| m.should_receive(:deactivated).once}
|
810
|
+
@env.connect(SIGNAL(:deactivated)){mk.deactivated}
|
811
|
+
@env.deactivate
|
812
|
+
@env.should_not be_active
|
813
|
+
end
|
814
|
+
|
815
|
+
end
|
816
|
+
|
817
|
+
describe '#activate' do
|
818
|
+
|
819
|
+
before do
|
820
|
+
Ruber[:world].close_all :documents, :discard
|
821
|
+
@doc = Ruber[:world].new_document
|
822
|
+
@env.activate
|
823
|
+
@env.deactivate
|
824
|
+
end
|
825
|
+
|
826
|
+
it 'activates the last activated editor' do
|
827
|
+
editors = 3.times.map{@env.editor_for! @doc, :existing => :never}
|
828
|
+
@env.activate
|
829
|
+
@env.activate_editor editors[1]
|
830
|
+
@env.deactivate
|
831
|
+
flexmock(@env).should_receive(:activate_editor).with(editors[1]).once
|
832
|
+
@env.activate
|
833
|
+
end
|
834
|
+
|
835
|
+
it 'makes all documents inactive if there is no editor in the environment' do
|
836
|
+
flexmock(@env).should_receive(:activate_editor).with(nil).once
|
837
|
+
@env.activate
|
838
|
+
end
|
839
|
+
|
840
|
+
it 'behaves like Activable#activate' do
|
841
|
+
mk = flexmock{|m| m.should_receive(:activated).once}
|
842
|
+
@env.connect(SIGNAL(:activated)){mk.activated}
|
843
|
+
@env.activate
|
844
|
+
@env.should be_active
|
845
|
+
end
|
846
|
+
|
847
|
+
end
|
848
|
+
|
849
|
+
describe '#active_editor' do
|
850
|
+
|
851
|
+
context 'if the environment is active' do
|
852
|
+
|
853
|
+
before do
|
854
|
+
Ruber[:world].close_all :documents, :discard
|
855
|
+
@env.activate
|
856
|
+
end
|
857
|
+
|
858
|
+
it 'returns nil if there\'s no active editor' do
|
859
|
+
@env.active_editor.should be_nil
|
860
|
+
end
|
861
|
+
|
862
|
+
it 'returns the active editor if it exists' do
|
863
|
+
doc = Ruber[:world].new_document
|
864
|
+
editors = 3.times.map{@env.editor_for! doc, :existing => :never}
|
865
|
+
@env.activate_editor editors[1]
|
866
|
+
@env.active_editor.should == editors[1]
|
867
|
+
end
|
868
|
+
|
869
|
+
end
|
870
|
+
|
871
|
+
context 'if the environment is not active' do
|
872
|
+
|
873
|
+
it 'always returns nil' do
|
874
|
+
@env.deactivate
|
875
|
+
@env.active_editor.should be_nil
|
876
|
+
@env.activate
|
877
|
+
doc = Ruber[:world].new_document
|
878
|
+
editors = 3.times.map{@env.editor_for! doc, :existing => :never}
|
879
|
+
@env.activate_editor editors[1]
|
880
|
+
@env.deactivate
|
881
|
+
@env.active_editor.should be_nil
|
882
|
+
end
|
883
|
+
|
884
|
+
end
|
885
|
+
|
886
|
+
end
|
887
|
+
|
888
|
+
describe '#active_document' do
|
889
|
+
|
890
|
+
context 'if the environment is active' do
|
891
|
+
|
892
|
+
before do
|
893
|
+
Ruber[:world].close_all :documents, :discard
|
894
|
+
@env.activate
|
895
|
+
end
|
896
|
+
|
897
|
+
it 'returns nil if there\'s no active editor' do
|
898
|
+
@env.active_document.should be_nil
|
899
|
+
end
|
900
|
+
|
901
|
+
it 'returns the document associated with the active editor if it exists' do
|
902
|
+
doc = Ruber[:world].new_document
|
903
|
+
editors = 3.times.map{@env.editor_for! doc, :existing => :never}
|
904
|
+
@env.activate_editor editors[1]
|
905
|
+
@env.active_document.should == editors[1].document
|
906
|
+
end
|
907
|
+
|
908
|
+
end
|
909
|
+
|
910
|
+
context 'if the environment is not active' do
|
911
|
+
|
912
|
+
it 'always returns nil' do
|
913
|
+
@env.deactivate
|
914
|
+
@env.active_document.should be_nil
|
915
|
+
@env.activate
|
916
|
+
doc = Ruber[:world].new_document
|
917
|
+
editors = 3.times.map{@env.editor_for! doc, :existing => :never}
|
918
|
+
@env.activate_editor editors[1]
|
919
|
+
@env.deactivate
|
920
|
+
@env.active_document.should be_nil
|
921
|
+
end
|
922
|
+
|
923
|
+
end
|
924
|
+
|
925
|
+
end
|
926
|
+
|
927
|
+
describe 'when the current tab changes' do
|
928
|
+
|
929
|
+
it 'activates the last active editor in the new tab' do
|
930
|
+
doc = Ruber[:world].new_document
|
931
|
+
views1 = 2.times.map{@env.editor_for! doc, :existing => :never, :new => :current_tab}
|
932
|
+
views2 = 2.times.map{@env.editor_for! doc, :existing => :never, :new => :new_tab}
|
933
|
+
@env.activate_editor views2[1]
|
934
|
+
@env.activate_editor views1[1]
|
935
|
+
@env.activate_editor views2[1]
|
936
|
+
@env.tab_widget.current_index = 0
|
937
|
+
@env.active_editor.should == views1[1]
|
938
|
+
end
|
939
|
+
|
940
|
+
end
|
941
|
+
|
942
|
+
describe 'when an editor is closed' do
|
943
|
+
|
944
|
+
before do
|
945
|
+
@doc = Ruber[:world].new_document
|
946
|
+
end
|
947
|
+
|
948
|
+
context 'if the view is the active one' do
|
949
|
+
|
950
|
+
before do
|
951
|
+
@views = @views = 4.times.map{|i| @env.editor_for! @doc, :existing => :never}
|
952
|
+
end
|
953
|
+
|
954
|
+
it 'deactivates it' do
|
955
|
+
@env.activate_editor @views[2]
|
956
|
+
@env.activate_editor @views[3]
|
957
|
+
@env.activate_editor @views[0]
|
958
|
+
@env.activate_editor @views[1]
|
959
|
+
@views[1].close
|
960
|
+
@env.active_editor.should_not == @views[1]
|
961
|
+
end
|
962
|
+
|
963
|
+
end
|
964
|
+
|
965
|
+
context 'if there are other editors in the same tab' do
|
966
|
+
|
967
|
+
before do
|
968
|
+
@views = 4.times.map{|i| @env.editor_for! @doc, :existing => :never, :new => (i == 3 ? :new_tab : :current_tab) }
|
969
|
+
end
|
970
|
+
|
971
|
+
it 'removes the view from the tab' do
|
972
|
+
pane = @env.tab_widget.widget 0
|
973
|
+
@views[1].close
|
974
|
+
pane.should_not include(@views[1])
|
975
|
+
end
|
976
|
+
|
977
|
+
it 'activates the previously activated view in the same tab if the view was active' do
|
978
|
+
@env.activate_editor @views[2]
|
979
|
+
@env.activate_editor @views[1]
|
980
|
+
@views[1].close
|
981
|
+
@env.active_editor.should == @views[2]
|
982
|
+
end
|
983
|
+
|
984
|
+
it 'gives focus to view which previously had focus in the same tab, if the closed view was active and focus_on_editors? returns true' do
|
985
|
+
flexmock(@env).should_receive(:focus_on_editor?).and_return true
|
986
|
+
@env.activate_editor @views[2]
|
987
|
+
@env.activate_editor @views[1]
|
988
|
+
@views[2].instance_eval{emit focus_in(self)}
|
989
|
+
@views[1].instance_eval{emit focus_in(self)}
|
990
|
+
flexmock(@views[2]).should_receive(:set_focus).once
|
991
|
+
@views[1].close
|
992
|
+
end
|
993
|
+
|
994
|
+
it 'doesn\'t give focus to view which previously had focus in the same tab, if focus_on_editors? returns false' do
|
995
|
+
flexmock(@env).should_receive(:focus_on_editors?).and_return false
|
996
|
+
@env.activate_editor @views[2]
|
997
|
+
@env.activate_editor @views[1]
|
998
|
+
@views[2].instance_eval{emit focus_in(self)}
|
999
|
+
@views[1].instance_eval{emit focus_in(self)}
|
1000
|
+
flexmock(@views[2]).should_receive(:set_focus).never
|
1001
|
+
@views[1].close
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
context 'if there\'s no other editor in the same tab' do
|
1007
|
+
|
1008
|
+
before do
|
1009
|
+
@views = 2.times.map{@env.editor_for! @doc, :existing => :never, :new => :new_tab}
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
it 'removes the tab' do
|
1013
|
+
@views[1].close
|
1014
|
+
@env.tab_widget.count.should == 1
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
it 'removes the view from the list of views' do
|
1020
|
+
views = 3.times.map{@env.editor_for! @doc, :existing => :never}
|
1021
|
+
views[1].close
|
1022
|
+
@env.views.should == [views[0], views[2]]
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
describe '#close_editor' do
|
1028
|
+
|
1029
|
+
before do
|
1030
|
+
@doc = Ruber[:world].new_document
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
context 'if the given editor is the last editor associated with the document' do
|
1034
|
+
|
1035
|
+
it 'closes the document, passing the second argument to Document#close' do
|
1036
|
+
editor = @env.editor_for! @doc
|
1037
|
+
class << @doc
|
1038
|
+
alias_method :close!, :close
|
1039
|
+
end
|
1040
|
+
flexmock(@doc).should_receive(:close).once.with(false)
|
1041
|
+
@env.close_editor editor, false
|
1042
|
+
@doc.close!
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
context 'if the given editor is not the only one associated with the document' do
|
1048
|
+
|
1049
|
+
it 'only closes the editor' do
|
1050
|
+
class << @doc
|
1051
|
+
alias_method :close!, :close
|
1052
|
+
end
|
1053
|
+
editor = @env.editor_for! @doc
|
1054
|
+
class << editor
|
1055
|
+
alias_method :close!, :close
|
1056
|
+
end
|
1057
|
+
other_editor = @doc.create_view
|
1058
|
+
flexmock(@doc).should_receive(:close).never
|
1059
|
+
flexmock(editor).should_receive(:close).once
|
1060
|
+
@env.close_editor editor, false
|
1061
|
+
editor.close!
|
1062
|
+
@doc.close!
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
describe '#close' do
|
1070
|
+
|
1071
|
+
context 'if the environment is associated with a project' do
|
1072
|
+
|
1073
|
+
before do
|
1074
|
+
@file = File.join Dir.tmpdir, 'environment_remove_from_project_test'
|
1075
|
+
@project = Ruber::Project.new @file, "Test"
|
1076
|
+
@env = Ruber::World::Environment.new @project
|
1077
|
+
@docs = 4.times.map{Ruber[:world].new_document}
|
1078
|
+
@env_views = []
|
1079
|
+
@env_views += 2.times.map{@env.editor_for! @docs[0], :existing => :never}
|
1080
|
+
@env_views += 3.times.map{@env.editor_for! @docs[1], :existing => :never}
|
1081
|
+
@env_views += 3.times.map{@env.editor_for! @docs[2], :existing => :never}
|
1082
|
+
@other_views = [@docs[2].create_view, @docs[3].create_view]
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
after do
|
1086
|
+
FileUtils.rm_f @file
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
context 'if the argument is :save' do
|
1090
|
+
|
1091
|
+
it 'calls the project\'s close method passing true as argument' do
|
1092
|
+
flexmock(@project).should_receive(:close).with(true).once
|
1093
|
+
@env.close :save
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
it 'returns the value returned by the project\'s close method' do
|
1097
|
+
flexmock(@project).should_receive(:close).once.and_return(true)
|
1098
|
+
@env.close(:save).should == true
|
1099
|
+
flexmock(@project).should_receive(:close).once.and_return(false)
|
1100
|
+
@env.close(:save).should == false
|
1101
|
+
end
|
1102
|
+
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
context 'if the argument is :discard' do
|
1106
|
+
|
1107
|
+
it 'calls the project\'s close method passing false as argument' do
|
1108
|
+
flexmock(@project).should_receive(:close).with(false).once
|
1109
|
+
@env.close :discard
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
it 'returns the value returned by the project\'s close method' do
|
1113
|
+
flexmock(@project).should_receive(:close).once.and_return(true)
|
1114
|
+
@env.close(:discard).should == true
|
1115
|
+
flexmock(@project).should_receive(:close).once.and_return(false)
|
1116
|
+
@env.close(:discard).should == false
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
context 'if the environment is not associated with a project' do
|
1124
|
+
|
1125
|
+
before do
|
1126
|
+
@docs = 4.times.map{Ruber[:world].new_document}
|
1127
|
+
@env_views = []
|
1128
|
+
@env_views += 2.times.map{@env.editor_for! @docs[0], :existing => :never}
|
1129
|
+
@env_views += 3.times.map{@env.editor_for! @docs[1], :existing => :never}
|
1130
|
+
@env_views << @env.editor_for!(@docs[2])
|
1131
|
+
@other_views = [@docs[2].create_view, @docs[3].create_view]
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
context 'if the argument is :save' do
|
1135
|
+
|
1136
|
+
it 'calls MainWindow#save_documents passing the list of documents all of whose views are in the environment' do
|
1137
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).with( [@docs[0], @docs[1]]).once
|
1138
|
+
@env.close :save
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
context 'if MainWindow#save returns true' do
|
1142
|
+
|
1143
|
+
before do
|
1144
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).and_return true
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
it 'emits the closing signal passing itself as argument' do
|
1148
|
+
mk = flexmock{|m| m.should_receive(:env_closing).once.with(@env.object_id)}
|
1149
|
+
@env.connect(SIGNAL('closing(QObject*)')){|e| mk.env_closing e.object_id}
|
1150
|
+
@env.close :save
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
it 'deactivates itself' do
|
1154
|
+
@env.activate
|
1155
|
+
@env.close :save
|
1156
|
+
@env.should_not be_active
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
it 'closes all the documents whose views are all contained in the environment without asking' do
|
1160
|
+
2.times{|i| flexmock(@docs[i]).should_receive(:close).with(false).once}
|
1161
|
+
2.upto(3){|i| flexmock(@docs[i]).should_receive(:close).never}
|
1162
|
+
@env.close :save
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
it 'closes all the views in the environment whose documents have views not associated with the enviroment' do
|
1166
|
+
@env_views.select{|v| v.document == @docs[2]}.each{|v| flexmock(v).should_receive(:close).once}
|
1167
|
+
@env.close :save
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
it 'disposes of itself' do
|
1171
|
+
flexmock(@env).should_receive(:delete_later).once
|
1172
|
+
@env.close :save
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
it 'returns true' do
|
1176
|
+
@env.close(:save).should == true
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
end
|
1180
|
+
|
1181
|
+
context 'if MainWindow#save returns false' do
|
1182
|
+
|
1183
|
+
before do
|
1184
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).and_return false
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
it 'does nothing' do
|
1188
|
+
@env_views.each{|v| flexmock(v).should_receive(:close).never}
|
1189
|
+
@docs.each{|d| flexmock(d).should_receive(:close).never}
|
1190
|
+
@env.close :save
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
it 'returns false' do
|
1194
|
+
@env.close(:save).should == false
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
context 'if the argument is :discard' do
|
1202
|
+
|
1203
|
+
|
1204
|
+
it 'doesn\'t call MainWindow#save_documents' do
|
1205
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).never
|
1206
|
+
@env.close :discard
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
it 'emits the closing signal passing itself as argument' do
|
1210
|
+
mk = flexmock{|m| m.should_receive(:env_closing).once.with(@env.object_id)}
|
1211
|
+
@env.connect(SIGNAL('closing(QObject*)')){|e| mk.env_closing e.object_id}
|
1212
|
+
@env.close :discard
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
it 'deactivates itself' do
|
1216
|
+
@env.activate
|
1217
|
+
@env.close :discard
|
1218
|
+
@env.should_not be_active
|
1219
|
+
end
|
1220
|
+
|
1221
|
+
it 'closes all the documents whose views are all contained in the environment without asking' do
|
1222
|
+
2.times{|i| flexmock(@docs[i]).should_receive(:close).with(false).once}
|
1223
|
+
2.upto(3){|i| flexmock(@docs[i]).should_receive(:close).never}
|
1224
|
+
@env.close :discard
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
it 'closes all the views in the environment whose documents have views not associated with the enviroment' do
|
1228
|
+
@env_views.select{|v| v.document == @docs[2]}.each{|v| flexmock(v).should_receive(:close).once}
|
1229
|
+
@env.close :discard
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
it 'disposes of itself' do
|
1233
|
+
flexmock(@env).should_receive(:delete_later).once
|
1234
|
+
@env.close :discard
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
it 'returns true' do
|
1238
|
+
@env.close(:discard).should == true
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
describe '#close_editors' do
|
1248
|
+
|
1249
|
+
before do
|
1250
|
+
@docs = 3.times.map{Ruber::Document.new}
|
1251
|
+
@views = []
|
1252
|
+
@docs.each_with_index do |doc, i|
|
1253
|
+
views = 3.times.map{@env.editor_for! doc, :existing => :never}
|
1254
|
+
@views[i] = views
|
1255
|
+
end
|
1256
|
+
end
|
1257
|
+
|
1258
|
+
context 'if the second argument is false' do
|
1259
|
+
|
1260
|
+
it 'closes without asking all documents whose views are all to be closed' do
|
1261
|
+
flexmock(@docs[0]).should_receive(:close).once.with(false)
|
1262
|
+
flexmock(@docs[2]).should_receive(:close).once.with(false)
|
1263
|
+
flexmock(@docs[1]).should_receive(:close).never
|
1264
|
+
@env.close_editors @views[0] + @views[2] + [@views[1][0]], false
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
it 'closes the editors associated with documents having some views not to be closed' do
|
1268
|
+
flexmock(@docs[0]).should_receive(:close).once.with(false)
|
1269
|
+
flexmock(@docs[2]).should_receive(:close).never
|
1270
|
+
flexmock(@docs[1]).should_receive(:close).never
|
1271
|
+
other_view = @docs[2].create_view
|
1272
|
+
(@views[2] + [@views[1][0]]).each do |v|
|
1273
|
+
flexmock(v).should_receive(:close).once
|
1274
|
+
end
|
1275
|
+
@env.close_editors @views[0] + @views[2] + [@views[1][0]], false
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
context 'if the second argument is true' do
|
1281
|
+
|
1282
|
+
it 'calls MainWindow#save_documents passing all the documents whose views are all to be closed' do
|
1283
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).with([@docs[0], @docs[2]]).once
|
1284
|
+
@env.close_editors @views[0] + @views[2] + [@views[1][0]], true
|
1285
|
+
end
|
1286
|
+
|
1287
|
+
context 'if MainWindow#save_documents returns false' do
|
1288
|
+
|
1289
|
+
it 'does nothing' do
|
1290
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).and_return false
|
1291
|
+
@views.flatten.each{|v| flexmock(v).should_receive(:close).never}
|
1292
|
+
@docs.each{|d| flexmock(d).should_receive(:close).never}
|
1293
|
+
@env.close_editors @views[0] + @views[2] + [@views[1][0]], true
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
context 'if MainWindow#save_documents returns true' do
|
1299
|
+
|
1300
|
+
before do
|
1301
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).and_return true
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
it 'closes without asking all documents whose views are all to be closed' do
|
1305
|
+
flexmock(@docs[0]).should_receive(:close).once.with(false)
|
1306
|
+
flexmock(@docs[2]).should_receive(:close).once.with(false)
|
1307
|
+
flexmock(@docs[1]).should_receive(:close).never
|
1308
|
+
@env.close_editors @views[0] + @views[2] + [@views[1][0]], true
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
it 'closes the editors associated with documents having some views not to be closed' do
|
1312
|
+
flexmock(@docs[0]).should_receive(:close).once.with(false)
|
1313
|
+
flexmock(@docs[2]).should_receive(:close).never
|
1314
|
+
flexmock(@docs[1]).should_receive(:close).never
|
1315
|
+
other_view = @docs[2].create_view
|
1316
|
+
(@views[2] + [@views[1][0]]).each do |v|
|
1317
|
+
flexmock(v).should_receive(:close).once
|
1318
|
+
end
|
1319
|
+
@env.close_editors @views[0] + @views[2] + [@views[1][0]], true
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
end
|
1325
|
+
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
describe '#display_document' do
|
1329
|
+
|
1330
|
+
before do
|
1331
|
+
@doc = Ruber[:world].new_document
|
1332
|
+
end
|
1333
|
+
|
1334
|
+
it 'retrieves an editor for the given document according to the hints' do
|
1335
|
+
ed = @env.editor_for! @doc
|
1336
|
+
hints = {:existing => :always, :strategy => :last}
|
1337
|
+
flexmock(@env).should_receive(:editor_for!).with(@doc, hints).once.and_return ed
|
1338
|
+
@env.display_document @doc, hints
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
it 'activates the editor' do
|
1342
|
+
ed = @env.editor_for! @doc
|
1343
|
+
hints = {:existing => :always, :strategy => :last}
|
1344
|
+
@env.display_document @doc, hints
|
1345
|
+
@env.active_editor.should == ed
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
it 'moves the cursor to the line and column corresponding to the :line and :column hints' do
|
1349
|
+
ed = @env.editor_for! @doc
|
1350
|
+
flexmock(ed).should_receive(:go_to).with(10, 6).once
|
1351
|
+
hints = {:existing => :always, :strategy => :last, :line => 10, :column => 6}
|
1352
|
+
@env.display_document @doc, hints
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
it 'uses 0 as column hint if the line hint is given and the column hint is not' do
|
1356
|
+
ed = @env.editor_for! @doc
|
1357
|
+
flexmock(ed).should_receive(:go_to).with(10, 0).once
|
1358
|
+
hints = {:existing => :always, :strategy => :last, :line => 10}
|
1359
|
+
@env.display_document @doc, hints
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
it 'doesn\'t move the cursor if the line hint is not given' do
|
1363
|
+
ed = @env.editor_for! @doc
|
1364
|
+
flexmock(ed).should_receive(:go_to).never
|
1365
|
+
hints = {:existing => :always, :strategy => :last}
|
1366
|
+
@env.display_document @doc, hints
|
1367
|
+
hints[:column] = 4
|
1368
|
+
@env.display_document @doc, hints
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
it 'returns the editor' do
|
1372
|
+
ed = @env.display_document @doc
|
1373
|
+
ed.should be_a(Ruber::EditorView)
|
1374
|
+
ed.document.should == @doc
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
context 'when a view receives focus' do
|
1380
|
+
|
1381
|
+
it 'is made active' do
|
1382
|
+
doc = Ruber[:world].new_document
|
1383
|
+
@views = 2.times.map{@env.editor_for! doc, :existing => :never}
|
1384
|
+
@env.activate_editor @views[0]
|
1385
|
+
@views[1].instance_eval{emit focus_in(self)}
|
1386
|
+
@env.active_editor.should == @views[1]
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
context 'when the close button on a tab is pressed' do
|
1392
|
+
|
1393
|
+
before do
|
1394
|
+
Ruber[:world].close_all :documents, :discard
|
1395
|
+
@doc = Ruber[:world].new_document
|
1396
|
+
@views = 3.times.map{@env.editor_for! @doc, :existing => :never, :new => :current_tab}
|
1397
|
+
@other_view = @env.editor_for! @doc, :existing => :never, :new => :new_tab
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
it 'closes all the editors in the tab' do
|
1401
|
+
flexmock(@env).should_receive(:close_editors).once.with(FlexMock.on{|a| a.sort_by(&:object_id) == @views.sort_by(&:object_id)})
|
1402
|
+
@env.tab_widget.instance_eval{emit tabCloseRequested(0)}
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
it 'does nothing if the user chooses to abort the operation' do
|
1406
|
+
flexmock(Ruber::MainWindow).should_receive(:save_documents).and_return false
|
1407
|
+
@views.each{|v| flexmock(v).should_receive(:close).never}
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
context 'when a view is split' do
|
1413
|
+
|
1414
|
+
before do
|
1415
|
+
@doc = Ruber[:world].new_document
|
1416
|
+
@view = @env.editor_for! @doc
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
it 'adds the new view to the list' do
|
1420
|
+
new_view = @doc.create_view
|
1421
|
+
@env.tab(@view).split @view, new_view, Qt::Vertical
|
1422
|
+
@env.views.should include(new_view)
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
it 'adds the document associated with the view to the list of documents, if needed' do
|
1426
|
+
doc = Ruber[:world].new_document
|
1427
|
+
new_view = doc.create_view
|
1428
|
+
@env.tab(@view).split @view, new_view, Qt::Vertical
|
1429
|
+
@env.documents.should include(doc)
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
it 'updates the tool tip of the tab' do
|
1433
|
+
doc = Ruber[:world].new_document
|
1434
|
+
new_view = doc.create_view
|
1435
|
+
@env.tab(@view).split @view, new_view, Qt::Vertical
|
1436
|
+
exp = @doc.document_name + "\n" + doc.document_name
|
1437
|
+
@env.tab_widget.tab_tool_tip(0).should == exp
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
it 'reacts to the view getting focus' do
|
1441
|
+
new_view = @doc.create_view
|
1442
|
+
@env.tab(@view).split @view, new_view, Qt::Vertical
|
1443
|
+
new_view.instance_eval{emit focus_in(self)}
|
1444
|
+
@env.active_editor.should == new_view
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
it 'reacts to the view being closed' do
|
1448
|
+
new_view = @doc.create_view
|
1449
|
+
@env.tab(@view).split @view, new_view, Qt::Vertical
|
1450
|
+
new_view.close
|
1451
|
+
@env.views.should_not include(new_view)
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
context 'when a view is replaced by another' do
|
1457
|
+
|
1458
|
+
before do
|
1459
|
+
@doc = Ruber[:world].new_document
|
1460
|
+
@view = @env.editor_for! @doc
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
it 'adds the new view to the list' do
|
1464
|
+
new_view = @doc.create_view
|
1465
|
+
@env.tab(@view).replace_view @view, new_view
|
1466
|
+
@env.views.should include(new_view)
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
it 'removes the replaced view from the list' do
|
1470
|
+
new_view = @doc.create_view
|
1471
|
+
@env.tab(@view).replace_view @view, new_view
|
1472
|
+
@env.views.should_not include(@view)
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
it 'adds the document associated with the view to the list of documents, if needed' do
|
1476
|
+
doc = Ruber[:world].new_document
|
1477
|
+
new_view = doc.create_view
|
1478
|
+
@env.tab(@view).replace_view @view, new_view
|
1479
|
+
@env.documents.should include(doc)
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
it 'removes the document associated with the replaced view if it was the only view associated with it in the environment' do
|
1483
|
+
doc = Ruber[:world].new_document
|
1484
|
+
new_view = doc.create_view
|
1485
|
+
@env.tab(@view).replace_view @view, new_view
|
1486
|
+
@env.documents.should_not include(@doc)
|
1487
|
+
end
|
1488
|
+
|
1489
|
+
it 'doesn\'t remove the document associated with the replaced view if it wasn\'t the only view associated with it in the environment' do
|
1490
|
+
doc = Ruber[:world].new_document
|
1491
|
+
new_view = doc.create_view
|
1492
|
+
@env.editor_for! @doc, :existing => :never, :new => :new_tab
|
1493
|
+
@env.tab(@view).replace_view @view, new_view
|
1494
|
+
@env.documents.should include(@doc)
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
it 'updates the tool tip of the tab' do
|
1498
|
+
doc = Ruber[:world].new_document
|
1499
|
+
new_view = doc.create_view
|
1500
|
+
@env.tab(@view).replace_view @view, new_view
|
1501
|
+
exp = doc.document_name
|
1502
|
+
@env.tab_widget.tab_tool_tip(0).should == exp
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
it 'reacts to the new view getting focus' do
|
1506
|
+
new_view = @doc.create_view
|
1507
|
+
@env.tab(@view).replace_view @view, new_view
|
1508
|
+
new_view.instance_eval{emit focus_in(self)}
|
1509
|
+
@env.active_editor.should == new_view
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
it 'doesn\'t react to the replaced view getting focus' do
|
1513
|
+
new_view = @doc.create_view
|
1514
|
+
@env.tab(@view).replace_view @view, new_view
|
1515
|
+
@env.activate_editor nil
|
1516
|
+
@view.instance_eval{emit focus_in(self)}
|
1517
|
+
@env.active_editor.should be_nil
|
1518
|
+
end
|
1519
|
+
|
1520
|
+
it 'reacts to the view being closed' do
|
1521
|
+
new_view = @doc.create_view
|
1522
|
+
@env.tab(@view).replace_view @view, new_view
|
1523
|
+
new_view.close
|
1524
|
+
@env.views.should_not include(new_view)
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
it 'doesn\'t react to the replaced view being closed anymore' do
|
1528
|
+
new_view = @doc.create_view
|
1529
|
+
@env.tab(@view).replace_view @view, new_view
|
1530
|
+
flexmock(@env).should_receive(:editor_closing).never
|
1531
|
+
@view.close
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
end
|
1535
|
+
|
1536
|
+
context 'when the URL of a document changes' do
|
1537
|
+
|
1538
|
+
before do
|
1539
|
+
@doc = Ruber[:world].new_document
|
1540
|
+
end
|
1541
|
+
|
1542
|
+
context 'if the document is associated with a view in the environment' do
|
1543
|
+
|
1544
|
+
before do
|
1545
|
+
@views = 2.times.map{@env.editor_for! @doc, :existing => :never}
|
1546
|
+
@url = KDE::Url.new __FILE__
|
1547
|
+
flexmock(@doc).should_receive(:url).and_return @url
|
1548
|
+
flexmock(@doc).should_receive(:document_name).and_return File.basename(__FILE__)
|
1549
|
+
flexmock(@doc).should_receive(:path).and_return(__FILE__)
|
1550
|
+
end
|
1551
|
+
|
1552
|
+
it 'updates the tool tip of the tabs containing views associated with the document' do
|
1553
|
+
@doc.instance_eval{emit document_url_changed(self)}
|
1554
|
+
@env.tab_widget.to_a.each_index{|i|@env.tab_widget.tab_tool_tip(i).should == File.basename(__FILE__)}
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
it 'updates the label of the editors associated with the document' do
|
1558
|
+
@doc.instance_eval{emit document_url_changed(self)}
|
1559
|
+
@views.each{|v| v.parent.label.should == @url.path}
|
1560
|
+
end
|
1561
|
+
|
1562
|
+
it 'updates the text amd icon of any tabs having a view associated with the document as last activated view' do
|
1563
|
+
pix = Qt::Pixmap.new(16,16)
|
1564
|
+
pix.fill Qt::Color.new(Qt.blue)
|
1565
|
+
icon = Qt::Icon.new pix
|
1566
|
+
flexmock(@doc).should_receive(:icon).and_return icon
|
1567
|
+
other_doc = Ruber[:world].new_document
|
1568
|
+
other_views = 2.times.map{|i| @env.editor_for! other_doc, :existing => :never, :new => @views[i]}
|
1569
|
+
@env.activate_editor other_views[1]
|
1570
|
+
@doc.instance_eval{emit document_url_changed(self)}
|
1571
|
+
@env.tab_widget.tab_text(0).should == File.basename(__FILE__)
|
1572
|
+
@env.tab_widget.tab_icon(0).pixmap(16,16).to_image.should == pix.to_image
|
1573
|
+
@env.tab_widget.tab_text(1).should == other_doc.document_name
|
1574
|
+
@env.tab_widget.tab_icon(1).pixmap(16,16).to_image.should_not == pix.to_image
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
end
|
1580
|
+
|
1581
|
+
describe 'when the modified status of a document associated with a view in the environment changes' do
|
1582
|
+
|
1583
|
+
before do
|
1584
|
+
@doc = Ruber[:world].new_document
|
1585
|
+
@other_doc = Ruber[:world].new_document
|
1586
|
+
@views = 2.times.map{@env.editor_for! @doc, :existing => :never}
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
context 'if the document has become modified' do
|
1590
|
+
|
1591
|
+
after do
|
1592
|
+
@doc.close false
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
it 'updates the label of the views associated with the document by putting [modified] after the name of the document' do
|
1596
|
+
other_views=2.times.map{@env.editor_for! @other_doc, :existing => :never}
|
1597
|
+
@doc.text = 'x'
|
1598
|
+
@views.each do |v|
|
1599
|
+
v.parent.label.should == @doc.document_name + ' [modified]'
|
1600
|
+
end
|
1601
|
+
other_views.each do |v|
|
1602
|
+
v.parent.label.should == @other_doc.document_name
|
1603
|
+
end
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
it 'updates the icon of any tabs having a view associated with the document as last activated view' do
|
1607
|
+
img = Ruber::Document::ICONS[:modified].pixmap(16,16).to_image
|
1608
|
+
other_views = 2.times.map{|i| @env.editor_for! @other_doc, :existing => :never, :new => @views[i]}
|
1609
|
+
@env.activate_editor other_views[1]
|
1610
|
+
@doc.text = 'x'
|
1611
|
+
@env.tab_widget.tab_icon(0).pixmap(16,16).to_image.should == img
|
1612
|
+
@env.tab_widget.tab_icon(1).pixmap(16,16).to_image.should_not == img
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
context 'if the document has become not modified' do
|
1618
|
+
|
1619
|
+
before do
|
1620
|
+
@doc.text = 'x'
|
1621
|
+
end
|
1622
|
+
|
1623
|
+
after do
|
1624
|
+
@doc.close false
|
1625
|
+
end
|
1626
|
+
|
1627
|
+
it 'updates the label of the views associated with the document' do
|
1628
|
+
other_views=2.times.map{@env.editor_for! @other_doc, :existing => :never}
|
1629
|
+
@doc.modified = false
|
1630
|
+
@views.each do |v|
|
1631
|
+
v.parent.label.should == @doc.document_name
|
1632
|
+
end
|
1633
|
+
other_views.each do |v|
|
1634
|
+
v.parent.label.should == @other_doc.document_name
|
1635
|
+
end
|
1636
|
+
end
|
1637
|
+
|
1638
|
+
it 'updates the icon of any tabs having a view associated with the document as last activated view' do
|
1639
|
+
img = Ruber::Document::ICONS[:modified].pixmap(16,16).to_image
|
1640
|
+
other_views = 2.times.map{|i| @env.editor_for! @other_doc, :existing => :never, :new => @views[i]}
|
1641
|
+
@env.activate_editor other_views[1]
|
1642
|
+
@doc.modified = false
|
1643
|
+
@env.tab_widget.tab_icon(0).pixmap(16,16).to_image.should_not == img
|
1644
|
+
@env.tab_widget.tab_icon(1).pixmap(16,16).to_image.should_not == img
|
1645
|
+
end
|
1646
|
+
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
describe "#focus_on_editors?" do
|
1652
|
+
|
1653
|
+
before do
|
1654
|
+
@views = Array.new(3){@env.editor_for! @doc, :existing => :never}
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
it 'returns true if one of the views in the environment received focus after the last one lost focus' do
|
1658
|
+
@views[1].instance_eval{emit focus_out(self)}
|
1659
|
+
@views[2].instance_eval{emit focus_in(self)}
|
1660
|
+
@env.focus_on_editors?.should be_true
|
1661
|
+
end
|
1662
|
+
|
1663
|
+
it 'returns false if no view in the environment got focus after the last one
|
1664
|
+
lost focus' do
|
1665
|
+
@env.activate_editor @views[1]
|
1666
|
+
flexmock(@views[1]).should_receive(:is_active_window).once.and_return true
|
1667
|
+
@views[1].instance_eval{emit focus_out(self)}
|
1668
|
+
@env.focus_on_editors?.should be_false
|
1669
|
+
end
|
1670
|
+
|
1671
|
+
it 'returns true if there are no views' do
|
1672
|
+
@views.each{|v| @env.close_editor v, false}
|
1673
|
+
@env.focus_on_editors?.should be_true
|
1674
|
+
end
|
1675
|
+
|
1676
|
+
end
|
1677
|
+
|
1678
|
+
describe '#query_save' do
|
1679
|
+
|
1680
|
+
before do
|
1681
|
+
@docs = Array.new(3){Ruber[:world].new_document}
|
1682
|
+
2.times{@env.editor_for! @docs[0], :existing => :never}
|
1683
|
+
2.times{@env.editor_for! @docs[1], :existing => :never}
|
1684
|
+
@docs[1].create_view
|
1685
|
+
2.times{@docs[2].create_view}
|
1686
|
+
end
|
1687
|
+
|
1688
|
+
context 'if the application\'s status is different from :asking_to_quit' do
|
1689
|
+
|
1690
|
+
before do
|
1691
|
+
flexmock(Ruber[:app]).should_receive(:status).and_return(:running)
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
it 'calls MainWindow#save_documents passing all the documents not having views outside the environment' do
|
1695
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).once.with([@docs[0]])
|
1696
|
+
@env.query_close
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
it 'returns the value returned by MainWindow#save_documents' do
|
1700
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).once.and_return(false)
|
1701
|
+
@env.query_close.should == false
|
1702
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).once.and_return(true)
|
1703
|
+
@env.query_close.should == true
|
1704
|
+
end
|
1705
|
+
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
context 'if the application\'s status is from :asking_to_quit' do
|
1709
|
+
|
1710
|
+
before do
|
1711
|
+
flexmock(Ruber[:app]).should_receive(:status).and_return(:asking_to_quit)
|
1712
|
+
end
|
1713
|
+
|
1714
|
+
it 'doesn\'t call MainWindow#save_documents' do
|
1715
|
+
flexmock(Ruber[:main_window]).should_receive(:save_documents).never
|
1716
|
+
@env.query_close
|
1717
|
+
end
|
1718
|
+
|
1719
|
+
it 'returns true' do
|
1720
|
+
@env.query_close.should == true
|
1721
|
+
end
|
1722
|
+
|
1723
|
+
end
|
1724
|
+
|
1725
|
+
end
|
1726
|
+
|
1727
|
+
describe '#remove_from_project' do
|
1728
|
+
|
1729
|
+
context 'if the environment is associated with a project' do
|
1730
|
+
|
1731
|
+
before do
|
1732
|
+
@file = File.join Dir.tmpdir, 'environment_remove_from_project_test'
|
1733
|
+
@project = Ruber::Project.new @file, "Test"
|
1734
|
+
@env = Ruber::World::Environment.new @project
|
1735
|
+
@docs = 4.times.map{Ruber[:world].new_document}
|
1736
|
+
@env_views = []
|
1737
|
+
@env_views += 2.times.map{@env.editor_for! @docs[0], :existing => :never}
|
1738
|
+
@env_views += 3.times.map{@env.editor_for! @docs[1], :existing => :never}
|
1739
|
+
@env_views += 3.times.map{@env.editor_for! @docs[2], :existing => :never}
|
1740
|
+
@other_views = [@docs[2].create_view, @docs[3].create_view]
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
it 'emits the closing signal passing itself as argument' do
|
1744
|
+
mk = flexmock{|m| m.should_receive(:env_closing).once.with(@env.object_id)}
|
1745
|
+
@env.connect(SIGNAL('closing(QObject*)')){|e| mk.env_closing e.object_id}
|
1746
|
+
@env.remove_from_project
|
1747
|
+
end
|
1748
|
+
|
1749
|
+
it 'deactivates itself' do
|
1750
|
+
@env.activate
|
1751
|
+
@env.remove_from_project
|
1752
|
+
@env.should_not be_active
|
1753
|
+
end
|
1754
|
+
|
1755
|
+
it 'closes all the documents whose views are all contained in the environment without asking' do
|
1756
|
+
2.times{|i| flexmock(@docs[i]).should_receive(:close).with(false).once}
|
1757
|
+
2.upto(3){|i| flexmock(@docs[i]).should_receive(:close).never}
|
1758
|
+
@env.remove_from_project
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
it 'closes all the views in the environment whose documents have views not associated with the enviroment without closing their documents' do
|
1762
|
+
flexmock(@docs[2]).should_receive(:close).never
|
1763
|
+
@env_views.each{|v| flexmock(v).should_receive(:close).once if v.document == @docs[2]}
|
1764
|
+
@env.remove_from_project
|
1765
|
+
end
|
1766
|
+
|
1767
|
+
end
|
1768
|
+
|
1769
|
+
context 'if the environment is not associated with a project' do
|
1770
|
+
|
1771
|
+
it 'raises RuntimeError' do
|
1772
|
+
lambda{@env.remove_from_project}.should raise_error(RuntimeError, "environment not associated with a project")
|
1773
|
+
end
|
1774
|
+
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
end
|
1778
|
+
|
1779
|
+
describe '#replace_editor' do
|
1780
|
+
|
1781
|
+
before do
|
1782
|
+
Ruber[:world].close_all :all, :discard
|
1783
|
+
@old_view = @env.editor_for! __FILE__
|
1784
|
+
|
1785
|
+
@new_view = Ruber[:world].new_document.create_view
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
it 'replaces the editor given as first argument with the one given as second argument' do
|
1789
|
+
flexmock(@old_view.parent).should_receive(:replace_view).with(@old_view, @new_view).once
|
1790
|
+
@env.replace_editor @old_view, @new_view
|
1791
|
+
end
|
1792
|
+
|
1793
|
+
it 'returns the new editor' do
|
1794
|
+
@env.replace_editor(@old_view, @new_view).should == @new_view
|
1795
|
+
end
|
1796
|
+
|
1797
|
+
context 'if the view to replace is the last view associated with its document' do
|
1798
|
+
|
1799
|
+
it 'calls the document\'s query_close method before replacing the view' do
|
1800
|
+
flexmock(@old_view.document).should_receive(:query_close).globally.ordered.once.and_return true
|
1801
|
+
flexmock(@old_view.parent).should_receive(:replace_view).with(@old_view, @new_view).once.globally.ordered
|
1802
|
+
@env.replace_editor @old_view, @new_view
|
1803
|
+
end
|
1804
|
+
|
1805
|
+
it 'does nothing if the document\'s query_close method returns false' do
|
1806
|
+
flexmock(@old_view.document).should_receive(:query_close).and_return false
|
1807
|
+
flexmock(@old_view.parent).should_receive(:replace_view).with(@old_view, @new_view).never
|
1808
|
+
@env.replace_editor @old_view, @new_view
|
1809
|
+
end
|
1810
|
+
|
1811
|
+
it 'closes the document after replacing the view' do
|
1812
|
+
mk = flexmock do |m|
|
1813
|
+
m.should_receive(:document_closing).with(@old_view.document).once
|
1814
|
+
end
|
1815
|
+
@old_view.document.connect(SIGNAL('closing(QObject*)')) do |doc|
|
1816
|
+
mk.document_closing doc
|
1817
|
+
end
|
1818
|
+
@env.replace_editor @old_view, @new_view
|
1819
|
+
end
|
1820
|
+
|
1821
|
+
end
|
1822
|
+
|
1823
|
+
context 'if the view to replace is not the last associated with its document' do
|
1824
|
+
|
1825
|
+
before do
|
1826
|
+
@other_view = @old_view.document.create_view
|
1827
|
+
end
|
1828
|
+
|
1829
|
+
it 'doesn\'t call the query_close method of the document associated with the view to replace' do
|
1830
|
+
flexmock(@old_view.document).should_receive(:query_close).never
|
1831
|
+
@env.replace_editor @old_view, @new_view
|
1832
|
+
end
|
1833
|
+
|
1834
|
+
it 'doesn\'t close the document associated with the view to replace' do
|
1835
|
+
mk = flexmock do |m|
|
1836
|
+
m.should_receive(:document_closing).with(@old_view.document).never
|
1837
|
+
end
|
1838
|
+
@old_view.document.connect(SIGNAL('closing(QObject*)')) do |doc|
|
1839
|
+
mk.document_closing doc
|
1840
|
+
end
|
1841
|
+
@env.replace_editor @old_view, @new_view
|
1842
|
+
end
|
1843
|
+
|
1844
|
+
it 'closes the replaced editor' do
|
1845
|
+
flexmock(@old_view).should_receive(:close).once
|
1846
|
+
@env.replace_editor @old_view, @new_view
|
1847
|
+
end
|
1848
|
+
|
1849
|
+
end
|
1850
|
+
|
1851
|
+
context 'if the second argument is a Document' do
|
1852
|
+
|
1853
|
+
before do
|
1854
|
+
@new_view = nil
|
1855
|
+
@doc = Ruber[:world].new_document
|
1856
|
+
end
|
1857
|
+
|
1858
|
+
it 'creates a new view for the document using the document\'s create_view method' do
|
1859
|
+
view = @doc.create_view
|
1860
|
+
flexmock(@doc).should_receive(:create_view).once.and_return view
|
1861
|
+
flexmock(@env).should_receive(:editor_for!).never
|
1862
|
+
flexmock(@old_view.parent).should_receive(:replace_view).once.with(@old_view, view)
|
1863
|
+
@env.replace_editor @old_view, @doc
|
1864
|
+
end
|
1865
|
+
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
context 'if the second argument is a String' do
|
1869
|
+
|
1870
|
+
it 'creates a new view for the document associated to that string' do
|
1871
|
+
file = '/xyz/abc.rb'
|
1872
|
+
doc = Ruber[:world].new_document
|
1873
|
+
flexmock(Ruber[:world]).should_receive(:document).with(file).once.and_return doc
|
1874
|
+
view = doc.create_view
|
1875
|
+
flexmock(doc).should_receive(:create_view).once.and_return view
|
1876
|
+
flexmock(@env).should_receive(:editor_for!).never
|
1877
|
+
flexmock(@old_view.parent).should_receive(:replace_view).once.with(@old_view, view)
|
1878
|
+
@env.replace_editor @old_view, file
|
1879
|
+
end
|
1880
|
+
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
context 'if the second argument is a KDE::Url' do
|
1884
|
+
|
1885
|
+
it 'creates a new view for the document associated to that string' do
|
1886
|
+
url = KDE::Url.new 'file:///xyz/abc.rb'
|
1887
|
+
doc = Ruber[:world].new_document
|
1888
|
+
flexmock(Ruber[:world]).should_receive(:document).with(url).once.and_return doc
|
1889
|
+
view = doc.create_view
|
1890
|
+
flexmock(doc).should_receive(:create_view).once.and_return view
|
1891
|
+
flexmock(@env).should_receive(:editor_for!).never
|
1892
|
+
flexmock(@old_view.parent).should_receive(:replace_view).once.with(@old_view, view)
|
1893
|
+
@env.replace_editor @old_view, url
|
1894
|
+
end
|
1895
|
+
|
1896
|
+
end
|
1897
|
+
|
1898
|
+
end
|
1899
|
+
|
1900
|
+
end
|