ruber 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +25 -0
- data/bin/ruber +0 -0
- data/data/share/apps/ruber/ruberui.rc +15 -1
- data/data/share/icons/{ruber.png → ruber-old.pgn} +0 -0
- data/lib/ruber/application/application.rb +216 -73
- data/lib/ruber/application/plugin.yaml +2 -2
- data/lib/ruber/document_project.rb +25 -5
- data/lib/ruber/documents/document_list.rb +11 -15
- data/lib/ruber/editor/document.rb +106 -50
- data/lib/ruber/editor/editor_view.rb +4 -2
- data/lib/ruber/external_program_plugin.rb +8 -0
- data/lib/ruber/kde_config_option_backend.rb +12 -4
- data/lib/ruber/kde_sugar.rb +35 -1
- data/lib/ruber/main_window/choose_plugins_dlg.rb +10 -10
- data/lib/ruber/main_window/hint_solver.rb +263 -0
- data/lib/ruber/main_window/main_window.rb +462 -206
- data/lib/ruber/main_window/main_window_actions.rb +228 -62
- data/lib/ruber/main_window/main_window_internal.rb +169 -115
- data/lib/ruber/main_window/plugin.yaml +13 -3
- data/lib/ruber/main_window/save_modified_files_dlg.rb +1 -1
- data/lib/ruber/main_window/ui/choose_plugins_widget.rb +1 -1
- data/lib/ruber/main_window/ui/main_window_settings_widget.rb +1 -1
- data/lib/ruber/main_window/ui/new_project_widget.rb +1 -1
- data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +1 -1
- data/lib/ruber/main_window/ui/output_color_widget.rb +1 -1
- data/lib/ruber/main_window/ui/workspace_settings_widget.rb +51 -0
- data/lib/ruber/main_window/ui/workspace_settings_widget.ui +28 -0
- data/lib/ruber/main_window/view_manager.rb +418 -0
- data/lib/ruber/main_window/workspace.png +0 -0
- data/lib/ruber/output_widget.rb +43 -37
- data/lib/ruber/pane.rb +621 -0
- data/lib/ruber/plugin_specification_reader.rb +8 -1
- data/lib/ruber/projects/project_files_list.rb +6 -0
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +1 -1
- data/lib/ruber/projects/ui/project_files_widget.rb +1 -1
- data/lib/ruber/qt_sugar.rb +94 -4
- data/lib/ruber/utils.rb +16 -7
- data/lib/ruber/version.rb +2 -2
- data/plugins/autosave/autosave.rb +62 -1
- data/plugins/autosave/plugin.yaml +1 -0
- data/plugins/autosave/ui/autosave_config_widget.rb +37 -14
- data/plugins/autosave/ui/autosave_config_widget.ui +62 -12
- data/plugins/find_in_files/find_in_files_widgets.rb +1 -3
- data/plugins/find_in_files/ui/config_widget.rb +1 -1
- data/plugins/find_in_files/ui/find_in_files_widget.rb +1 -1
- data/plugins/rake/plugin.yaml +1 -1
- data/plugins/rake/ui/add_quick_task_widget.rb +1 -1
- data/plugins/rake/ui/choose_task_widget.rb +1 -1
- data/plugins/rake/ui/config_widget.rb +1 -1
- data/plugins/rake/ui/project_widget.rb +1 -1
- data/plugins/rspec/rspec.rb +14 -22
- data/plugins/rspec/ruber_rspec_formatter.rb +4 -1
- data/plugins/rspec/ui/rspec_project_widget.rb +1 -1
- data/plugins/ruby_development/plugin.yaml +7 -2
- data/plugins/ruby_development/ruby_development.rb +134 -13
- data/plugins/ruby_development/ui/config_widget.rb +66 -0
- data/plugins/ruby_development/ui/config_widget.ui +58 -0
- data/plugins/ruby_development/ui/project_widget.rb +1 -1
- data/plugins/ruby_runner/plugin.yaml +2 -2
- data/plugins/ruby_runner/ruby_runner.rb +15 -3
- data/plugins/ruby_runner/ui/config_widget.rb +1 -1
- data/plugins/ruby_runner/ui/project_widget.rb +1 -1
- data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +1 -1
- data/plugins/state/plugin.yaml +6 -2
- data/plugins/state/state.rb +305 -81
- data/plugins/state/ui/config_widget.rb +1 -1
- data/spec/common.rb +11 -3
- data/spec/document_list_spec.rb +8 -8
- data/spec/document_project_spec.rb +98 -25
- data/spec/document_spec.rb +178 -152
- data/spec/editor_view_spec.rb +26 -5
- data/spec/framework.rb +5 -0
- data/spec/hint_solver_spec.rb +450 -0
- data/spec/kde_sugar_spec.rb +73 -6
- data/spec/output_widget_spec.rb +172 -156
- data/spec/pane_spec.rb +1165 -0
- data/spec/plugin_specification_reader_spec.rb +37 -1
- data/spec/project_files_list_spec.rb +30 -20
- data/spec/qt_sugar_spec.rb +269 -0
- data/spec/state_spec.rb +566 -353
- data/spec/utils_spec.rb +1 -1
- data/spec/view_manager_spec.rb +71 -0
- metadata +16 -4
@@ -53,7 +53,7 @@ module Ruber
|
|
53
53
|
@reader.process_pdf({}).should eql(@info)
|
54
54
|
end
|
55
55
|
|
56
|
-
it '
|
56
|
+
it 'requires all files obtained by joining the PluginSpecification\'s directory with the files returned by the read_required method, before calling the read_required method' do
|
57
57
|
@info.directory = '/xyz'
|
58
58
|
flexmock(@reader).should_receive(:read_required).and_return %w[a b]
|
59
59
|
flexmock(@reader).should_receive(:require).globally.ordered.once.with '/xyz/a'
|
@@ -61,6 +61,15 @@ module Ruber
|
|
61
61
|
flexmock(@reader).should_receive(:read_ui_file).globally.ordered.once.and_return 'testui.rc'
|
62
62
|
@reader.process_pdf({})
|
63
63
|
end
|
64
|
+
|
65
|
+
it 'loads files returned by the read_required method rather than require them if they end in .rb' do
|
66
|
+
@info.directory = '/xyz'
|
67
|
+
flexmock(@reader).should_receive(:read_required).and_return %w[a b.rb]
|
68
|
+
flexmock(@reader).should_receive(:require).globally.ordered.once.with '/xyz/a'
|
69
|
+
flexmock(@reader).should_receive(:load).globally.ordered.once.with '/xyz/b.rb'
|
70
|
+
flexmock(@reader).should_receive(:read_ui_file).globally.ordered.once.and_return 'testui.rc'
|
71
|
+
@reader.process_pdf({})
|
72
|
+
end
|
64
73
|
|
65
74
|
end
|
66
75
|
|
@@ -1651,6 +1660,33 @@ describe Ruber::PluginSpecificationReader do
|
|
1651
1660
|
|
1652
1661
|
end
|
1653
1662
|
|
1663
|
+
context ', when reading the place' do
|
1664
|
+
|
1665
|
+
it 'puts the contents of the place entry of the argument in the :place entry of the returned hash' do
|
1666
|
+
@reader.send(:read_rules, {:place => [:local]})[:place].should == [:local]
|
1667
|
+
@reader.send(:read_rules, {'place' => [:remote]})[:place].should == [:remote]
|
1668
|
+
end
|
1669
|
+
|
1670
|
+
it 'converts the values :all and all to [:local, :remote]' do
|
1671
|
+
@reader.send(:read_rules, {:place => ['all']})[:place].should == [:local, :remote]
|
1672
|
+
@reader.send(:read_rules, {'place' => [:all]})[:place].should == [:local, :remote]
|
1673
|
+
end
|
1674
|
+
|
1675
|
+
it 'encloses the place entry of the argument in a array, unless it\'s already an array' do
|
1676
|
+
@reader.send(:read_rules, {:place => :local})[:place].should == [:local]
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
it 'converts each entry of the place array to a symbol' do
|
1680
|
+
@reader.send(:read_rules, {:place => %w[local remote]})[:place].should == [:local, :remote]
|
1681
|
+
end
|
1682
|
+
|
1683
|
+
it 'uses [:local] as default value' do
|
1684
|
+
@reader.send(:read_rules, {})[:place].should == [:local]
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
end
|
1688
|
+
|
1689
|
+
|
1654
1690
|
describe ', when reading the mimetype' do
|
1655
1691
|
|
1656
1692
|
it 'stores the contents of the mimetype entry of the argument in the returned value' do
|
@@ -131,49 +131,49 @@ describe 'Ruber::ProjectFilesList' do
|
|
131
131
|
FileUtils.rm_f @dir
|
132
132
|
end
|
133
133
|
|
134
|
-
it '
|
134
|
+
it 'updates the cache if it\'s not up to date' do
|
135
135
|
@list.instance_variable_set :@up_to_date, false
|
136
136
|
flexmock(@list).should_receive(:refresh).once
|
137
137
|
@list.project_files
|
138
138
|
end
|
139
139
|
|
140
|
-
it '
|
140
|
+
it 'doesn\'t update the cache if it\'s already up to date' do
|
141
141
|
@list.instance_variable_set :@up_to_date, true
|
142
142
|
flexmock(@list).should_receive(:refresh).never
|
143
143
|
@list.project_files
|
144
144
|
end
|
145
145
|
|
146
|
-
it '
|
146
|
+
it 'returns an array containing all the files corresponding to include rules of type path unless they also correspond to an exclude rule of type path' do
|
147
147
|
@prj[:general, :project_files] = {:include => ['README', 'COPYING', 'f1.rb', 'd2/CHANGELOG', 'd2/f21.rb'], :exclude => ['COPYING', 'd2/f21.rb'], :extensions => []}
|
148
148
|
@list.project_files(false).should =~ %w[README f1.rb d2/CHANGELOG]
|
149
149
|
end
|
150
150
|
|
151
|
-
it '
|
151
|
+
it 'doesn\'t include in the returned array files which don\'t exist' do
|
152
152
|
@prj[:general, :project_files] = {:include => ['README1', 'COPYING', 'f1.rb', 'd2/CHANGELOG', 'd2/f211.rb'], :exclude => ['COPYING'], :extensions => []}
|
153
153
|
@list.project_files(false).should =~ %w[f1.rb d2/CHANGELOG]
|
154
154
|
end
|
155
155
|
|
156
|
-
it '
|
156
|
+
it 'skips include rules of type path corresponding to directories' do
|
157
157
|
@prj[:general, :project_files] = {:include => ['README', 'COPYING', 'f1.rb', 'd2/CHANGELOG', 'd2/f21.rb', 'd3'], :exclude => ['COPYING', 'd2/f21.rb'], :extensions => []}
|
158
158
|
@list.project_files(false).should =~ %w[README f1.rb d2/CHANGELOG]
|
159
159
|
end
|
160
160
|
|
161
|
-
it '
|
161
|
+
it 'includes all the files in the project directory which correspond to one of the extensions in the returned array, unless they match one of the exclude rule' do
|
162
162
|
@prj[:general, :project_files] = {:include => [], :exclude => ['COPYING', 'd2/f21.rb'], :extensions => %w[*.rb]}
|
163
163
|
@list.project_files(false).should =~ %w[f1.rb d2/f22.rb d3/f31.rb d3/f32.rb]
|
164
164
|
end
|
165
165
|
|
166
|
-
it '
|
166
|
+
it 'includes all the files in the project directory which match one of the include rules of type regexp and don\'t match any exclude rule' do
|
167
167
|
@prj[:general, :project_files] = {:include => [%r{d3/.*}, %r{.*\.yaml}], :exclude => [%r{d3/.*2.*}, %r{.*1.*\.rb}], :extensions => []}
|
168
168
|
@list.project_files(false).should =~ %w[d2/f22.yaml f1.yaml d2/f21.yaml]
|
169
169
|
end
|
170
170
|
|
171
|
-
it '
|
171
|
+
it 'doesn\'t include duplicate elements' do
|
172
172
|
@prj[:general, :project_files] = {:include => [%r{d2/.*}, 'f1.rb'], :exclude => [], :extensions => ['*.rb']}
|
173
173
|
@list.project_files(false).should =~ %w[f1.rb d2/f21.rb d2/f22.rb d2/f21.yaml d2/f22.yaml d2/CHANGELOG d3/f31.rb d3/f32.rb]
|
174
174
|
end
|
175
175
|
|
176
|
-
it '
|
176
|
+
it 'returns a deep copy of the cache object' do
|
177
177
|
@prj[:general, :project_files] = {:include => [%r{d2/.*}, 'f1.rb'], :exclude => [], :extensions => ['*.rb']}
|
178
178
|
old_cache = @list.instance_variable_get(:@project_files).deep_copy
|
179
179
|
res = @list.project_files(false)
|
@@ -182,12 +182,12 @@ describe 'Ruber::ProjectFilesList' do
|
|
182
182
|
@list.instance_variable_get(:@project_files).should == old_cache
|
183
183
|
end
|
184
184
|
|
185
|
-
it '
|
185
|
+
it 'returns full paths if the argument is true' do
|
186
186
|
@prj[:general, :project_files] = {:include => [%r{d2/.*}, 'f1.rb'], :exclude => [], :extensions => ['*.rb']}
|
187
187
|
@list.project_files(true).should =~ %w[f1.rb d2/f21.rb d2/f22.rb d2/f21.yaml d2/f22.yaml d2/CHANGELOG d3/f31.rb d3/f32.rb].map{|i| File.join @dir, i}
|
188
188
|
end
|
189
189
|
|
190
|
-
it '
|
190
|
+
it 'returns the correct list if a file or directory is added or deleted after the file watcher has been created' do
|
191
191
|
@prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => ['*.rb']}
|
192
192
|
# Experiments show that KDE::DirWatch needs an event loop to work. Since we don't have one running, we'll have to make it emit the 'dirty' signal manually
|
193
193
|
watcher = @list.instance_variable_get(:@watcher)
|
@@ -213,7 +213,7 @@ describe 'Ruber::ProjectFilesList' do
|
|
213
213
|
watcher.instance_eval{emit dirty( @dir)}
|
214
214
|
@list.project_files(false).should_not include("f1.rb")
|
215
215
|
end
|
216
|
-
|
216
|
+
|
217
217
|
end
|
218
218
|
|
219
219
|
describe 'Ruber::ProjectFilesList#each' do
|
@@ -344,41 +344,41 @@ describe 'Ruber::ProjectFilesList' do
|
|
344
344
|
@prj.add_extension :file_lister, @list
|
345
345
|
end
|
346
346
|
|
347
|
-
it '
|
347
|
+
it 'returns true if the argument matches one of the exact include rules' do
|
348
348
|
@prj[:general, :project_files] = {:include => %w[./xyz ./abc ./123], :exclude => [], :extensions => ['*.rb']}
|
349
349
|
@list.file_in_project?(File.join(@prj.project_dir, 'abc')).should be_true
|
350
350
|
end
|
351
351
|
|
352
|
-
it '
|
352
|
+
it 'returns true if the argument matches one of the regexp include rules' do
|
353
353
|
@prj[:general, :project_files] = {:include => [/a/, /x/], :exclude => [], :extensions => ['*.rb']}
|
354
354
|
@list.file_in_project?(File.join(@prj.project_dir, 'xyz')).should be_true
|
355
355
|
end
|
356
356
|
|
357
|
-
it '
|
357
|
+
it 'returns true if the argument matches one of the include extensions' do
|
358
358
|
@prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => ['*.rb', '*.yaml']}
|
359
359
|
@list.file_in_project?(File.join(@prj.project_dir, 'abc.rb')).should be_true
|
360
360
|
end
|
361
361
|
|
362
|
-
it '
|
362
|
+
it 'returns false if the file isn\'t in the project directory' do
|
363
363
|
@prj[:general, :project_files] = {:include => %w[xyz abc 123], :exclude => [], :extensions => ['*.rb']}
|
364
364
|
@list.file_in_project?('/usr/abc').should be_false
|
365
365
|
end
|
366
366
|
|
367
|
-
it '
|
367
|
+
it 'treats the argument as a path relative to the project directory if it isn\'t an absolute path' do
|
368
368
|
@prj[:general, :project_files] = {:include => %w[xyz abc 123], :exclude => [], :extensions => ['*.rb']}
|
369
369
|
@list.file_in_project?('abc').should be_true
|
370
370
|
end
|
371
371
|
|
372
|
-
it '
|
372
|
+
it 'returns false if the file doesn\'t match any include rule' do
|
373
373
|
@list.file_in_project?(File.join(@prj.project_dir, 'abc.rb')).should be_false
|
374
374
|
end
|
375
375
|
|
376
|
-
it '
|
376
|
+
it 'returns false if the file matches one of the file exclude rules' do
|
377
377
|
@prj[:general, :project_files] = {:include => %w[xyz abc 123], :exclude => ['abc'], :extensions => ['*.rb']}
|
378
378
|
@list.file_in_project?(File.join(@prj.project_dir, 'abc')).should be_false
|
379
379
|
end
|
380
380
|
|
381
|
-
it '
|
381
|
+
it 'returns false if the file matches one of the exclude regexps' do
|
382
382
|
@prj[:general, :project_files] = {:include => [/a/], :exclude => [/a/], :extensions => []}
|
383
383
|
@list.file_in_project?(File.join(@prj.project_dir, 'abc')).should be_false
|
384
384
|
end
|
@@ -394,6 +394,16 @@ describe 'Ruber::ProjectFilesList' do
|
|
394
394
|
@list.file_in_project?('xyz/').should be_nil
|
395
395
|
end
|
396
396
|
|
397
|
+
it 'returns false if the path represents a remote URL' do
|
398
|
+
@prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => ['*.rb']}
|
399
|
+
@list.file_in_project?("http://#{@dir}/abc.xyz.rb").should be_false
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'works normally if the path represents a local url' do
|
403
|
+
@prj[:general, :project_files] = {:include => [], :exclude => [], :extensions => ['*.rb']}
|
404
|
+
@list.file_in_project?("file://#{@dir}/abc.xyz.rb").should be_true
|
405
|
+
end
|
406
|
+
|
397
407
|
end
|
398
408
|
|
399
409
|
end
|
data/spec/qt_sugar_spec.rb
CHANGED
@@ -326,3 +326,272 @@ describe Qt::Variant, '#to_bool' do
|
|
326
326
|
end
|
327
327
|
|
328
328
|
end
|
329
|
+
|
330
|
+
describe Qt::Layout do
|
331
|
+
|
332
|
+
it 'includes QtEnumerable' do
|
333
|
+
Qt::Layout.ancestors.should include(QtEnumerable)
|
334
|
+
end
|
335
|
+
|
336
|
+
describe '#each' do
|
337
|
+
|
338
|
+
it 'passes to the block each widget in turn if called with a block' do
|
339
|
+
#Since Qt::Layout is an abstract class, we fake calls to count and item_at,
|
340
|
+
#which are pure virtual, with mocks
|
341
|
+
w = Qt::Widget.new
|
342
|
+
layout = Qt::Layout.new w
|
343
|
+
w.layout = layout
|
344
|
+
widgets = [Qt::PushButton, Qt::VBoxLayout, Qt::CheckBox].map{|c| c.new}
|
345
|
+
res = []
|
346
|
+
flexmock(layout).should_receive(:count).once.and_return(3)
|
347
|
+
flexmock(layout).should_receive(:item_at).with(0).once.and_return(Qt::WidgetItem.new(widgets[0]))
|
348
|
+
flexmock(layout).should_receive(:item_at).with(1).once.and_return(widgets[1])
|
349
|
+
flexmock(layout).should_receive(:item_at).with(2).once.and_return(Qt::WidgetItem.new(widgets[2]))
|
350
|
+
layout.each{|w| res << w}
|
351
|
+
res.should == widgets
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'returns an enumerator if no block is given' do
|
355
|
+
w = Qt::Widget.new
|
356
|
+
layout = Qt::Layout.new w
|
357
|
+
w.layout = layout
|
358
|
+
widgets = [Qt::PushButton, Qt::VBoxLayout, Qt::CheckBox].map{|c| c.new}
|
359
|
+
res = []
|
360
|
+
flexmock(layout).should_receive(:count).once.and_return(3)
|
361
|
+
flexmock(layout).should_receive(:item_at).with(0).once.and_return(Qt::WidgetItem.new(widgets[0]))
|
362
|
+
flexmock(layout).should_receive(:item_at).with(1).once.and_return(widgets[1])
|
363
|
+
flexmock(layout).should_receive(:item_at).with(2).once.and_return(Qt::WidgetItem.new(widgets[2]))
|
364
|
+
e = layout.each
|
365
|
+
e.each{|w| res << w}
|
366
|
+
res.should == widgets
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
372
|
+
|
373
|
+
shared_examples_for 'any box layout' do
|
374
|
+
|
375
|
+
it 'includes QtEnumerable' do
|
376
|
+
@layout.class.ancestors.should include(QtEnumerable)
|
377
|
+
end
|
378
|
+
|
379
|
+
it 'has an each method which passes to the block each widget in turn if called with a block' do
|
380
|
+
w = Qt::Widget.new
|
381
|
+
w.layout = @layout
|
382
|
+
widgets = [Qt::PushButton, Qt::VBoxLayout, Qt::CheckBox].map{|c| c.new}
|
383
|
+
widgets.each{|w| @layout.send w.is_a?(Qt::Widget) ? :add_widget : :add_layout, w}
|
384
|
+
res = []
|
385
|
+
@layout.each{|w| res << w}
|
386
|
+
res.should == widgets
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'has an each method which returns an enumerator if no block is given' do
|
390
|
+
w = Qt::Widget.new
|
391
|
+
w.layout = @layout
|
392
|
+
widgets = [Qt::PushButton, Qt::VBoxLayout, Qt::CheckBox].map{|c| c.new}
|
393
|
+
res = []
|
394
|
+
widgets.each{|w| @layout.send w.is_a?(Qt::Widget) ? :add_widget : :add_layout, w}
|
395
|
+
e = @layout.each
|
396
|
+
e.each{|w| res << w}
|
397
|
+
res.should == widgets
|
398
|
+
end
|
399
|
+
|
400
|
+
end
|
401
|
+
|
402
|
+
describe Qt::BoxLayout do
|
403
|
+
|
404
|
+
before do
|
405
|
+
@layout = Qt::BoxLayout.new(Qt::Horizontal)
|
406
|
+
end
|
407
|
+
|
408
|
+
it_behaves_like 'any box layout'
|
409
|
+
|
410
|
+
end
|
411
|
+
|
412
|
+
describe Qt::VBoxLayout do
|
413
|
+
|
414
|
+
before do
|
415
|
+
@layout = Qt::VBoxLayout.new
|
416
|
+
end
|
417
|
+
|
418
|
+
it_behaves_like 'any box layout'
|
419
|
+
|
420
|
+
end
|
421
|
+
|
422
|
+
describe Qt::HBoxLayout do
|
423
|
+
|
424
|
+
before do
|
425
|
+
@layout = Qt::HBoxLayout.new
|
426
|
+
end
|
427
|
+
|
428
|
+
it_behaves_like 'any box layout'
|
429
|
+
|
430
|
+
end
|
431
|
+
|
432
|
+
describe Qt::StackedLayout do
|
433
|
+
|
434
|
+
before do
|
435
|
+
@layout = Qt::StackedLayout.new
|
436
|
+
end
|
437
|
+
|
438
|
+
it 'includes QtEnumerable' do
|
439
|
+
@layout.class.ancestors.should include(QtEnumerable)
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'has an each method which passes to the block each widget in turn if called with a block' do
|
443
|
+
w = Qt::Widget.new
|
444
|
+
w.layout = @layout
|
445
|
+
widgets = [Qt::PushButton, Qt::LineEdit, Qt::CheckBox].map{|c| c.new}
|
446
|
+
widgets.each{|w| @layout.add_widget w}
|
447
|
+
res = []
|
448
|
+
@layout.each{|w| res << w}
|
449
|
+
res.should == widgets
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'has an each method which returns an enumerator if no block is given' do
|
453
|
+
w = Qt::Widget.new
|
454
|
+
w.layout = @layout
|
455
|
+
widgets = [Qt::PushButton, Qt::LineEdit, Qt::CheckBox].map{|c| c.new}
|
456
|
+
res = []
|
457
|
+
widgets.each{|w| @layout.add_widget w}
|
458
|
+
e = @layout.each
|
459
|
+
e.each{|w| res << w}
|
460
|
+
res.should == widgets
|
461
|
+
end
|
462
|
+
|
463
|
+
end
|
464
|
+
|
465
|
+
describe Qt::FormLayout do
|
466
|
+
|
467
|
+
before do
|
468
|
+
@layout = Qt::FormLayout.new
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'includes QtEnumerable' do
|
472
|
+
@layout.class.ancestors.should include(QtEnumerable)
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'has an each method which passes to the block each widget in turn if called with a block' do
|
476
|
+
w = Qt::Widget.new
|
477
|
+
w.layout = @layout
|
478
|
+
widgets = [['l1', Qt::PushButton], ['l2', Qt::LineEdit], ['l3', Qt::CheckBox]].map{|c| [Qt::Label.new(c[0]), c[1].new]}
|
479
|
+
widgets.each{|w| @layout.add_row w[0], w[1]}
|
480
|
+
res = []
|
481
|
+
@layout.each{|w| res << w}
|
482
|
+
res.should == widgets.flatten
|
483
|
+
end
|
484
|
+
|
485
|
+
it 'has an each method which returns an enumerator if no block is given' do
|
486
|
+
w = Qt::Widget.new
|
487
|
+
w.layout = @layout
|
488
|
+
widgets = [['l1', Qt::PushButton], ['l2', Qt::LineEdit], ['l3', Qt::CheckBox]].map{|c| [Qt::Label.new(c[0]), c[1].new]}
|
489
|
+
widgets.each{|w| @layout.add_row w[0], w[1]}
|
490
|
+
res = []
|
491
|
+
e = @layout.each
|
492
|
+
e.each{|w| res << w}
|
493
|
+
res.should == widgets.flatten
|
494
|
+
end
|
495
|
+
|
496
|
+
end
|
497
|
+
|
498
|
+
describe Qt::GridLayout do
|
499
|
+
|
500
|
+
before do
|
501
|
+
@layout = Qt::GridLayout.new
|
502
|
+
end
|
503
|
+
|
504
|
+
it 'includes QtEnumerable' do
|
505
|
+
@layout.class.ancestors.should include(QtEnumerable)
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'has an each method which passes to the block each widget in turn if called with a block' do
|
509
|
+
w = Qt::Widget.new
|
510
|
+
w.layout = @layout
|
511
|
+
widgets = [[Qt::TextEdit, Qt::HBoxLayout], [Qt::Label, Qt::LineEdit], [Qt::VBoxLayout, Qt::CheckBox]].map{|c1, c2| [c1.new, c2.new]}
|
512
|
+
add = lambda{|w, r, c|w.is_a?(Qt::Widget) ? @layout.add_widget(w, r, c) : @layout.add_layout(w, r, c) }
|
513
|
+
widgets.each_with_index do |w, r|
|
514
|
+
add.call w[0], r, 0
|
515
|
+
add.call w[1], r, 1
|
516
|
+
end
|
517
|
+
res = []
|
518
|
+
@layout.each{|w| res << w}
|
519
|
+
res.should == widgets.flatten
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'has an each method which returns an enumerator if no block is given' do
|
523
|
+
w = Qt::Widget.new
|
524
|
+
w.layout = @layout
|
525
|
+
widgets = [[Qt::TextEdit, Qt::HBoxLayout], [Qt::Label, Qt::LineEdit], [Qt::VBoxLayout, Qt::CheckBox]].map{|c1, c2| [c1.new, c2.new]}
|
526
|
+
add = lambda{|w, r, c|w.is_a?(Qt::Widget) ? @layout.add_widget(w, r, c) : @layout.add_layout(w, r, c) }
|
527
|
+
widgets.each_with_index do |w, r|
|
528
|
+
add.call w[0], r, 0
|
529
|
+
add.call w[1], r, 1
|
530
|
+
end
|
531
|
+
res = []
|
532
|
+
e = @layout.each
|
533
|
+
e.each{|w| res << w}
|
534
|
+
res.should == widgets.flatten
|
535
|
+
end
|
536
|
+
|
537
|
+
it 'passes widgets spanning more than one row or column only once' do
|
538
|
+
w = Qt::Widget.new
|
539
|
+
w.layout = @layout
|
540
|
+
widgets = [[Qt::TextEdit, Qt::HBoxLayout], [Qt::LineEdit], [Qt::VBoxLayout, Qt::CheckBox]].map do |c1, c2|
|
541
|
+
c2 ? [c1.new, c2.new] : [c1.new]
|
542
|
+
end
|
543
|
+
add = lambda{|w, r, c, r1, c1|w.is_a?(Qt::Widget) ? @layout.add_widget(w, r, c, r1, c1) : @layout.add_layout(w, r, c, r1, c1) }
|
544
|
+
widgets.each_with_index do |w, r|
|
545
|
+
if w.size == 1
|
546
|
+
add.call w[0], r, 0, r, 1
|
547
|
+
else
|
548
|
+
add.call w[0], r, 0, r, 0
|
549
|
+
add.call w[1], r, 1, r, 1
|
550
|
+
end
|
551
|
+
end
|
552
|
+
res = []
|
553
|
+
@layout.each{|w| res << w}
|
554
|
+
res.should == widgets.flatten
|
555
|
+
end
|
556
|
+
|
557
|
+
end
|
558
|
+
|
559
|
+
describe Qt::Splitter do
|
560
|
+
|
561
|
+
it 'includes the QtEnumerable module' do
|
562
|
+
Qt::Splitter.ancestors.should include(QtEnumerable)
|
563
|
+
end
|
564
|
+
|
565
|
+
describe '#each' do
|
566
|
+
|
567
|
+
before do
|
568
|
+
@splitter = Qt::Splitter.new Qt::Vertical
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'calls the block each widget in the splitter' do
|
572
|
+
widgets = [Qt::LineEdit, Qt::PushButton, Qt::Label].map{|cls| cls.new}
|
573
|
+
widgets.reverse_each{|w| @splitter.add_widget w}
|
574
|
+
res = []
|
575
|
+
@splitter.each{|w| res << w}
|
576
|
+
res.should == widgets.reverse
|
577
|
+
end
|
578
|
+
|
579
|
+
it 'returns an enumerator if no block is given' do
|
580
|
+
widgets = [Qt::LineEdit, Qt::PushButton, Qt::Label].map{|cls| cls.new}
|
581
|
+
widgets.reverse_each{|w| @splitter.add_widget w}
|
582
|
+
res = []
|
583
|
+
enum = @splitter.each
|
584
|
+
enum.should be_an(Enumerator)
|
585
|
+
enum.each{|w| res << w}
|
586
|
+
res.should == widgets.reverse
|
587
|
+
end
|
588
|
+
|
589
|
+
it 'returns self if a block has been given' do
|
590
|
+
widgets = [Qt::LineEdit, Qt::PushButton, Qt::Label].map{|cls| cls.new}
|
591
|
+
widgets.reverse_each{|w| @splitter.add_widget w}
|
592
|
+
@splitter.each{}.should == @splitter
|
593
|
+
end
|
594
|
+
|
595
|
+
end
|
596
|
+
|
597
|
+
end
|