ruber 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|