ruber 0.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +339 -0
- data/INSTALL +137 -0
- data/LICENSE +8 -0
- data/bin/ruber +65 -0
- data/data/share/apps/ruber/core_components.yaml +31 -0
- data/data/share/apps/ruber/ruberui.rc +109 -0
- data/data/share/icons/ruber.png +0 -0
- data/data/share/pixmaps/ruby.png +0 -0
- data/icons/ruber-16.png +0 -0
- data/icons/ruber-32.png +0 -0
- data/icons/ruber-48.png +0 -0
- data/icons/ruber-8.png +0 -0
- data/lib/ruber/application/application.rb +288 -0
- data/lib/ruber/application/plugin.yaml +11 -0
- data/lib/ruber/component_manager.rb +899 -0
- data/lib/ruber/config/config.rb +82 -0
- data/lib/ruber/config/plugin.yaml +3 -0
- data/lib/ruber/document_project.rb +209 -0
- data/lib/ruber/documents/document_list.rb +416 -0
- data/lib/ruber/documents/plugin.yaml +4 -0
- data/lib/ruber/editor/document.rb +506 -0
- data/lib/ruber/editor/editor_view.rb +167 -0
- data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
- data/lib/ruber/exception_widgets.rb +245 -0
- data/lib/ruber/external_program_plugin.rb +397 -0
- data/lib/ruber/filtered_output_widget.rb +342 -0
- data/lib/ruber/gui_states_handler.rb +231 -0
- data/lib/ruber/kde_config_option_backend.rb +167 -0
- data/lib/ruber/kde_sugar.rb +249 -0
- data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
- data/lib/ruber/main_window/main_window.rb +524 -0
- data/lib/ruber/main_window/main_window_actions.rb +537 -0
- data/lib/ruber/main_window/main_window_internal.rb +239 -0
- data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
- data/lib/ruber/main_window/output_color_widget.rb +35 -0
- data/lib/ruber/main_window/plugin.yaml +58 -0
- data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
- data/lib/ruber/main_window/status_bar.rb +156 -0
- data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
- data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
- data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
- data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
- data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
- data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
- data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
- data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
- data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
- data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
- data/lib/ruber/main_window/workspace.rb +442 -0
- data/lib/ruber/output_widget.rb +1093 -0
- data/lib/ruber/plugin.rb +264 -0
- data/lib/ruber/plugin_like.rb +589 -0
- data/lib/ruber/plugin_specification.rb +106 -0
- data/lib/ruber/plugin_specification_reader.rb +451 -0
- data/lib/ruber/project.rb +493 -0
- data/lib/ruber/project_backend.rb +105 -0
- data/lib/ruber/projects/plugin.yaml +11 -0
- data/lib/ruber/projects/project_files_list.rb +314 -0
- data/lib/ruber/projects/project_files_widget.rb +301 -0
- data/lib/ruber/projects/project_list.rb +314 -0
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
- data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
- data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
- data/lib/ruber/qt_sugar.rb +673 -0
- data/lib/ruber/settings_container.rb +515 -0
- data/lib/ruber/settings_dialog.rb +244 -0
- data/lib/ruber/settings_dialog_manager.rb +503 -0
- data/lib/ruber/utils.rb +414 -0
- data/lib/ruber/yaml_option_backend.rb +159 -0
- data/outsider_files +15 -0
- data/plugins/autosave/autosave.rb +404 -0
- data/plugins/autosave/plugin.yaml +16 -0
- data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
- data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
- data/plugins/command/command.png +0 -0
- data/plugins/command/command.rb +74 -0
- data/plugins/command/plugin.yaml +11 -0
- data/plugins/find_in_files/find_in_files.rb +337 -0
- data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
- data/plugins/find_in_files/find_in_files_ui.rc +11 -0
- data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
- data/plugins/find_in_files/plugin.yaml +23 -0
- data/plugins/find_in_files/ui/config_widget.rb +58 -0
- data/plugins/find_in_files/ui/config_widget.ui +41 -0
- data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
- data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
- data/plugins/project_browser/plugin.yaml +10 -0
- data/plugins/project_browser/project_browser.rb +245 -0
- data/plugins/rake/plugin.yaml +39 -0
- data/plugins/rake/rake.png +0 -0
- data/plugins/rake/rake.rb +567 -0
- data/plugins/rake/rake_extension.rb +153 -0
- data/plugins/rake/rake_widgets.rb +615 -0
- data/plugins/rake/rakeui.rc +27 -0
- data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
- data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
- data/plugins/rake/ui/choose_task_widget.rb +77 -0
- data/plugins/rake/ui/choose_task_widget.ui +72 -0
- data/plugins/rake/ui/config_widget.rb +127 -0
- data/plugins/rake/ui/config_widget.ui +123 -0
- data/plugins/rake/ui/project_widget.rb +217 -0
- data/plugins/rake/ui/project_widget.ui +246 -0
- data/plugins/rspec/plugin.yaml +30 -0
- data/plugins/rspec/rspec.png +0 -0
- data/plugins/rspec/rspec.rb +945 -0
- data/plugins/rspec/rspec.svg +90 -0
- data/plugins/rspec/rspecui.rc +20 -0
- data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
- data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
- data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
- data/plugins/ruby_development/plugin.yaml +27 -0
- data/plugins/ruby_development/ruby_development.png +0 -0
- data/plugins/ruby_development/ruby_development.rb +453 -0
- data/plugins/ruby_development/ruby_developmentui.rc +19 -0
- data/plugins/ruby_development/ui/project_widget.rb +112 -0
- data/plugins/ruby_development/ui/project_widget.ui +108 -0
- data/plugins/ruby_runner/config_widget.rb +116 -0
- data/plugins/ruby_runner/plugin.yaml +26 -0
- data/plugins/ruby_runner/project_widget.rb +62 -0
- data/plugins/ruby_runner/ruby.png +0 -0
- data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
- data/plugins/ruby_runner/ruby_runner.rb +411 -0
- data/plugins/ruby_runner/ui/config_widget.rb +92 -0
- data/plugins/ruby_runner/ui/config_widget.ui +91 -0
- data/plugins/ruby_runner/ui/project_widget.rb +60 -0
- data/plugins/ruby_runner/ui/project_widget.ui +48 -0
- data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
- data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
- data/plugins/state/plugin.yaml +28 -0
- data/plugins/state/state.rb +520 -0
- data/plugins/state/ui/config_widget.rb +92 -0
- data/plugins/state/ui/config_widget.ui +89 -0
- data/plugins/syntax_checker/plugin.yaml +18 -0
- data/plugins/syntax_checker/syntax_checker.rb +662 -0
- data/ruber.desktop +10 -0
- data/spec/annotation_model_spec.rb +174 -0
- data/spec/common.rb +119 -0
- data/spec/component_manager_spec.rb +1259 -0
- data/spec/document_list_spec.rb +626 -0
- data/spec/document_project_spec.rb +373 -0
- data/spec/document_spec.rb +779 -0
- data/spec/editor_view_spec.rb +167 -0
- data/spec/external_program_plugin_spec.rb +676 -0
- data/spec/filtered_output_widget_spec.rb +642 -0
- data/spec/gui_states_handler_spec.rb +304 -0
- data/spec/kde_config_option_backend_spec.rb +214 -0
- data/spec/kde_sugar_spec.rb +101 -0
- data/spec/ktexteditor_wrapper_spec.rb +305 -0
- data/spec/output_widget_spec.rb +1703 -0
- data/spec/plugin_spec.rb +1393 -0
- data/spec/plugin_specification_reader_spec.rb +1765 -0
- data/spec/plugin_specification_spec.rb +401 -0
- data/spec/project_backend_spec.rb +172 -0
- data/spec/project_files_list_spec.rb +401 -0
- data/spec/project_list_spec.rb +511 -0
- data/spec/project_spec.rb +990 -0
- data/spec/qt_sugar_spec.rb +328 -0
- data/spec/settings_container_spec.rb +617 -0
- data/spec/settings_dialog_manager_spec.rb +773 -0
- data/spec/settings_dialog_spec.rb +419 -0
- data/spec/state_spec.rb +991 -0
- data/spec/utils_spec.rb +406 -0
- data/spec/workspace_spec.rb +869 -0
- data/spec/yaml_option_backend_spec.rb +246 -0
- metadata +284 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec/common'
|
2
|
+
|
3
|
+
require 'ruber/kde_sugar'
|
4
|
+
|
5
|
+
describe 'KDE::Url' do
|
6
|
+
|
7
|
+
it 'should be serializable using YAML' do
|
8
|
+
u = KDE::Url.new 'http:///xyz.org/a%20file%20with%20spaces.txt'
|
9
|
+
res = YAML.load(YAML.dump(u))
|
10
|
+
res.should == u
|
11
|
+
res.should_not equal(u)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be marshallable' do
|
15
|
+
u = KDE::Url.new 'http:///xyz.org/a%20file%20with%20spaces.txt'
|
16
|
+
res = Marshal.load(Marshal.dump(u))
|
17
|
+
res.should == u
|
18
|
+
res.should_not equal(u)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#local_file?' do
|
22
|
+
it "calls is_local_file" do
|
23
|
+
u = KDE::Url.new 'http://www.kde.org'
|
24
|
+
flexmock(u).should_receive(:is_local_file).once
|
25
|
+
u.local_file?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'KDE::MimeType#=~' do
|
32
|
+
|
33
|
+
before do
|
34
|
+
@mime = KDE::MimeType.mime_type 'application/x-ruby'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should return true if the mimetype is a child of the argument or if they\'re equal and false otherwise' do
|
38
|
+
(@mime =~ 'application/x-ruby').should be_true
|
39
|
+
(@mime =~ 'text/plain').should be_true
|
40
|
+
(@mime =~ 'text/x-python').should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should return invert the match if the argument starts with a !' do
|
44
|
+
(@mime =~ '!application/x-ruby').should be_false
|
45
|
+
(@mime =~ '!text/plain').should be_false
|
46
|
+
(@mime =~ '!text/x-python').should be_true
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should return true only if the argument is equal to the mimetype\'s name if the argument starts with =' do
|
50
|
+
(@mime =~ '=application/x-ruby').should be_true
|
51
|
+
(@mime =~ '=text/plain').should be_false
|
52
|
+
(@mime =~ '=text/x-python').should be_false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should make an exact match and invert it if the argument starts with != or =!' do
|
56
|
+
(@mime =~ '!=application/x-ruby').should be_false
|
57
|
+
(@mime =~ '!=text/plain').should be_true
|
58
|
+
(@mime =~ '!=text/x-python').should be_true
|
59
|
+
(@mime =~ '=!application/x-ruby').should be_false
|
60
|
+
(@mime =~ '=!text/plain').should be_true
|
61
|
+
(@mime =~ '=!text/x-python').should be_true
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe KDE::ComboBox do
|
67
|
+
|
68
|
+
before do
|
69
|
+
@combo = KDE::ComboBox.new
|
70
|
+
@combo.add_items %w[a b c d]
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#items' do
|
74
|
+
|
75
|
+
it 'returns an array containing the items in the combo box' do
|
76
|
+
@combo.items.should == %w[a b c d]
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#each' do
|
82
|
+
|
83
|
+
it 'calls the block passing each item in turn if a block is given' do
|
84
|
+
m = flexmock do |mk|
|
85
|
+
%w[a b c d].each{|i| mk.should_receive(:test).once.with(i).ordered}
|
86
|
+
end
|
87
|
+
@combo.each{|i| m.test i}
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns an enumerator whose each method passes each item in turn to the block' do
|
91
|
+
m = flexmock do |mk|
|
92
|
+
%w[a b c d].each{|i| mk.should_receive(:test).once.with(i).ordered}
|
93
|
+
end
|
94
|
+
enum = @combo.each
|
95
|
+
enum.should be_a(Enumerator)
|
96
|
+
enum.each{|i| m.test i}
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,305 @@
|
|
1
|
+
require 'spec/common'
|
2
|
+
|
3
|
+
require 'ktexteditor'
|
4
|
+
require 'ruber/editor/ktexteditor_wrapper'
|
5
|
+
|
6
|
+
describe Ruber::KTextEditorWrapper do
|
7
|
+
|
8
|
+
class SimpleWrapped < Qt::Object
|
9
|
+
|
10
|
+
include Ruber::KTextEditorWrapper
|
11
|
+
|
12
|
+
attr_reader :doc
|
13
|
+
def initialize
|
14
|
+
super
|
15
|
+
@doc = KTextEditor::EditorChooser.editor('katepart').create_document( self)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.prepare_wrapper_connections' do
|
21
|
+
|
22
|
+
it 'takes two arguments' do
|
23
|
+
lambda{Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, {}}.should_not raise_error
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'creates signals for the class given as first argument having the keys of the hash as names and the arguments obtained by rearranging the arguments of the wrapped signal as indicated in the second entry of the value' do
|
27
|
+
data = {
|
28
|
+
'first_signal' => ['QObject*, QString', [1, 0]],
|
29
|
+
'second_signal' => ['int, int, QObject*', [2,0,1]]
|
30
|
+
}
|
31
|
+
flexmock(SimpleWrapped).should_receive(:signals).once.with('first_signal(QString, QObject*)')
|
32
|
+
flexmock(SimpleWrapped).should_receive(:signals).once.with('second_signal(QObject*, int, int)')
|
33
|
+
Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, data
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'replaces nil with "QObject*" in the new argument list if the class isn\'t a Qt::Widget' do
|
37
|
+
data = {
|
38
|
+
'first_signal' => ['QObject*, QString', [1, 0, nil]],
|
39
|
+
}
|
40
|
+
flexmock(SimpleWrapped).should_receive(:signals).once.with('first_signal(QString, QObject*, QObject*)')
|
41
|
+
Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, data
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'replaces nil with "QWidget*" in the new argument list if the class is a Qt::Widget' do
|
45
|
+
data = {
|
46
|
+
'first_signal' => ['QObject*, QString', [1, 0, nil]],
|
47
|
+
}
|
48
|
+
flexmock(SimpleWrapped).should_receive(:ancestors).and_return [Qt::Widget, SimpleWrapped]
|
49
|
+
flexmock(SimpleWrapped).should_receive(:signals).once.with('first_signal(QString, QObject*, QWidget*)')
|
50
|
+
Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, data
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'creates a slot in the class passed as first argument for each entry in the hash which has the same argument list as the original signal and the name given by "__emit_sig_signal", wehere sig is the signal name' do
|
54
|
+
data = {
|
55
|
+
'first_signal' => ['QObject*, QString', [1, 0]],
|
56
|
+
'second_signal' => ['int, int, QObject*', [2,0,1]]
|
57
|
+
}
|
58
|
+
flexmock(SimpleWrapped).should_receive(:slots).once.with('__emit_first_signal_signal(QObject*, QString)')
|
59
|
+
flexmock(SimpleWrapped).should_receive(:slots).once.with('__emit_second_signal_signal(int, int, QObject*)')
|
60
|
+
Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, data
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'creates a method in the class with the same name passed to the slot which calls the corresponding signal using as argument those in the argument list, correctly sorted, and self where the second array in the entry has nil' do
|
64
|
+
data = {
|
65
|
+
'first_signal' => ['QObject*, QString', [1, 0]],
|
66
|
+
'second_signal' => ['int, int, QObject*', [2,0,1]],
|
67
|
+
'third_signal' => ['QString, KTextEditor::Document*', [nil, 0]]
|
68
|
+
}
|
69
|
+
methods = []
|
70
|
+
methods << <<-EOS
|
71
|
+
def __emit_first_signal_signal(a0, a1)
|
72
|
+
emit first_signal(a1, a0)
|
73
|
+
end
|
74
|
+
EOS
|
75
|
+
|
76
|
+
methods << <<-EOS
|
77
|
+
def __emit_second_signal_signal(a0, a1, a2)
|
78
|
+
emit second_signal(a2, a0, a1)
|
79
|
+
end
|
80
|
+
EOS
|
81
|
+
|
82
|
+
methods << <<-EOS
|
83
|
+
def __emit_third_signal_signal(a0, a1)
|
84
|
+
emit third_signal(self, a0)
|
85
|
+
end
|
86
|
+
EOS
|
87
|
+
|
88
|
+
methods.each{|m| flexmock(SimpleWrapped).should_receive(:class_eval).once.with(m)}
|
89
|
+
Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, data
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'returns a hash whose keys are the hash keys converted to camelcase and with the arguments added and whose entries are the names of the created slots' do
|
93
|
+
data = {
|
94
|
+
'first_signal' => ['QObject*, QString', [1, 0]],
|
95
|
+
'second_signal' => ['int, int, QObject*', [2,0,1]],
|
96
|
+
'third_signal' => ['QString', [nil, 0]]
|
97
|
+
}
|
98
|
+
res = Ruber::KTextEditorWrapper.prepare_wrapper_connections SimpleWrapped, data
|
99
|
+
exp = {
|
100
|
+
'firstSignal(QObject*, QString)' => '__emit_first_signal_signal(QObject*, QString)',
|
101
|
+
'secondSignal(int, int, QObject*)' => '__emit_second_signal_signal(int, int, QObject*)',
|
102
|
+
'thirdSignal(QString)' => '__emit_third_signal_signal(QString)',
|
103
|
+
}
|
104
|
+
res.should == exp
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#initialize_wrapper' do
|
110
|
+
|
111
|
+
before do
|
112
|
+
@w = SimpleWrapped.new
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'takes two arguments' do
|
116
|
+
lambda{@w.send :initialize_wrapper, Qt::Object.new, {}}.should_not raise_error
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'calls the connect_wrapped_signals method passing it the second argument' do
|
120
|
+
flexmock(@w).should_receive(:connect_wrapped_signals).once.with({'a' => 'b'})
|
121
|
+
@w.send :initialize_wrapper, Qt::Object.new, {'a' => 'b'}
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'creates an interface proxy passing it the argument' do
|
125
|
+
obj = Qt::Object.new
|
126
|
+
prx = Ruber::KTextEditorWrapper::InterfaceProxy.new obj
|
127
|
+
flexmock(Ruber::KTextEditorWrapper::InterfaceProxy).should_receive(:new).once.with(obj).and_return prx
|
128
|
+
@w.send :initialize_wrapper, obj, {}
|
129
|
+
@w.instance_variable_get(:@_interface).should be_a(Ruber::KTextEditorWrapper::InterfaceProxy)
|
130
|
+
@w.instance_variable_get(:@_wrapped).should equal(obj)
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#internal' do
|
136
|
+
|
137
|
+
before do
|
138
|
+
@w = SimpleWrapped.new
|
139
|
+
@w.send :initialize_wrapper, @w.doc, {}
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'returns the argument passed to initialize_wrapper' do
|
143
|
+
@w.send(:internal).should equal(@w.doc)
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
describe '#interface' do
|
150
|
+
|
151
|
+
before do
|
152
|
+
@w = SimpleWrapped.new
|
153
|
+
@w.send :initialize_wrapper, @w.doc, {}
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'sets the proxy\'s interface to the argument' do
|
157
|
+
@w.interface('modification_interface')
|
158
|
+
@w.instance_variable_get(:@_interface).instance_variable_get(:@interface).should be_a(KTextEditor::ModificationInterface)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'returns the proxy' do
|
162
|
+
@w.interface('modification_interface').should be_a(Ruber::KTextEditorWrapper::InterfaceProxy)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#connect_wrapped_signals' do
|
168
|
+
|
169
|
+
before do
|
170
|
+
@w = SimpleWrapped.new
|
171
|
+
def @w.connect *args
|
172
|
+
end
|
173
|
+
@w.send :initialize_wrapper, @w.doc, {}
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'takes one argument' do
|
177
|
+
lambda{@w.send :connect_wrapped_signals, {}}.should_not raise_error
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'calls the connect method of the wrapped object for each entry in the argument, using the wrapped object as sender and self as receiver' do
|
181
|
+
flexmock(@w).should_receive(:connect).once.with(@w.doc, SIGNAL('a'), @w, SLOT('b'))
|
182
|
+
flexmock(@w).should_receive(:connect).once.with(@w.doc, SIGNAL('c'), @w, SLOT('d'))
|
183
|
+
@w.send :connect_wrapped_signals, {'a' => 'b', 'c' => 'd'}
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#method_missing' do
|
189
|
+
|
190
|
+
before do
|
191
|
+
@w = SimpleWrapped.new
|
192
|
+
@w.send :initialize_wrapper, @w.doc, {}
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'attempts to call the superclass method' do
|
196
|
+
@w.objectName = 'xyz'
|
197
|
+
@w.object_name.should == 'xyz'
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'calls the method with the same name, arguments and block in the wrapped object if the superclass method raises NoMethodError' do
|
201
|
+
flexmock(@w.doc).should_receive(:test).with('xyz', Proc).once
|
202
|
+
@w.test('xyz'){puts 'xyz'}
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'calls the method with the same name, arguments and block in the wrapped object if the superclass method raises NameError' do
|
206
|
+
lambda{@w.instance_eval("text")}.should_not raise_error
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'calls the method with the same name, arguments and block in the wrapped object if the superclass method raises NotImplementedError' do
|
210
|
+
pending 'I don\'t remember when calling super causes a NotImplementedError exception, so I can\'t test this situation right now'
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
describe Ruber::KTextEditorWrapper::InterfaceProxy do
|
219
|
+
|
220
|
+
before do
|
221
|
+
@doc = KTextEditor::EditorChooser.editor('katepart').create_document(nil)
|
222
|
+
end
|
223
|
+
|
224
|
+
describe ', when created' do
|
225
|
+
|
226
|
+
it 'takes the wrapped object as argument and stores it' do
|
227
|
+
proxy = nil
|
228
|
+
lambda{proxy = Ruber::KTextEditorWrapper::InterfaceProxy.new @doc}.should_not raise_error
|
229
|
+
proxy.instance_variable_get(:@obj).should equal(@doc)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'has a nil interface' do
|
233
|
+
proxy = Ruber::KTextEditorWrapper::InterfaceProxy.new @doc
|
234
|
+
proxy.instance_variable_get(:@interface).should be_nil
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
describe '#interface=, when called with a string or symbol' do
|
240
|
+
|
241
|
+
before do
|
242
|
+
@proxy = Ruber::KTextEditorWrapper::InterfaceProxy.new @doc
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'stores the object cast to the interface obtained from the string passed as argument' do
|
246
|
+
@proxy.interface = 'mark_interface'
|
247
|
+
@proxy.instance_variable_get(:@interface).should be_a(KTextEditor::MarkInterface)
|
248
|
+
@proxy.interface = :modification_interface
|
249
|
+
@proxy.instance_variable_get(:@interface).should be_a(KTextEditor::ModificationInterface)
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
describe '#interface=, when called with a class' do
|
255
|
+
|
256
|
+
before do
|
257
|
+
@proxy = Ruber::KTextEditorWrapper::InterfaceProxy.new @doc
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'stores the object cast to the class given as argument' do
|
261
|
+
@proxy.interface = KTextEditor::MarkInterface
|
262
|
+
@proxy.instance_variable_get(:@interface).should be_a(KTextEditor::MarkInterface)
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#method_missing' do
|
268
|
+
|
269
|
+
class SimpleWrapped < Qt::Object
|
270
|
+
|
271
|
+
include Ruber::KTextEditorWrapper
|
272
|
+
|
273
|
+
attr_reader :doc
|
274
|
+
def initialize
|
275
|
+
super
|
276
|
+
@doc = KTextEditor::EditorChooser.editor('katepart').create_document( self)
|
277
|
+
initialize_wrapper @doc, {}
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
before do
|
283
|
+
@obj = SimpleWrapped.new
|
284
|
+
@proxy = Ruber::KTextEditorWrapper::InterfaceProxy.new @obj.doc
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'calls the same method on the stored interface' do
|
288
|
+
@proxy.interface = :modification_interface
|
289
|
+
lambda{@proxy.modified_on_disk_warning = true}.should_not raise_error
|
290
|
+
flexmock(@proxy.instance_variable_get(:@interface)).should_receive(:modified_on_disk_warning=).once.with(true)
|
291
|
+
@proxy.modified_on_disk_warning = true
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'replaces any argument whose class mixes-in Ruber::KTextEditorWrapper with the wrapped object' do
|
295
|
+
@proxy.interface = :modification_interface
|
296
|
+
#A method called test_method doesn't exist in the interface. However, this
|
297
|
+
#is enough to test that the @doc argument is converted to the correct class
|
298
|
+
#without my having to search for an actual method taking a document as argument
|
299
|
+
flexmock(@proxy.instance_variable_get(:@interface)).should_receive(:test_method).once.with(@obj.doc, true)
|
300
|
+
@proxy.test_method @obj, true
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
@@ -0,0 +1,1703 @@
|
|
1
|
+
require 'spec/common'
|
2
|
+
require 'ruber/output_widget'
|
3
|
+
|
4
|
+
describe Ruber::OutputWidget::ActionList do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@list = Ruber::OutputWidget::ActionList.new
|
8
|
+
@list << 'a' << 'b' << nil << 'c' << nil << 'd' << 'e' << nil << 'f' << 'g'
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#insert_after' do
|
12
|
+
|
13
|
+
describe ', when the first argument is an integer' do
|
14
|
+
|
15
|
+
it 'inserts the entries, in order, after a number of nil entries given by the first argument' do
|
16
|
+
@list.insert_after 2, 'x', 'y'
|
17
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'x', 'y', 'd', 'e', nil, 'f', 'g']
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'inserts the entries in order at the end of the list if the list contains less separators than requested' do
|
21
|
+
@list.insert_after 10, 'x', 'y'
|
22
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'd', 'e', nil, 'f', 'g', 'x', 'y']
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'when the first argument is a string' do
|
28
|
+
|
29
|
+
it 'inserts the entries, in order, after the first entry equal to the first argument' do
|
30
|
+
@list.insert_after 'd', 'x', 'y'
|
31
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'd', 'x', 'y', 'e', nil, 'f', 'g']
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'inserts the entries in order at the end of the list if the list doesn\'t contain the first argument' do
|
35
|
+
@list.insert_after 'z', 'x', 'y'
|
36
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'd', 'e', nil, 'f', 'g', 'x', 'y']
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#insert_before' do
|
44
|
+
|
45
|
+
describe ', when the first argument is an integer' do
|
46
|
+
|
47
|
+
it 'inserts the entries, in order, before the nth nil entry, where n is the first argument' do
|
48
|
+
@list.insert_before 2, 'x', 'y'
|
49
|
+
@list.should == ['a', 'b', nil, 'c', 'x', 'y', nil, 'd', 'e', nil, 'f', 'g']
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'inserts the entries in order at the end of the list if the list contains less separators than requested' do
|
53
|
+
@list.insert_before 10, 'x', 'y'
|
54
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'd', 'e', nil, 'f', 'g', 'x', 'y']
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'when the first argument is a string' do
|
60
|
+
|
61
|
+
it 'inserts the entries, in order, before the first entry equal to the first argument' do
|
62
|
+
@list.insert_before 'd', 'x', 'y'
|
63
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'x', 'y', 'd', 'e', nil, 'f', 'g']
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'inserts the entries in order at the end of the list if the list doesn\'t contain the first argument' do
|
67
|
+
@list.insert_before 'z', 'x', 'y'
|
68
|
+
@list.should == ['a', 'b', nil, 'c', nil, 'd', 'e', nil, 'f', 'g', 'x', 'y']
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe Ruber::OutputWidget do
|
78
|
+
|
79
|
+
it 'inherits from Qt::Widget' do
|
80
|
+
Ruber::OutputWidget.ancestors.should include(Qt::Widget)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'includes the GuiStatesHandler modules' do
|
84
|
+
Ruber::OutputWidget.ancestors.should include(Ruber::GuiStatesHandler)
|
85
|
+
end
|
86
|
+
|
87
|
+
describe ', when created' do
|
88
|
+
|
89
|
+
it 'can take up to two arguments' do
|
90
|
+
lambda{Ruber::OutputWidget.new}.should_not raise_error
|
91
|
+
lambda{Ruber::OutputWidget.new Qt::Widget.new}.should_not raise_error
|
92
|
+
lambda{Ruber::OutputWidget.new Qt::Widget.new, :view => :list}.should_not raise_error
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'has a grid layout' do
|
96
|
+
Ruber::OutputWidget.new.layout.should be_a(Qt::GridLayout)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'uses the object passed in the model option as model, if given' do
|
100
|
+
mod = Qt::StringListModel.new
|
101
|
+
ow = Ruber::OutputWidget.new(nil, :model => mod)
|
102
|
+
ow.model.should equal(mod)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'creates a model which is an instance of Ruber::OutputWidget::Model if the model option isn\'t given' do
|
106
|
+
ow = Ruber::OutputWidget.new
|
107
|
+
ow.model.should be_a(Ruber::OutputWidget::Model)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'makes sure the model contains at least one column' do
|
111
|
+
ow = Ruber::OutputWidget.new
|
112
|
+
ow.model.should be_a(Ruber::OutputWidget::Model)
|
113
|
+
ow.model.column_count.should >= 1
|
114
|
+
mod = Qt::StringListModel.new
|
115
|
+
ow = Ruber::OutputWidget.new nil, :model => mod
|
116
|
+
ow.model.column_count.should >= 1
|
117
|
+
mod = Qt::StringListModel.new
|
118
|
+
mod.insert_columns(0,5)
|
119
|
+
ow = Ruber::OutputWidget.new nil, :model => mod
|
120
|
+
ow.model.column_count.should >= 1
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'uses the content of the view option as view, if it\'s a Qt::Widget' do
|
124
|
+
v = Qt::TreeView.new
|
125
|
+
ow = Ruber::OutputWidget.new nil, :view => v
|
126
|
+
ow.view.should be_the_same_as(v)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'takes ownership of the view, if the view option is a Qt::Widget' do
|
130
|
+
v = Qt::TreeView.new
|
131
|
+
ow = Ruber::OutputWidget.new nil, :view => v
|
132
|
+
ow.view.parent.should be_the_same_as(ow)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'creates a new instance of class Ruber::OutputWidget::ListView and uses it as view if the view option is :list or is missing' do
|
136
|
+
w = Ruber::OutputWidget.new Qt::Widget.new, :view => :list
|
137
|
+
w.view.should be_a(Ruber::OutputWidget::ListView)
|
138
|
+
w.view.parent.should equal(w)
|
139
|
+
w = Ruber::OutputWidget.new
|
140
|
+
w.view.should be_a(Ruber::OutputWidget::ListView)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'creates a new instance of class Ruber::OutputWidget::ListView and uses it as view if the view option is :tree' do
|
144
|
+
w = Ruber::OutputWidget.new Qt::Widget.new, :view => :tree
|
145
|
+
w.view.should be_a(Ruber::OutputWidget::TreeView)
|
146
|
+
w.view.parent.should equal(w)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'creates an instance of class OutputWidget::TableView with parent self and stores it in the @view instance variable if the second argument is :table' do
|
150
|
+
w = Ruber::OutputWidget.new Qt::Widget.new, :view => :table
|
151
|
+
w.view.should be_a(Ruber::OutputWidget::TableView)
|
152
|
+
w.view.parent.should equal(w)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'inserts the view in the layout at position (0,0)' do
|
156
|
+
w = Ruber::OutputWidget.new
|
157
|
+
w.layout.item_at_position(0,0).widget.should be_a(Ruber::OutputWidget::ListView)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'sets the selection mode to Extended' do
|
161
|
+
w = Ruber::OutputWidget.new
|
162
|
+
w.view.selection_mode.should == Qt::AbstractItemView::ExtendedSelection
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'makes the view use the widget\'s model' do
|
166
|
+
w = Ruber::OutputWidget.new
|
167
|
+
w.view.model.should be_the_same_as(w.model)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'makes the model child of the view' do
|
171
|
+
mod = Qt::StandardItemModel.new
|
172
|
+
view = Qt::ListView.new
|
173
|
+
ow = Ruber::OutputWidget.new nil, :model => mod, :view => view
|
174
|
+
ow.model.parent.should be_the_same_as(view)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'connects the view\'s selection model\'s selectionChanged signal with its own selection_changed slot' do
|
178
|
+
ow = Ruber::OutputWidget.new
|
179
|
+
flexmock(ow).should_receive(:selection_changed).once.with(Qt::ItemSelection, Qt::ItemSelection)
|
180
|
+
ow.view.selection_model.instance_eval{emit selectionChanged(Qt::ItemSelection.new, Qt::ItemSelection.new)}
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'connects the view\'s "activated(QModelIndex)" signal with its "maybe_open_file(QModelIndex)" slot' do
|
184
|
+
ow = Ruber::OutputWidget.new
|
185
|
+
ow.model.append_row Qt::StandardItem.new('x')
|
186
|
+
flexmock(ow).should_receive(:maybe_open_file).once.with(ow.model.index(0,0))
|
187
|
+
ow.view.instance_eval{emit activated(ow.model.index(0,0))}
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'connects the model\'s rowsInserted signal with its own rows_changed slot' do
|
191
|
+
ow = Ruber::OutputWidget.new
|
192
|
+
flexmock(ow).should_receive(:rows_changed).once
|
193
|
+
ow.model.insertRows(0, 4)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'connects the model\'s rowsRemoved signal with its own rows_changed slot' do
|
197
|
+
ow = Ruber::OutputWidget.new
|
198
|
+
5.times{|i| ow.model.append_row Qt::StandardItem.new(i.to_s)}
|
199
|
+
flexmock(ow).should_receive(:rows_changed).once
|
200
|
+
ow.model.removeRows(0, 4)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'connects the model\'s rowsInserted signal to the do_auto_scroll slot' do
|
204
|
+
ow = Ruber::OutputWidget.new
|
205
|
+
flexmock(ow).should_receive(:do_auto_scroll).once.with(Qt::ModelIndex.new, 0, 3)
|
206
|
+
ow.model.insertRows(0, 4)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'connects the view\'s "context_menu_requested(QPoint)" signal with its "show_menu(QPoint)" slot' do
|
210
|
+
w = Ruber::OutputWidget.new
|
211
|
+
flexmock(w).should_receive(:show_menu).once.with(Qt::Point.new(2,3))
|
212
|
+
w.view.instance_eval{emit context_menu_requested(Qt::Point.new(2,3))}
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'has an empty menu' do
|
216
|
+
w = Ruber::OutputWidget.new
|
217
|
+
w.instance_variable_get(:@menu).should be_empty
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'calls the initialize_states_handler method' do
|
221
|
+
w = Ruber::OutputWidget.new
|
222
|
+
w.instance_variable_get(:@gui_state_handler_states).should be_a(Hash)
|
223
|
+
w.instance_variable_get(:@gui_state_handler_handlers).should be_a(Hash)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'inserts the "copy", "copy_selected" and "clear" entries in the action list' do
|
227
|
+
w = Ruber::OutputWidget.new
|
228
|
+
w.instance_variable_get(:@action_list).should == ['copy', 'copy_selected', nil, 'clear']
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'creates the actions for the "copy", "copy_selected" and "clear" entries' do
|
232
|
+
w = Ruber::OutputWidget.new
|
233
|
+
actions = w.instance_variable_get(:@actions)
|
234
|
+
actions['copy'].should be_a(KDE::Action)
|
235
|
+
actions['copy_selected'].should be_a(KDE::Action)
|
236
|
+
actions['clear'].should be_a(KDE::Action)
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'connects the "copy" action\'s triggered signal with its copy slot' do
|
240
|
+
w = Ruber::OutputWidget.new
|
241
|
+
flexmock(w).should_receive(:copy).once
|
242
|
+
w.instance_variable_get(:@actions)['copy'].instance_eval{emit triggered}
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'connects the "copy_selected" action\'s triggered signal with its copy_selected slot' do
|
246
|
+
w = Ruber::OutputWidget.new
|
247
|
+
flexmock(w).should_receive(:copy_selected).once
|
248
|
+
w.instance_variable_get(:@actions)['copy_selected'].instance_eval{emit triggered}
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'connects the "clear" action\'s triggered signal with its clear_output slot' do
|
252
|
+
w = Ruber::OutputWidget.new
|
253
|
+
flexmock(w).should_receive(:clear_output).once
|
254
|
+
w.instance_variable_get(:@actions)['clear'].instance_eval{emit triggered}
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'register handlers for the "copy", "copy_selected" and "clear" actions' do
|
258
|
+
w = Ruber::OutputWidget.new
|
259
|
+
handlers = w.instance_variable_get(:@gui_state_handler_handlers)
|
260
|
+
actions = w.instance_variable_get(:@actions)
|
261
|
+
handlers['no_text'].map(&:action).should == [actions['copy'], actions['copy_selected'], actions['clear']]
|
262
|
+
handlers['no_selection'].map(&:action).should == [actions['copy_selected']]
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'creates an handler which returns true if the no_text state is false and true otherwise for the "copy" action' do
|
266
|
+
w = Ruber::OutputWidget.new
|
267
|
+
handlers = w.instance_variable_get(:@gui_state_handler_handlers)
|
268
|
+
handlers['no_text'][0].handler.call('no_text' => true).should be_false
|
269
|
+
handlers['no_text'][0].handler.call('no_text' => false).should be_true
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'creates an handler which returns true only if both the no_text and no_selection states are false for the "copy_selected" action' do
|
273
|
+
w = Ruber::OutputWidget.new
|
274
|
+
handlers = w.instance_variable_get(:@gui_state_handler_handlers)
|
275
|
+
h = handlers['no_text'][1].handler
|
276
|
+
h.call('no_text' => true, 'no_selection' => true).should be_false
|
277
|
+
h.call('no_text' => false, 'no_selection' => true).should be_false
|
278
|
+
h.call('no_text' => true, 'no_selection' => false).should be_false
|
279
|
+
h.call('no_text' => false, 'no_selection' => false).should be_true
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'creates an handler which returns true if the no_text state is false and true otherwise for the "clear" action' do
|
283
|
+
w = Ruber::OutputWidget.new
|
284
|
+
handlers = w.instance_variable_get(:@gui_state_handler_handlers)
|
285
|
+
handlers['no_text'][2].handler.call('no_text' => true).should be_false
|
286
|
+
handlers['no_text'][2].handler.call('no_text' => false).should be_true
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'sets the "no_text" state to true' do
|
290
|
+
w = Ruber::OutputWidget.new
|
291
|
+
w.gui_state('no_text').should be_true
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'sets the "no_selection" state to true' do
|
295
|
+
w = Ruber::OutputWidget.new
|
296
|
+
w.gui_state('no_selection').should be_true
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'has no color registered' do
|
300
|
+
w = Ruber::OutputWidget.new
|
301
|
+
w.instance_variable_get(:@colors).should == {}
|
302
|
+
end
|
303
|
+
|
304
|
+
it 'has auto_scrolling enabled' do
|
305
|
+
w = Ruber::OutputWidget.new
|
306
|
+
w.auto_scroll.should be_true
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'has the ignore_word_wrap_option attribute set to false' do
|
310
|
+
w = Ruber::OutputWidget.new
|
311
|
+
w.ignore_word_wrap_option.should be_false
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'has no working dir' do
|
315
|
+
w = Ruber::OutputWidget.new
|
316
|
+
w.working_dir.should be_nil
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'sets the @skip_first_file_in_title instance variable to true' do
|
320
|
+
w = Ruber::OutputWidget.new
|
321
|
+
w.skip_first_file_in_title.should be_true
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'sets the @use_default_font to the value specified in opts' do
|
325
|
+
w = Ruber::OutputWidget.new nil, :use_default_font => true
|
326
|
+
w.instance_variable_get(:@use_default_font).should be_true
|
327
|
+
w = Ruber::OutputWidget.new nil
|
328
|
+
w.instance_variable_get(:@use_default_font).should be_nil
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
describe 'fill_menu' do
|
334
|
+
|
335
|
+
before do
|
336
|
+
@ow = Ruber::OutputWidget.new
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'emits the "about_to_fill_menu()" signal' do
|
340
|
+
m = flexmock{|mk| mk.should_receive(:setup_actions).once}
|
341
|
+
@ow.connect(SIGNAL(:about_to_fill_menu)){m.setup_actions}
|
342
|
+
@ow.send :fill_menu
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'inserts the actions and separators in the same order as they are in the @action_list instance variable, taking them from the @actions instance variable' do
|
346
|
+
menu = @ow.instance_variable_get(:@menu)
|
347
|
+
class << @ow
|
348
|
+
public :action_list, :actions
|
349
|
+
end
|
350
|
+
@ow.action_list.insert_before 'copy_selected', 'test1', nil, 'test2'
|
351
|
+
@ow.action_list << 'test3'
|
352
|
+
@ow.actions['test1'] = KDE::Action.new(nil)
|
353
|
+
@ow.actions['test2'] = KDE::Action.new(nil)
|
354
|
+
@ow.actions['test3'] = KDE::Action.new(nil)
|
355
|
+
flexmock(menu).should_receive(:add_action).with(@ow.actions['copy']).once.ordered
|
356
|
+
flexmock(menu).should_receive(:add_action).with(@ow.actions['test1']).once.ordered
|
357
|
+
flexmock(menu).should_receive(:add_separator).once.ordered
|
358
|
+
flexmock(menu).should_receive(:add_action).with(@ow.actions['test2']).once.ordered
|
359
|
+
flexmock(menu).should_receive(:add_action).with(@ow.actions['copy_selected']).once.ordered
|
360
|
+
flexmock(menu).should_receive(:add_separator).once.ordered
|
361
|
+
flexmock(menu).should_receive(:add_action).with(@ow.actions['clear']).once.ordered
|
362
|
+
flexmock(menu).should_receive(:add_action).with(@ow.actions['test3']).once.ordered
|
363
|
+
@ow.send :fill_menu
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
|
368
|
+
describe '#show_menu' do
|
369
|
+
|
370
|
+
before do
|
371
|
+
@ow = Ruber::OutputWidget.new
|
372
|
+
end
|
373
|
+
|
374
|
+
it 'fills the menu if it is empty' do
|
375
|
+
flexmock(@ow).should_receive(:fill_menu).once
|
376
|
+
@ow.send :show_menu, Qt::Point.new(2,3)
|
377
|
+
end
|
378
|
+
|
379
|
+
it 'doesn\'t fill the menu if it isn\'t empty' do
|
380
|
+
@ow.send :fill_menu
|
381
|
+
#The following line is needed to avoid displaying the menu
|
382
|
+
flexmock(@ow.instance_variable_get(:@menu)).should_receive(:popup)
|
383
|
+
flexmock(@ow).should_receive(:fill_menu).never
|
384
|
+
@ow.send :show_menu, Qt::Point.new(2,3)
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'calls the popup method of the menu, passing it the argument, after filling it' do
|
388
|
+
flexmock(@ow).should_receive(:fill_menu).once.ordered
|
389
|
+
flexmock(@ow.instance_variable_get(:@menu)).should_receive(:popup).with(Qt::Point.new(2,3)).once.ordered
|
390
|
+
@ow.send :show_menu, Qt::Point.new(2,3)
|
391
|
+
end
|
392
|
+
|
393
|
+
end
|
394
|
+
|
395
|
+
describe '#data_changed' do
|
396
|
+
|
397
|
+
before do
|
398
|
+
@ow = Ruber::OutputWidget.new
|
399
|
+
@model = @ow.model
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'sets the "no_text" state to false if the model contains at least an item' do
|
403
|
+
flexmock(@model).should_receive(:row_count).once.and_return 3
|
404
|
+
@ow.send(:rows_changed)
|
405
|
+
@ow.state('no_text').should be_false
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'sets the "no_text" state to true if the model contains at least an item' do
|
409
|
+
@ow.send(:rows_changed)
|
410
|
+
@ow.state('no_text').should be_true
|
411
|
+
end
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
describe '#selection_changed' do
|
416
|
+
|
417
|
+
before do
|
418
|
+
@ow = Ruber::OutputWidget.new
|
419
|
+
@model = @ow.model
|
420
|
+
3.times{|i| @model.append_row Qt::StandardItem.new(i.to_s)}
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'sets the "no_selection" state to false if the selection contains at least one item' do
|
424
|
+
sm = @ow.view.selection_model
|
425
|
+
sm.select @model.index(0,0), Qt::ItemSelectionModel::Select
|
426
|
+
@ow.send :selection_changed, Qt::ModelIndex.new, Qt::ModelIndex.new
|
427
|
+
@ow.state('no_selection').should be_false
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'sets the "no_selection" state to true if the selection contains at least one item' do
|
431
|
+
sm = @ow.view.selection_model
|
432
|
+
sm.select @model.index(0,0), Qt::ItemSelectionModel::Select
|
433
|
+
sm.select @model.index(0,0), Qt::ItemSelectionModel::Deselect
|
434
|
+
@ow.send :selection_changed, Qt::ModelIndex.new, Qt::ModelIndex.new
|
435
|
+
@ow.state('no_selection').should be_true
|
436
|
+
end
|
437
|
+
|
438
|
+
end
|
439
|
+
|
440
|
+
describe '#set_color_for' do
|
441
|
+
|
442
|
+
before do
|
443
|
+
@ow = Ruber::OutputWidget.new
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'stores the given color under the given name' do
|
447
|
+
@ow.set_color_for :error, Qt::Color.new(Qt.red)
|
448
|
+
@ow.instance_variable_get(:@colors)[:error].should == Qt::Color.new(255, 0, 0)
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'overwrites an existing entry with the same name' do
|
452
|
+
@ow.set_color_for :error, Qt::Color.new(Qt.red)
|
453
|
+
@ow.set_color_for :error, Qt::Color.new(Qt.blue)
|
454
|
+
@ow.instance_variable_get(:@colors)[:error].should == Qt::Color.new(0, 0, 255)
|
455
|
+
end
|
456
|
+
|
457
|
+
end
|
458
|
+
|
459
|
+
describe '#scroll_to' do
|
460
|
+
|
461
|
+
before do
|
462
|
+
@ow = Ruber::OutputWidget.new
|
463
|
+
@mod = @ow.model
|
464
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
465
|
+
end
|
466
|
+
|
467
|
+
describe ', when called with a positive integer' do
|
468
|
+
|
469
|
+
it 'it scrolls the view so that the row with the argument as index is at the bottom' do
|
470
|
+
idx = @mod.index(2, 0)
|
471
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
472
|
+
@ow.scroll_to 2
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'scrolls so that the last item is at the bottom if the argument is greater than the index of the last row' do
|
476
|
+
idx = @mod.index(4, 0)
|
477
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
478
|
+
@ow.scroll_to 6
|
479
|
+
end
|
480
|
+
|
481
|
+
end
|
482
|
+
|
483
|
+
describe ', when called with a negative integer' do
|
484
|
+
|
485
|
+
it 'scrolls the view so that the row with index the argument, counting from below, is at the bottom' do
|
486
|
+
idx = @mod.index(1, 0)
|
487
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
488
|
+
@ow.scroll_to -4
|
489
|
+
end
|
490
|
+
|
491
|
+
it 'scrolls so that the first item is at the bottom if the absolute value of the argument is greater than the index of the last row - 1' do
|
492
|
+
idx = @mod.index(0, 0)
|
493
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
494
|
+
@ow.scroll_to -8
|
495
|
+
end
|
496
|
+
|
497
|
+
end
|
498
|
+
|
499
|
+
describe ', when called with a Qt::ModelIndex' do
|
500
|
+
|
501
|
+
it 'scrolls the view so that the item corresponding to the index is at the bottom of the view' do
|
502
|
+
@mod.append_column(5.times.map{|i| Qt::StandardItem.new (2*i).to_s})
|
503
|
+
idx = @mod.index(2,1)
|
504
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
505
|
+
@ow.scroll_to idx
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'scrolls so that the last element is at the bottom if the index is invalid' do
|
509
|
+
idx = @mod.index(4,0)
|
510
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
511
|
+
@ow.scroll_to Qt::ModelIndex.new
|
512
|
+
end
|
513
|
+
|
514
|
+
end
|
515
|
+
|
516
|
+
describe ', when called with nil' do
|
517
|
+
|
518
|
+
it 'scrolls so that the last element is at the bottom' do
|
519
|
+
idx = @mod.index(4,0)
|
520
|
+
flexmock(@ow.view).should_receive(:scroll_to).with(idx, Qt::AbstractItemView::PositionAtBottom).once
|
521
|
+
@ow.scroll_to nil
|
522
|
+
end
|
523
|
+
|
524
|
+
end
|
525
|
+
|
526
|
+
end
|
527
|
+
|
528
|
+
describe '#set_output_type' do
|
529
|
+
|
530
|
+
before do
|
531
|
+
@ow = Ruber::OutputWidget.new nil
|
532
|
+
@colors = {:message => Qt::Color.new(Qt.blue), :error => Qt::Color.new(Qt.green)}
|
533
|
+
@colors.each_pair{|k, v| @ow.set_color_for k, v}
|
534
|
+
@mod = @ow.model
|
535
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
536
|
+
end
|
537
|
+
|
538
|
+
it 'sets the foreground of the given index with the color associated with the type' do
|
539
|
+
@ow.set_output_type @mod.index(2,0), :error
|
540
|
+
@ow.model.item(2,0).foreground.color.should == @colors[:error]
|
541
|
+
end
|
542
|
+
|
543
|
+
it 'sets the role corresponding to Ruber::OutputWidget::OutputTypeRole to a string version of the type' do
|
544
|
+
@ow.set_output_type @mod.index(2,0), :error
|
545
|
+
@ow.model.item(2,0).data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'error'
|
546
|
+
end
|
547
|
+
|
548
|
+
it 'doesn\'t change the foreground if there\'s no color defined for the given type' do
|
549
|
+
color = Qt::Color.new(Qt.yellow)
|
550
|
+
@ow.model.item(2,0).foreground = Qt::Brush.new(color)
|
551
|
+
@ow.set_output_type @mod.index(2,0), :test
|
552
|
+
@ow.model.item(2,0).foreground.color.should == color
|
553
|
+
end
|
554
|
+
|
555
|
+
it 'doesn\'t change the output type if there\'s no color defined for the given type' do
|
556
|
+
@ow.model.item(2,0).set_data(Qt::Variant.new('other'), Ruber::OutputWidget::OutputTypeRole)
|
557
|
+
@ow.set_output_type @mod.index(2,0), :test
|
558
|
+
@ow.model.item(2,0).data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'other'
|
559
|
+
end
|
560
|
+
|
561
|
+
it 'returns the type if the type was changed successfully' do
|
562
|
+
@ow.set_output_type(@mod.index(2,0), :error).should == :error
|
563
|
+
end
|
564
|
+
|
565
|
+
it 'returns nil if the type wasn\'t changed successfully' do
|
566
|
+
@ow.set_output_type(@mod.index(2,0), :test).should be_nil
|
567
|
+
end
|
568
|
+
|
569
|
+
end
|
570
|
+
|
571
|
+
describe '#do_auto_scroll' do
|
572
|
+
|
573
|
+
before do
|
574
|
+
@ow = Ruber::OutputWidget.new
|
575
|
+
5.times{|i| @ow.model.append_row Qt::StandardItem.new(i.to_s)}
|
576
|
+
end
|
577
|
+
|
578
|
+
it 'calls the scroll_to method passing the index of the model associated with the view corresponding to the last row and column 0 under the given parent, if auto scrolling is enabled' do
|
579
|
+
flexmock(@ow.view).should_receive(:model).once.and_return(@ow.model)
|
580
|
+
flexmock(@ow).should_receive(:scroll_to).once.with(@ow.model.index(3,0))
|
581
|
+
@ow.send :do_auto_scroll, Qt::ModelIndex.new, 1, 3
|
582
|
+
end
|
583
|
+
|
584
|
+
it 'does nothing if auto scrolling is disabled' do
|
585
|
+
@ow.auto_scroll = false
|
586
|
+
flexmock(@ow).should_receive(:scroll_to).never
|
587
|
+
@ow.send :do_auto_scroll, Qt::ModelIndex.new, 1, 3
|
588
|
+
end
|
589
|
+
|
590
|
+
end
|
591
|
+
|
592
|
+
describe '#with_auto_scrolling' do
|
593
|
+
|
594
|
+
before do
|
595
|
+
@ow = Ruber::OutputWidget.new
|
596
|
+
end
|
597
|
+
|
598
|
+
it 'calls the block after setting the value of the auto_scroll attribute to the argument' do
|
599
|
+
as = true
|
600
|
+
@ow.with_auto_scrolling(false){as = @ow.auto_scroll}
|
601
|
+
as.should be_false
|
602
|
+
@ow.auto_scroll = false
|
603
|
+
@ow.with_auto_scrolling(true){as = @ow.auto_scroll}
|
604
|
+
as.should be_true
|
605
|
+
end
|
606
|
+
|
607
|
+
it 'restores the value of the auto_scroll attribute after executing the block' do
|
608
|
+
@ow.with_auto_scrolling(false){}
|
609
|
+
@ow.auto_scroll.should be_true
|
610
|
+
@ow.with_auto_scrolling(true){}
|
611
|
+
@ow.auto_scroll.should be_true
|
612
|
+
@ow.auto_scroll = false
|
613
|
+
@ow.with_auto_scrolling(false){}
|
614
|
+
@ow.auto_scroll.should be_false
|
615
|
+
@ow.with_auto_scrolling(true){}
|
616
|
+
@ow.auto_scroll.should be_false
|
617
|
+
end
|
618
|
+
|
619
|
+
it 'restores the value of the auto_scroll attribute even if the block raises an exception' do
|
620
|
+
@ow.with_auto_scrolling(false){raise StandardError} rescue nil
|
621
|
+
@ow.auto_scroll.should be_true
|
622
|
+
@ow.with_auto_scrolling(true){raise StandardError} rescue nil
|
623
|
+
@ow.auto_scroll.should be_true
|
624
|
+
@ow.auto_scroll = false
|
625
|
+
@ow.with_auto_scrolling(false){raise StandardError} rescue nil
|
626
|
+
@ow.auto_scroll.should be_false
|
627
|
+
@ow.with_auto_scrolling(true){raise StandardError} rescue nil
|
628
|
+
@ow.auto_scroll.should be_false
|
629
|
+
end
|
630
|
+
|
631
|
+
end
|
632
|
+
|
633
|
+
describe '#title=' do
|
634
|
+
|
635
|
+
before do
|
636
|
+
@ow = Ruber::OutputWidget.new
|
637
|
+
@ow.set_color_for :message, Qt::Color.new(Qt.blue)
|
638
|
+
3.times{|i| @ow.model.append_row Qt::StandardItem.new(i.to_s)}
|
639
|
+
end
|
640
|
+
|
641
|
+
it 'adds a new entry of type message at index 0, 0 if no title exists' do
|
642
|
+
old_rc = @ow.model.row_count
|
643
|
+
@ow.title = 'x'
|
644
|
+
@ow.model.row_count.should == old_rc + 1
|
645
|
+
it = @ow.model.item 0
|
646
|
+
it.text.should == 'x'
|
647
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
648
|
+
it.data(Ruber::OutputWidget::IsTitleRole).to_bool.should be_true
|
649
|
+
end
|
650
|
+
|
651
|
+
it 'replaces the old title with the new one if a title already existed' do
|
652
|
+
@ow.title = 'x'
|
653
|
+
old_rc = @ow.model.row_count
|
654
|
+
@ow.title = 'y'
|
655
|
+
@ow.model.row_count.should == old_rc
|
656
|
+
it = @ow.model.item 0
|
657
|
+
it.text.should == 'y'
|
658
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
659
|
+
it.data(Ruber::OutputWidget::IsTitleRole).to_bool.should be_true
|
660
|
+
end
|
661
|
+
|
662
|
+
end
|
663
|
+
|
664
|
+
describe '#has_title?' do
|
665
|
+
|
666
|
+
before do
|
667
|
+
@ow = Ruber::OutputWidget.new
|
668
|
+
@ow.set_color_for :message, Qt::Color.new(Qt.blue)
|
669
|
+
3.times{|i| @ow.model.append_row Qt::StandardItem.new(i.to_s)}
|
670
|
+
end
|
671
|
+
|
672
|
+
it 'returns true if the item at row 0, column 0 has the IsTitleRole set to true' do
|
673
|
+
@ow.title = 'x'
|
674
|
+
@ow.should have_title
|
675
|
+
end
|
676
|
+
|
677
|
+
it 'returns false if the item at row 0, column 0 has the IsTitleRole set to false or unset' do
|
678
|
+
@ow.should_not have_title
|
679
|
+
@ow.model.item(0).set_data Qt::Variant.new(false), Ruber::OutputWidget::IsTitleRole
|
680
|
+
@ow.should_not have_title
|
681
|
+
end
|
682
|
+
|
683
|
+
it 'returns false if the model is empty' do
|
684
|
+
@ow.model.clear
|
685
|
+
@ow.should_not have_title
|
686
|
+
end
|
687
|
+
|
688
|
+
end
|
689
|
+
|
690
|
+
describe '#load_settings' do
|
691
|
+
|
692
|
+
before do
|
693
|
+
@colors = {
|
694
|
+
:message => Qt::Color.new(0,0,0),
|
695
|
+
:message_good => Qt::Color.new(0, 0, 255),
|
696
|
+
:message_bad => Qt::Color.new(104, 0, 104),
|
697
|
+
:output => Qt::Color.new(0, 0, 255),
|
698
|
+
:output1 => Qt::Color.new(0, 0, 150),
|
699
|
+
:output2 => Qt::Color.new(0, 255, 255),
|
700
|
+
:error => Qt::Color.new(255, 0, 0),
|
701
|
+
:error1 => Qt::Color.new(150, 0, 0),
|
702
|
+
:error2 => Qt::Color.new(255, 255, 0),
|
703
|
+
:warning => Qt::Color.new(160, 160, 164),
|
704
|
+
:warning1 => Qt::Color.new(104, 104, 104),
|
705
|
+
:warning2 => Qt::Color.new(192, 192, 192),
|
706
|
+
}
|
707
|
+
@config = flexmock do |m|
|
708
|
+
@colors.each_pair{|k, v| m.should_receive(:[]).with(:output_colors, k).and_return(v).by_default}
|
709
|
+
m.should_receive(:[]).with(:general, :wrap_output).and_return(false).by_default
|
710
|
+
m.should_receive(:[]).with(:general, :output_font).and_return(Qt::Font.new('Courier', 10)).by_default
|
711
|
+
end
|
712
|
+
flexmock(Ruber).should_receive(:[]).with(:config).and_return @config
|
713
|
+
@ow = Ruber::OutputWidget.new
|
714
|
+
end
|
715
|
+
|
716
|
+
it 'reads the colors stored in the output_colors config group' do
|
717
|
+
@ow.send :load_settings
|
718
|
+
res = @ow.instance_variable_get(:@colors)
|
719
|
+
@colors.each_pair{|k, v| res[k].should == v}
|
720
|
+
end
|
721
|
+
|
722
|
+
it 'changes the foreground role of all the entries according to the new settings' do
|
723
|
+
mod = @ow.model
|
724
|
+
@colors.each_key do |k|
|
725
|
+
it = Qt::StandardItem.new k.to_s
|
726
|
+
it.foreground = Qt::Brush.new Qt::Color.new(Qt.green)
|
727
|
+
it.set_data Qt::Variant.new(k.to_s), Ruber::OutputWidget::OutputTypeRole
|
728
|
+
mod.append_row it
|
729
|
+
end
|
730
|
+
@ow.send :load_settings
|
731
|
+
mod.row_count.times do |i|
|
732
|
+
it = mod.item i
|
733
|
+
it.foreground.color.should == @colors[it.text.to_sym]
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
it 'doesn\'t change items which have an unknown output type' do
|
738
|
+
mod = @ow.model
|
739
|
+
color = Qt::Color.new(123, 18, 234)
|
740
|
+
it1 = Qt::StandardItem.new 'x'
|
741
|
+
it1.set_data Qt::Variant.new('unknown'), Ruber::OutputWidget::OutputTypeRole
|
742
|
+
it1.foreground = Qt::Brush.new(color)
|
743
|
+
mod.append_row it1
|
744
|
+
it2 = Qt::StandardItem.new 'y'
|
745
|
+
it2.foreground = Qt::Brush.new(color)
|
746
|
+
mod.append_row it2
|
747
|
+
@ow.send :load_settings
|
748
|
+
it1.foreground.color.should == color
|
749
|
+
it2.foreground.color.should == color
|
750
|
+
end
|
751
|
+
|
752
|
+
it 'also changes the color of children items' do
|
753
|
+
mod = @ow.model
|
754
|
+
it1 = Qt::StandardItem.new('parent'){set_data Qt::Variant.new('error'), Ruber::OutputWidget::OutputTypeRole}
|
755
|
+
it2 = Qt::StandardItem.new('child'){set_data Qt::Variant.new('output'), Ruber::OutputWidget::OutputTypeRole}
|
756
|
+
it1.append_row it2
|
757
|
+
mod.append_row it1
|
758
|
+
@ow.send :load_settings
|
759
|
+
it1.foreground.color.should == @colors[:error]
|
760
|
+
it2.foreground.color.should == @colors[:output]
|
761
|
+
end
|
762
|
+
|
763
|
+
it 'sets the view font to the value stored in the general/output_font setting if the @use_default_font instance variable is false' do
|
764
|
+
flexmock(@ow.view).should_receive(:font=).with(Qt::Font.new('Courier', 10)).once
|
765
|
+
@ow.send :load_settings
|
766
|
+
end
|
767
|
+
|
768
|
+
it 'doesn\'t change the view font if the @use_default_font instance variable is true' do
|
769
|
+
@ow.instance_variable_set(:@use_default_font, true)
|
770
|
+
flexmock(@ow.view).should_receive(:font=).never
|
771
|
+
@ow.send :load_settings
|
772
|
+
end
|
773
|
+
|
774
|
+
|
775
|
+
it 'attempts to set the word_wrap property of the view according to the general/wrap_output setting' do
|
776
|
+
flexmock(@ow.view).should_receive(:word_wrap=).with(false).once
|
777
|
+
@ow.send :load_settings
|
778
|
+
end
|
779
|
+
|
780
|
+
it 'doesn\'t attempt to change the word_wrap property of the view if the ignore_word_wrap_option attribute is true' do
|
781
|
+
@ow.ignore_word_wrap_option = true
|
782
|
+
flexmock(@ow.view).should_receive(:word_wrap=).never
|
783
|
+
@ow.send :load_settings
|
784
|
+
end
|
785
|
+
|
786
|
+
it 'doesn\'t fail if the view doesn\'t have a word_wrap= method' do
|
787
|
+
flexmock(@ow.view).should_receive(:word_wrap=).with(false).once.and_raise(NoMethodError)
|
788
|
+
lambda{@ow.send :load_settings}.should_not raise_error
|
789
|
+
end
|
790
|
+
|
791
|
+
end
|
792
|
+
|
793
|
+
describe '#clear_output' do
|
794
|
+
|
795
|
+
it 'removes all the rows in the model' do
|
796
|
+
ow = Ruber::OutputWidget.new
|
797
|
+
mod = ow.model
|
798
|
+
5.times{|i| mod.append_row Qt::StandardItem.new(i.to_s)}
|
799
|
+
it = mod.item(2)
|
800
|
+
it.append_row(Qt::StandardItem.new('x'))
|
801
|
+
ow.send(:clear_output)
|
802
|
+
mod.row_count.should == 0
|
803
|
+
end
|
804
|
+
|
805
|
+
end
|
806
|
+
|
807
|
+
describe '#copy' do
|
808
|
+
|
809
|
+
before do
|
810
|
+
@ow = Ruber::OutputWidget.new
|
811
|
+
@mod = @ow.model
|
812
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
813
|
+
end
|
814
|
+
|
815
|
+
it 'calls the text_for_clipboard method passing it an array containing all the indexes' do
|
816
|
+
c1 = Qt::StandardItem.new 'c1'
|
817
|
+
c2 = Qt::StandardItem.new 'c2'
|
818
|
+
c3 = Qt::StandardItem.new 'c3'
|
819
|
+
c1.append_row c3
|
820
|
+
it = @mod.item(3,0)
|
821
|
+
it.append_row c1
|
822
|
+
it.append_row c2
|
823
|
+
exp = [@mod.index(0,0), @mod.index(1,0), @mod.index(2,0), it.index, c1.index, c3.index, c2.index, @mod.index(4,0)]
|
824
|
+
flexmock(@ow).should_receive(:text_for_clipboard).once.with(exp)
|
825
|
+
@ow.send :copy
|
826
|
+
end
|
827
|
+
|
828
|
+
it 'inserts the value returned by text_for_clipboard in the clipboard' do
|
829
|
+
text = random_string
|
830
|
+
flexmock(@ow).should_receive(:text_for_clipboard).once.with(5.times.map{|i| @mod.index(i,0)}).and_return text
|
831
|
+
@ow.send :copy
|
832
|
+
KDE::Application.clipboard.text.should == text
|
833
|
+
end
|
834
|
+
|
835
|
+
end
|
836
|
+
|
837
|
+
describe '#copy_selected' do
|
838
|
+
|
839
|
+
before do
|
840
|
+
@ow = Ruber::OutputWidget.new
|
841
|
+
@mod = @ow.model
|
842
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
843
|
+
@mod.append_column 5.times.map{|i| Qt::StandardItem.new (i+5).to_s}
|
844
|
+
sm = @ow.view.selection_model
|
845
|
+
@exp = [[1,0], [2,1], [3,1]].map{|i, j| @mod.index i, j}
|
846
|
+
@exp.each{|i| sm.select i, Qt::ItemSelectionModel::Select}
|
847
|
+
end
|
848
|
+
|
849
|
+
it 'calls the text_for_clipboard method passing the list of selected items as argument' do
|
850
|
+
flexmock(@ow).should_receive(:text_for_clipboard).once.with @exp
|
851
|
+
@ow.send :copy_selected
|
852
|
+
end
|
853
|
+
|
854
|
+
it 'inserts the value returned by text_for_clipboard in the clipboard' do
|
855
|
+
text = random_string
|
856
|
+
flexmock(@ow).should_receive(:text_for_clipboard).once.with(@exp).and_return text
|
857
|
+
@ow.send :copy_selected
|
858
|
+
KDE::Application.clipboard.text.should == text
|
859
|
+
end
|
860
|
+
|
861
|
+
end
|
862
|
+
|
863
|
+
describe '#text_for_clipboard' do
|
864
|
+
|
865
|
+
before do
|
866
|
+
@ow = Ruber::OutputWidget.new
|
867
|
+
@mod = @ow.model
|
868
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
869
|
+
@mod.append_column 5.times.map{|i| Qt::StandardItem.new (i+5).to_s}
|
870
|
+
sm = @ow.view.selection_model
|
871
|
+
@exp = [[1,0], [2,1], [3,1]].map{|i, j| @mod.index i, j}
|
872
|
+
@exp.each{|i| sm.select i, Qt::ItemSelectionModel::Select}
|
873
|
+
end
|
874
|
+
|
875
|
+
it 'returns a string where the text of all the top-level items in a single row in the argument are on the same line, separated by tabs' do
|
876
|
+
text = @ow.send :text_for_clipboard, [@mod.index(0,0), @mod.index(1,1), @mod.index(1,0), @mod.index(0,1)]
|
877
|
+
text.should == "0\t5\n1\t6"
|
878
|
+
end
|
879
|
+
|
880
|
+
it 'ignores any child item' do
|
881
|
+
@mod.item(0,0).append_row Qt::StandardItem.new('c')
|
882
|
+
text = @ow.send :text_for_clipboard, [@mod.index(0,0), @mod.index(1,1), @mod.index(1,0), @mod.index(0,1), @mod.index(0,0, @mod.index(0,0))]
|
883
|
+
text.should == "0\t5\n1\t6"
|
884
|
+
end
|
885
|
+
|
886
|
+
end
|
887
|
+
|
888
|
+
describe '#maybe_open_file' do
|
889
|
+
|
890
|
+
before do
|
891
|
+
begin
|
892
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).and_return(0).by_default
|
893
|
+
rescue NameError
|
894
|
+
Ruber::Application = flexmock{|m| m.should_receive(:keyboard_modifiers).and_return(0).by_default}
|
895
|
+
end
|
896
|
+
@ow = Ruber::OutputWidget.new
|
897
|
+
@mod = @ow.model
|
898
|
+
@mod.append_row Qt::StandardItem.new ''
|
899
|
+
@mw = flexmock{|m| m.should_ignore_missing}
|
900
|
+
flexmock(Ruber).should_receive(:[]).with(:main_window).and_return(@mw).by_default
|
901
|
+
end
|
902
|
+
|
903
|
+
after do
|
904
|
+
Ruber.send :remove_const, :Application unless Ruber::Application.is_a?(KDE::Application)
|
905
|
+
end
|
906
|
+
|
907
|
+
it 'calls the find_filename_in_index method passing it the index' do
|
908
|
+
flexmock(@ow).should_receive(:find_filename_in_index).once.with @mod.index(0,0)
|
909
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
910
|
+
end
|
911
|
+
|
912
|
+
describe ', when the find_filename_in_index methods returns an array' do
|
913
|
+
|
914
|
+
before do
|
915
|
+
flexmock(@ow).should_receive(:find_filename_in_index).with(@mod.index(0,0)).and_return([__FILE__, 10]).by_default
|
916
|
+
end
|
917
|
+
|
918
|
+
it 'opens displays the file corresponding to the first entry of the array in the editor, scrolling to the line corresponding to the second entry minus 1' do
|
919
|
+
@mw.should_receive(:display_document).once.with(__FILE__, 9)
|
920
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
921
|
+
end
|
922
|
+
|
923
|
+
it 'doesn\'t subtract 1 from the line number if it is 0' do
|
924
|
+
@mw.should_receive(:display_document).once.with(__FILE__, 0)
|
925
|
+
@ow.should_receive(:find_filename_in_index).once.and_return [__FILE__, 0]
|
926
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
927
|
+
end
|
928
|
+
|
929
|
+
it 'hides the tool widget if the Meta key is not pressed' do
|
930
|
+
@mw.should_receive(:hide_tool).with(@ow).once
|
931
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
932
|
+
end
|
933
|
+
|
934
|
+
it 'doesn\'t hide the tool widget if the Meta key is pressed' do
|
935
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return(Qt::MetaModifier.to_i)
|
936
|
+
@mw.should_receive(:hide_tool).with(@ow).never
|
937
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
938
|
+
end
|
939
|
+
|
940
|
+
it 'does nothing if the Control and/or Shift modifiers are pressed' do
|
941
|
+
flexmock(@ow).should_receive(:find_filename_in_index).never
|
942
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return(Qt::ShiftModifier.to_i)
|
943
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
944
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return(Qt::ControlModifier.to_i)
|
945
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
946
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return((Qt::ShiftModifier|Qt::ControlModifier).to_i)
|
947
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
948
|
+
end
|
949
|
+
|
950
|
+
it 'ignores the Control and the shift modifiers if the selection mode of the view is NoSelection' do
|
951
|
+
@ow.view.selection_mode = Qt::AbstractItemView::NoSelection
|
952
|
+
flexmock(@ow).should_receive(:find_filename_in_index).with(@mod.index(0,0)).and_return([__FILE__, 10]).times(3)
|
953
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return(Qt::ShiftModifier.to_i)
|
954
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
955
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return(Qt::ControlModifier.to_i)
|
956
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
957
|
+
flexmock(Ruber::Application).should_receive(:keyboard_modifiers).once.and_return((Qt::ShiftModifier|Qt::ControlModifier).to_i)
|
958
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
959
|
+
end
|
960
|
+
|
961
|
+
end
|
962
|
+
|
963
|
+
describe ', when the find_filename_in_index methods returns nil' do
|
964
|
+
|
965
|
+
it 'does nothing' do
|
966
|
+
@mw.should_receive(:display_document).never
|
967
|
+
flexmock(@ow).should_receive(:find_filename_in_index).once.with(@mod.index(0,0)).and_return nil
|
968
|
+
@ow.send :maybe_open_file, @mod.index(0,0)
|
969
|
+
end
|
970
|
+
|
971
|
+
end
|
972
|
+
|
973
|
+
end
|
974
|
+
|
975
|
+
describe '#find_filename_in_index' do
|
976
|
+
|
977
|
+
before do
|
978
|
+
@ow = Ruber::OutputWidget.new
|
979
|
+
@mod = @ow.model
|
980
|
+
@mod.append_row Qt::StandardItem.new('')
|
981
|
+
end
|
982
|
+
|
983
|
+
it 'calls the find_filename_in_string method, passing it the text of the index, if the argument is a Qt::ModelIndex' do
|
984
|
+
@mod.item(0,0).text = __FILE__
|
985
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with __FILE__
|
986
|
+
@ow.send :find_filename_in_index, @mod.index(0,0)
|
987
|
+
end
|
988
|
+
|
989
|
+
it 'calls the find_filename_in_string method, passing it the argument, if the argument is a string' do
|
990
|
+
@mod.item(0,0).text = __FILE__
|
991
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with __FILE__
|
992
|
+
@ow.send :find_filename_in_index, __FILE__
|
993
|
+
end
|
994
|
+
|
995
|
+
it 'returns nil if find_filename_in_string returns nil' do
|
996
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return nil
|
997
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should be_nil
|
998
|
+
end
|
999
|
+
|
1000
|
+
it 'returns an array having the value returned by find_filename_in_string as first element and 0 as second if find_filename_in_string returns a string' do
|
1001
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return __FILE__
|
1002
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should == [__FILE__, 0]
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
it 'returns an array having the value returned by find_filename_in_string as first element and 0 as second if find_filename_in_string returns an array with one element' do
|
1006
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return [__FILE__]
|
1007
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should == [__FILE__, 0]
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
it 'returns the value returned by find_filename_in_string if it is an array with two elements' do
|
1011
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return [__FILE__, 6]
|
1012
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should == [__FILE__, 6]
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
it 'removes the first filename from the index text before passing it to find_filename_in_string if the index corresponds to the title and the @skip_first_file_in_title instance variable is true' do
|
1016
|
+
@mod.clear
|
1017
|
+
@ow.title = "/usr/bin/ruby #{__FILE__}"
|
1018
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with(" #{__FILE__}").and_return [__FILE__, 0]
|
1019
|
+
@ow.send :find_filename_in_index, @mod.index(0,0)
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
it 'doesn\'t alter the item text before passing it to find_filename_in_string if the item is not the title' do
|
1023
|
+
@mod.item(0,0).text = "/usr/bin/ruby #{__FILE__}"
|
1024
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with("/usr/bin/ruby #{__FILE__}").and_return ['/usr/bin/ruby', 0]
|
1025
|
+
@ow.send :find_filename_in_index, @mod.index(0,0)
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
it 'doesn\'t alter the text before passing it to find_filename_in_string if the argument is a string' do
|
1029
|
+
text = "/usr/bin/ruby #{__FILE__}"
|
1030
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with("/usr/bin/ruby #{__FILE__}").and_return ['/usr/bin/ruby', 0]
|
1031
|
+
@ow.send :find_filename_in_index, text
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
it 'doesn\'t alter the title text before passing it to find_filename_in_string if the @skip_first_file_in_title instance variable is false' do
|
1035
|
+
@mod.clear
|
1036
|
+
@ow.title = "/usr/bin/ruby #{__FILE__}"
|
1037
|
+
@ow.skip_first_file_in_title = false
|
1038
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with("/usr/bin/ruby #{__FILE__}").and_return ['/usr/bin/ruby', 0]
|
1039
|
+
@ow.send :find_filename_in_index, @mod.index(0,0)
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
describe ', when the string or the first element of the array returned by find_filename_in_string is not an absolute path' do
|
1043
|
+
|
1044
|
+
it 'considers the path relative to the working_dir and transforms it into an absolute path' do
|
1045
|
+
@ow.working_dir = File.dirname(__FILE__)
|
1046
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return [File.basename(__FILE__), 6]
|
1047
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return [File.basename(__FILE__)]
|
1048
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return File.basename(__FILE__)
|
1049
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should == [__FILE__, 6]
|
1050
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should == [__FILE__, 0]
|
1051
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should == [__FILE__, 0]
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
it 'returns nil if the file doesn\'t exist' do
|
1057
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return '/' + random_string
|
1058
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should be_nil
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
it 'returns nil if the file is a directory' do
|
1062
|
+
flexmock(@ow).should_receive(:find_filename_in_string).once.with('').and_return File.dirname(__FILE__)
|
1063
|
+
@ow.send(:find_filename_in_index, @mod.index(0,0)).should be_nil
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
describe '#find_filename_in_string' do
|
1069
|
+
|
1070
|
+
before do
|
1071
|
+
@ow = Ruber::OutputWidget.new
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
it 'recognizes an absolute path without line numbers' do
|
1075
|
+
str = random_string( 1 + rand(10))+ " #{__FILE__} " + random_string(1 + rand(10))
|
1076
|
+
res = @ow.send :find_filename_in_string, str
|
1077
|
+
res[0].should == __FILE__
|
1078
|
+
str = random_string( 1 + rand(10))+ " #{__FILE__}"
|
1079
|
+
res = @ow.send :find_filename_in_string, str
|
1080
|
+
res[0].should == __FILE__
|
1081
|
+
str = "#{__FILE__} " + random_string( 1 + rand(10))
|
1082
|
+
res = @ow.send :find_filename_in_string, str
|
1083
|
+
res[0].should == __FILE__
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
it 'recognizes and expands an absolute path starting with ~/ without line numbers' do
|
1087
|
+
file = '/test/yxz.rb'
|
1088
|
+
exp = File.join ENV['HOME'], file
|
1089
|
+
str = random_string( 1 + rand(10))+ " ~#{file} " + random_string(1 + rand(10))
|
1090
|
+
res = @ow.send :find_filename_in_string, str
|
1091
|
+
res[0].should == exp
|
1092
|
+
str = random_string( 1 + rand(10))+ " ~#{file}"
|
1093
|
+
res = @ow.send :find_filename_in_string, str
|
1094
|
+
res[0].should == exp
|
1095
|
+
str = "~#{file} " + random_string( 1 + rand(10))
|
1096
|
+
res = @ow.send :find_filename_in_string, str
|
1097
|
+
res[0].should == exp
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
it 'recognizes and expands an absolute path starting with ~user/ without line numbers' do
|
1101
|
+
file = '/test/yxz.rb'
|
1102
|
+
exp = File.join ENV['HOME'], file
|
1103
|
+
str = random_string( 1 + rand(10))+ " ~#{ENV['USER']}#{file} " + random_string(1 + rand(10))
|
1104
|
+
res = @ow.send :find_filename_in_string, str
|
1105
|
+
res[0].should == exp
|
1106
|
+
str = random_string( 1 + rand(10))+ " ~#{ENV['USER']}#{file}"
|
1107
|
+
res = @ow.send :find_filename_in_string, str
|
1108
|
+
res[0].should == exp
|
1109
|
+
str = "~#{ENV['USER']}#{file} " + random_string( 1 + rand(10))
|
1110
|
+
res = @ow.send :find_filename_in_string, str
|
1111
|
+
res[0].should == exp
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
it 'recognizes a relative path starting with a single dot and doesn\'t expand it' do
|
1115
|
+
str = random_string( 1 + rand(10))+ " .#{__FILE__} " + random_string(1 + rand(10))
|
1116
|
+
res = @ow.send :find_filename_in_string, str
|
1117
|
+
res[0].should == '.' + __FILE__
|
1118
|
+
str = random_string( 1 + rand(10))+ " .#{__FILE__}"
|
1119
|
+
res = @ow.send :find_filename_in_string, str
|
1120
|
+
res[0].should == '.' + __FILE__
|
1121
|
+
str = ".#{__FILE__} " + random_string( 1 + rand(10))
|
1122
|
+
res = @ow.send :find_filename_in_string, str
|
1123
|
+
res[0].should == '.' + __FILE__
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
it 'recognizes a relative path starting with two dots and doesn\'t expand it' do
|
1127
|
+
str = random_string( 1 + rand(10))+ " ..#{__FILE__} " + random_string(1 + rand(10))
|
1128
|
+
res = @ow.send :find_filename_in_string, str
|
1129
|
+
res[0].should == '..' + __FILE__
|
1130
|
+
str = random_string( 1 + rand(10))+ " ..#{__FILE__}"
|
1131
|
+
res = @ow.send :find_filename_in_string, str
|
1132
|
+
res[0].should == '..' + __FILE__
|
1133
|
+
str = "..#{__FILE__} " + random_string( 1 + rand(10))
|
1134
|
+
res = @ow.send :find_filename_in_string, str
|
1135
|
+
res[0].should == '..' + __FILE__
|
1136
|
+
end
|
1137
|
+
|
1138
|
+
it 'recognizes a relative path not starting with a dot but containing slashes' do
|
1139
|
+
file = "test/xyz"
|
1140
|
+
str = random_string( 1 + rand(10))+ " #{file} " + random_string(1 + rand(10))
|
1141
|
+
res = @ow.send :find_filename_in_string, str
|
1142
|
+
res[0].should == file
|
1143
|
+
str = random_string( 1 + rand(10))+ " #{file}"
|
1144
|
+
res = @ow.send :find_filename_in_string, str
|
1145
|
+
res[0].should == file
|
1146
|
+
str = "#{file} " + random_string( 1 + rand(10))
|
1147
|
+
res = @ow.send :find_filename_in_string, str
|
1148
|
+
res[0].should == file
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
it 'doesn\'t recognize sequences ending with a slash' do
|
1152
|
+
strs = ["#{__FILE__}/", "~#{__FILE__}/", "~#{ENV['USER']}#{__FILE__}/", ".#{__FILE__}/", "..#{__FILE__}/"]
|
1153
|
+
strs.map!{|s| random_string(rand(10)) + ' ' + s + ' ' + random_string(rand(10))}
|
1154
|
+
strs.each{|s| res = @ow.send(:find_filename_in_string, s).should be_nil}
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
it 'recognizes filenames ending in a colon followd by digits, which are interpreted as line numbers' do
|
1158
|
+
strs = ["#{__FILE__}", "~#{__FILE__}", "~#{ENV['USER']}#{__FILE__}", ".#{__FILE__}", "..#{__FILE__}"]
|
1159
|
+
strs.map!{|s| random_string(rand(10)) + ' ' + s + ":10#{rand > 0.5 ? ' ' : ''}" + random_string(rand(10))}
|
1160
|
+
@ow.send(:find_filename_in_string, strs[0]).should == [__FILE__, 10]
|
1161
|
+
@ow.send(:find_filename_in_string, strs[1]).should == [File.join(ENV['HOME'], __FILE__), 10]
|
1162
|
+
@ow.send(:find_filename_in_string, strs[2]).should == [File.join(ENV['HOME'], __FILE__), 10]
|
1163
|
+
@ow.send(:find_filename_in_string, strs[3]).should == ['.' + __FILE__, 10]
|
1164
|
+
@ow.send(:find_filename_in_string, strs[4]).should == ['..' + __FILE__, 10]
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
it 'recognizes any string not containing spaces and ending in a slash followed by a colon and digits, which are interpreted as line numbers' do
|
1168
|
+
file = 'xyz'
|
1169
|
+
str = random_string( 1 + rand(10))+ " #{file}:16 " + random_string(1 + rand(10))
|
1170
|
+
res = @ow.send :find_filename_in_string, str
|
1171
|
+
res.should == [file, 16]
|
1172
|
+
str = random_string( 1 + rand(10))+ " #{file}:16"
|
1173
|
+
res = @ow.send :find_filename_in_string, str
|
1174
|
+
res.should == [file, 16]
|
1175
|
+
str = "#{file}:16 " + random_string( 1 + rand(10))
|
1176
|
+
res = @ow.send :find_filename_in_string, str
|
1177
|
+
res.should == [file, 16]
|
1178
|
+
#In the following tests, there's no space between the last digit and the following character
|
1179
|
+
str = random_string( 1 + rand(10))+ " #{file}:16" + random_string(1 + rand(10))
|
1180
|
+
res = @ow.send :find_filename_in_string, str
|
1181
|
+
res.should == [file, 16]
|
1182
|
+
str = "#{file}:16" + random_string( 1 + rand(10))
|
1183
|
+
res = @ow.send :find_filename_in_string, str
|
1184
|
+
res.should == [file, 16]
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
it 'recognizes the file names enclosed in quotes, double quotes, backticks, all brackets and angular brackets' do
|
1188
|
+
quotes = %w|' " ` ( [ { < |
|
1189
|
+
quotes.each do |q|
|
1190
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + "#{__FILE__}").should == [__FILE__]
|
1191
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + "~#{__FILE__}").should == [File.join(ENV['HOME'], __FILE__)]
|
1192
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + "~#{ENV['USER']}#{__FILE__}").should == [File.join(ENV['HOME'], __FILE__)]
|
1193
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + ".#{__FILE__}").should == [File.join('.', __FILE__)]
|
1194
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + "..#{__FILE__}").should == [File.join('..', __FILE__)]
|
1195
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + "abc/xyz").should == ['abc/xyz']
|
1196
|
+
@ow.send(:find_filename_in_string, random_string( 1 + rand(10))+ ' ' + q + "abc:12").should == ['abc', 12]
|
1197
|
+
end
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
it 'only considers the first match' do
|
1201
|
+
str = "#{__FILE__.upcase} #{__FILE__}"
|
1202
|
+
@ow.send(:find_filename_in_string, str).should == [__FILE__.upcase]
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
describe '#keyReleaseEvent' do
|
1208
|
+
|
1209
|
+
before do
|
1210
|
+
@ow = Ruber::OutputWidget.new
|
1211
|
+
@mw = flexmock('main window'){|m| m.should_ignore_missing}
|
1212
|
+
@ev = Qt::KeyEvent.new Qt::Event::KeyRelease, Qt::Key_A, Qt::NoModifier, 'a'
|
1213
|
+
flexmock(Ruber).should_receive(:[]).with(:main_window).and_return(@mw).by_default
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
it 'gives focus to the current editor' do
|
1217
|
+
ed = flexmock('editor'){|m| m.should_receive(:set_focus).once}
|
1218
|
+
ed.should_ignore_missing
|
1219
|
+
@mw.should_receive(:active_editor).once.and_return ed
|
1220
|
+
@ow.send :keyReleaseEvent, @ev
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
# it 'inserts the text corresponding to the released key in the editor' do
|
1224
|
+
# ed = flexmock('editor'){|m| m.should_receive(:insert_text).once.with('a')}
|
1225
|
+
# ed.should_ignore_missing
|
1226
|
+
# @mw.should_receive(:active_editor).once.and_return ed
|
1227
|
+
# @ow.send :keyReleaseEvent, @ev
|
1228
|
+
# end
|
1229
|
+
|
1230
|
+
it 'does nothing if there\'s no active editor' do
|
1231
|
+
@mw.should_receive(:active_editor).once.and_return nil
|
1232
|
+
lambda{@ow.send :keyReleaseEvent, @ev}.should_not raise_error
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
it 'returns nil' do
|
1236
|
+
# ed = flexmock('editor'){|m| m.should_receive(:insert_text).once.with('a')}
|
1237
|
+
ed = flexmock('editor'){|m| m.should_ignore_missing}
|
1238
|
+
@mw.should_receive(:active_editor).once.and_return ed
|
1239
|
+
@mw.should_receive(:active_editor).once.and_return nil
|
1240
|
+
@ow.send(:keyReleaseEvent, @ev).should be_nil
|
1241
|
+
@ow.send(:keyReleaseEvent, @ev).should be_nil
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
end
|
1245
|
+
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
describe Ruber::OutputWidget::Model do
|
1249
|
+
|
1250
|
+
before do
|
1251
|
+
@ow = Ruber::OutputWidget.new
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
it 'inherits from Qt::StandardItemModel' do
|
1255
|
+
Ruber::OutputWidget::Model.ancestors.should include(Qt::StandardItemModel)
|
1256
|
+
end
|
1257
|
+
|
1258
|
+
describe ', when created' do
|
1259
|
+
|
1260
|
+
it 'can take one or two parameters' do
|
1261
|
+
lambda{Ruber::OutputWidget::Model.new @ow}.should_not raise_error
|
1262
|
+
lambda{Ruber::OutputWidget::Model.new @ow, Qt::Object.new}.should_not raise_error
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
it 'stores the first argument in the "@output_widget" instance variable' do
|
1266
|
+
mod = Ruber::OutputWidget::Model.new @ow
|
1267
|
+
mod.instance_variable_get(:@output_widget).should be_the_same_as(@ow)
|
1268
|
+
end
|
1269
|
+
|
1270
|
+
it 'uses the second argument (or nil) as parent' do
|
1271
|
+
mod = Ruber::OutputWidget::Model.new @ow
|
1272
|
+
mod.parent.should be_nil
|
1273
|
+
w = Qt::Widget.new
|
1274
|
+
mod = Ruber::OutputWidget::Model.new @ow, w
|
1275
|
+
mod.parent.should be_the_same_as(w)
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
it 'sets the @global_flags instance variable to Qt::ItemIsEnabled | Qt::ItemIsSelectable converted to an integer' do
|
1279
|
+
mod = Ruber::OutputWidget::Model.new @ow
|
1280
|
+
mod.instance_variable_get(:@global_flags).should == (Qt::ItemIsEnabled | Qt::ItemIsSelectable).to_i
|
1281
|
+
end
|
1282
|
+
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
describe '#global_flags=' do
|
1286
|
+
|
1287
|
+
before do
|
1288
|
+
@mod = Ruber::OutputWidget::Model.new @ow
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
it 'sets the @global_flags instance variable to the argument converted to an integer' do
|
1292
|
+
@mod.global_flags = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
1293
|
+
@mod.instance_variable_get(:@global_flags).should == (Qt::ItemIsEnabled | Qt::ItemIsUserCheckable).to_i
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
it 'doesn\'t attempt to convert the value to an integer if it\'s nil' do
|
1297
|
+
@mod.global_flags = nil
|
1298
|
+
@mod.instance_variable_get(:@global_flags).should be_nil
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
describe '#flags' do
|
1304
|
+
|
1305
|
+
before do
|
1306
|
+
@mod = @ow.model
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
it 'returns the value specified in the @flags variable if the index is valid and the global_flags attribute is not nil' do
|
1310
|
+
flags = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
1311
|
+
@mod.global_flags = flags
|
1312
|
+
@mod.append_row Qt::StandardItem.new('x')
|
1313
|
+
@mod.flags(@mod.index(0,0)).should == flags.to_i
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
it 'returns Qt::NoItemFlags if the inxed is not valid and the global_flags attribute is not nil' do
|
1317
|
+
flags = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable
|
1318
|
+
@mod.global_flags = flags
|
1319
|
+
@mod.append_row Qt::StandardItem.new('x')
|
1320
|
+
@mod.flags(Qt::ModelIndex.new).should == Qt::NoItemFlags.to_i
|
1321
|
+
end
|
1322
|
+
|
1323
|
+
it 'calls super if the global_flags attribute is nil' do
|
1324
|
+
@mod.global_flags = nil
|
1325
|
+
it = Qt::StandardItem.new('x')
|
1326
|
+
flags = Qt::ItemIsEnabled|Qt::ItemIsEditable|Qt::ItemIsDragEnabled
|
1327
|
+
it.flags = flags
|
1328
|
+
@mod.append_row it
|
1329
|
+
@mod.flags(it.index).to_i.should == flags.to_i
|
1330
|
+
@mod.flags(Qt::ModelIndex.new).to_i.should == Qt::ItemIsDropEnabled.to_i
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
describe '#set' do
|
1336
|
+
|
1337
|
+
before do
|
1338
|
+
@ow = Ruber::OutputWidget.new
|
1339
|
+
@mod = @ow.model
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
it 'takes three or four arguments' do
|
1343
|
+
lambda{@mod.set 'test', :message, 3}.should_not raise_error
|
1344
|
+
lambda{@mod.set 'test', :message, 3, {}}.should_not raise_error
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
it 'creates a new item having the first argument as text and passes it to set_item using the third argument as row and 0 as column if no optional argument are given' do
|
1348
|
+
@mod.set 'test', :message, 3
|
1349
|
+
@mod.item(3,0).text.should == 'test'
|
1350
|
+
flexmock(@mod).should_receive(:set_item).once.with(6, 0, FlexMock.on{|i| i.text == 'test'})
|
1351
|
+
@mod.set 'test', :message, 6
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
it 'creates a new item having the first argument as text and passes it to set_item using the third argument as row and the col option as column only the col optional argument is given' do
|
1355
|
+
@mod.set 'test', :message, 3, :col => 5
|
1356
|
+
@mod.item(3,5).text.should == 'test'
|
1357
|
+
flexmock(@mod).should_receive(:set_item).once.with(6, 5, FlexMock.on{|i| i.text == 'test'})
|
1358
|
+
@mod.set 'test', :message, 6, :col => 5
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
it 'creates a new item having the first argument as text and passes it to the set_child method of the given parent, using the given row (and column, if given) if the parent option is given' do
|
1362
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1363
|
+
@mod.set 'test', :message, 3, :parent => @mod.item(2)
|
1364
|
+
@mod.item(2, 0).child(3, 0).text.should == 'test'
|
1365
|
+
@mod.set 'TEST', :message, 4, :parent => @mod.item(1), :col => 3
|
1366
|
+
@mod.item(1, 0).child(4, 3).text.should == 'TEST'
|
1367
|
+
flexmock(@mod.item(4)).should_receive(:set_child).once.with(5, 0, FlexMock.on{|i| i.text == 'Test'})
|
1368
|
+
flexmock(@mod.item(0)).should_receive(:set_child).once.with(2, 4, FlexMock.on{|i| i.text == 'Test'})
|
1369
|
+
@mod.set 'Test', :message, 5, :parent => @mod.item(4,0)
|
1370
|
+
@mod.set 'Test', :message, 2, :col => 4, :parent => @mod.item(0,0)
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
it 'calls the set_output_type method of the output widget passing it the index of the item and the type argument' do
|
1374
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1375
|
+
flexmock(@ow).should_receive(:set_output_type).once.with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.row == 3 and i.column == 5}, :message)
|
1376
|
+
@mod.set 'text', :message, 3, :col => 5
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
it 'counts rows and columns backwards if negative' do
|
1380
|
+
flexmock(@mod).should_receive(:row_count).and_return(7)
|
1381
|
+
flexmock(@mod).should_receive(:column_count).and_return(5)
|
1382
|
+
flexmock(@mod).should_receive(:set_item).with(2, 0, Qt::StandardItem).once
|
1383
|
+
flexmock(@mod).should_receive(:set_item).with(1, 3, Qt::StandardItem).once
|
1384
|
+
@mod.set 'test', :message, -5
|
1385
|
+
@mod.set 'test', :message, -6, :col => -2
|
1386
|
+
|
1387
|
+
it = Qt::StandardItem.new 'x'
|
1388
|
+
@mod.append_row it
|
1389
|
+
flexmock(it).should_receive(:row_count).and_return(7)
|
1390
|
+
flexmock(it).should_receive(:column_count).and_return(5)
|
1391
|
+
flexmock(it).should_receive(:set_child).with(2, 0, Qt::StandardItem).once
|
1392
|
+
flexmock(it).should_receive(:set_child).with(1, 3, Qt::StandardItem).once
|
1393
|
+
@mod.set 'test', :message, -5, :parent => it
|
1394
|
+
@mod.set 'test', :message, -6, :col => -2, :parent => it
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
it 'returns the new item' do
|
1398
|
+
it = @mod.set('text', :message, 3, :col => 5)
|
1399
|
+
it.should be_a(Qt::StandardItem)
|
1400
|
+
it.text.should == 'text'
|
1401
|
+
it.row.should == 3
|
1402
|
+
it.column.should == 5
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
describe '#insert' do
|
1408
|
+
|
1409
|
+
before do
|
1410
|
+
@ow = Ruber::OutputWidget.new
|
1411
|
+
@mod = @ow.model
|
1412
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
it 'takes three or four arguments' do
|
1416
|
+
lambda{@mod.insert ['test'], :message, 3}.should_not raise_error
|
1417
|
+
lambda{@mod.insert ['test'], :message, 3, {}}.should_not raise_error
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
describe ', when the first argument is an array' do
|
1421
|
+
|
1422
|
+
it 'creates a row from the array by replacing nil entries with invalid Qt::StandardItem and string entries with Qt::StandardItems with the strings as title and inserts it in the row given as third argument if no optional argument is given' do
|
1423
|
+
text = ['x', nil, nil, 'y', nil ]
|
1424
|
+
flexmock(@mod).should_receive(:insert_row).with(3, FlexMock.on{|a| a[0].text == 'x' and a[1].text.nil? and a[2].text.nil? and a[3].text == 'y' and a[4].text.nil?}).once
|
1425
|
+
@mod.insert text, :message, 3
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
it 'inserts the items as children of the item given in the :parent option, if given' do
|
1429
|
+
text = ['x', nil, nil, 'y', nil ]
|
1430
|
+
it = @mod.item(2,0)
|
1431
|
+
flexmock(it).should_receive(:insert_row).with(3, FlexMock.on{|a| a[0].text == 'x' and a[1].text.nil? and a[2].text.nil? and a[3].text == 'y' and a[4].text.nil?}).once
|
1432
|
+
3.times{it.append_row []}
|
1433
|
+
@mod.insert text, :message, 3, :parent => it
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
it 'calls the output widget\'s set_output_type for each valid item passing the second argument if the second argument is a symbol' do
|
1437
|
+
text = ['x', nil, nil, 'y', nil ]
|
1438
|
+
flexmock(@ow).should_receive(:set_output_type).with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.data.to_string == 'x'}, :error).once
|
1439
|
+
flexmock(@ow).should_receive(:set_output_type).with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.data.to_string == 'y'}, :error).once
|
1440
|
+
@mod.insert text, :error, 3
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
it 'calls the output widget\'s set_output_type for each valid item passing the corresponding item in the second argument if the second argument is an array' do
|
1444
|
+
text = ['x', nil, nil, 'y', nil ]
|
1445
|
+
flexmock(@ow).should_receive(:set_output_type).with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.data.to_string == 'x'}, :error).once
|
1446
|
+
flexmock(@ow).should_receive(:set_output_type).with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.data.to_string == 'y'}, :error1).once
|
1447
|
+
@mod.insert text, [:error, :error1], 3
|
1448
|
+
end
|
1449
|
+
|
1450
|
+
it 'returns an array with the items corresponding to the strings in the argument' do
|
1451
|
+
text = ['x', nil, nil, 'y', nil ]
|
1452
|
+
res = @mod.insert text, :error, 3
|
1453
|
+
res.should == [@mod.item(3,0), @mod.item(3,3)]
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
end
|
1457
|
+
|
1458
|
+
describe ', when the first argument is a string' do
|
1459
|
+
|
1460
|
+
it 'inserts a row having the given text as first column row at the given position if no optional argument is given' do
|
1461
|
+
flexmock(@mod).should_receive(:insert_row).with(3, FlexMock.on{|a| a.size == 1 and a[0].is_a?(Qt::StandardItem) and a[0].text == 'x'}).once
|
1462
|
+
@mod.insert 'x', :message, 3
|
1463
|
+
end
|
1464
|
+
|
1465
|
+
|
1466
|
+
it 'inserts a row having the given text as the given column and all the previous elements empty at the given position if the col optional argument is given' do
|
1467
|
+
flexmock(@mod).should_receive(:insert_row).with(3, FlexMock.on{|a| a.size == 4 and a[0].text.nil? and a[1].text.nil? and a[2].text.nil? and a[3].is_a?(Qt::StandardItem) and a[3].text == 'x'}).once
|
1468
|
+
3.times{@mod.append_column []}
|
1469
|
+
@mod.insert 'x', :message, 3, :col => 3
|
1470
|
+
end
|
1471
|
+
|
1472
|
+
it 'inserts the new row under the given parent if the :parent optional argument is given' do
|
1473
|
+
it = @mod.item(2,0)
|
1474
|
+
flexmock(it).should_receive(:insert_row).with(3, FlexMock.on{|a| a.size == 4 and a[0].text.nil? and a[1].text.nil? and a[2].text.nil? and a[3].is_a?(Qt::StandardItem) and a[3].text == 'x'}).once
|
1475
|
+
3.times{it.append_row []}
|
1476
|
+
3.times{it.append_column []}
|
1477
|
+
@mod.insert 'x', :message, 3, :col => 3, :parent => it
|
1478
|
+
end
|
1479
|
+
|
1480
|
+
it 'calls the output widget\'s set_output_type for the new item passing the second argument if the second argument is a symbol' do
|
1481
|
+
flexmock(@ow).should_receive(:set_output_type).with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.data.to_string == 'x'}, :error).once
|
1482
|
+
@mod.insert 'x', :error, 3
|
1483
|
+
end
|
1484
|
+
|
1485
|
+
it 'calls the output widget\'s set_output_type for the new item passing the first item in the second argument if the second argument is an array' do
|
1486
|
+
flexmock(@ow).should_receive(:set_output_type).with(FlexMock.on{|i| i.is_a?(Qt::ModelIndex) and i.data.to_string == 'x'}, :error).once
|
1487
|
+
@mod.insert 'x', [:error, :error1], 3
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
it 'returns an array with the items corresponding to the strings in the argument' do
|
1491
|
+
res = @mod.insert 'x', :error, 3
|
1492
|
+
res.should == [@mod.item(3,0)]
|
1493
|
+
end
|
1494
|
+
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
it 'counts rows and columns backwards if negative ' do
|
1498
|
+
@mod.clear
|
1499
|
+
10.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1500
|
+
@mod.insert 'x', :message, -3
|
1501
|
+
@mod.item(7,0).text.should == 'x'
|
1502
|
+
|
1503
|
+
@mod.clear
|
1504
|
+
10.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1505
|
+
4.times{|i| @mod.append_column []}
|
1506
|
+
@mod.insert 'x', :message, -3, :col => -3
|
1507
|
+
@mod.item(7,2).text.should == 'x'
|
1508
|
+
|
1509
|
+
@mod.clear
|
1510
|
+
@mod.append_row [Qt::StandardItem.new('p'), Qt::StandardItem.new('x')]
|
1511
|
+
it = @mod.item 0,0
|
1512
|
+
10.times{|i| it.append_row Qt::StandardItem.new(i.to_s)}
|
1513
|
+
@mod.insert 'x', :message, -3, :parent => it
|
1514
|
+
it.child(7,0).text.should == 'x'
|
1515
|
+
|
1516
|
+
@mod.clear
|
1517
|
+
@mod.append_row [Qt::StandardItem.new('p'), Qt::StandardItem.new('x')]
|
1518
|
+
it = @mod.item 0,0
|
1519
|
+
10.times{|i| it.append_row Qt::StandardItem.new(i.to_s)}
|
1520
|
+
4.times{|i| it.append_column []}
|
1521
|
+
@mod.insert 'x', :message, -3, :parent => it, :col => -3
|
1522
|
+
it.child(7,2).text.should == 'x'
|
1523
|
+
end
|
1524
|
+
|
1525
|
+
it 'considers the row to be equal to row_count if the third argument is nil' do
|
1526
|
+
@mod.insert 'x', :message, nil
|
1527
|
+
@mod.item(@mod.row_count - 1,0).text.should == 'x'
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
it 'always inserts a new row and never changes an existing one' do
|
1531
|
+
rc = @mod.row_count
|
1532
|
+
@mod.insert 'x', :message, 3
|
1533
|
+
@mod.row_count.should == rc + 1
|
1534
|
+
@mod.item(3,0).text.should == 'x'
|
1535
|
+
@mod.item(4,0).text.should == '3'
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
it 'raises IndexError if the specified row is greater than the row_count of the parent or is less than the opposite of that number' do
|
1539
|
+
lambda{@mod.insert 'x', :message, 15}.should raise_error(IndexError, "Row index 15 is out of range. The allowed values are from 0 to 5")
|
1540
|
+
lambda{@mod.insert 'x', :message, -15}.should raise_error(IndexError, "Row index -10 is out of range. The allowed values are from 0 to 5")
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
describe '#insert_lines' do
|
1546
|
+
|
1547
|
+
before do
|
1548
|
+
@ow = Ruber::OutputWidget.new
|
1549
|
+
@color = Qt::Color.new(0,0,255)
|
1550
|
+
@ow.set_color_for :message, @color
|
1551
|
+
@mod = @ow.model
|
1552
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1553
|
+
end
|
1554
|
+
|
1555
|
+
it 'inserts each line of the text as a separate item (one below the other), using the #insert method' do
|
1556
|
+
text = "a\nb\nc"
|
1557
|
+
lines = %w[a b c]
|
1558
|
+
|
1559
|
+
@mod.insert_lines text, :message, 2
|
1560
|
+
lines.each_with_index do |l, i|
|
1561
|
+
it = @mod.item(2+i)
|
1562
|
+
it.text.should == l
|
1563
|
+
it.foreground.color.should == @color
|
1564
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
@mod.clear
|
1568
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1569
|
+
@mod.insert_lines text, :message, 2, :col => 3
|
1570
|
+
lines.each_with_index do |l, i|
|
1571
|
+
it = @mod.item(2+i, 3)
|
1572
|
+
it.text.should == l
|
1573
|
+
it.foreground.color.should == @color
|
1574
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
@mod.clear
|
1578
|
+
5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
|
1579
|
+
@mod.item(1).insert_columns(0,3)
|
1580
|
+
@mod.item(1).insert_rows(0,2)
|
1581
|
+
@mod.insert_lines text, :message, 2, :col => 3, :parent => @mod.item(1)
|
1582
|
+
lines.each_with_index do |l, i|
|
1583
|
+
it = (@mod.item(1)).child(2+i, 3)
|
1584
|
+
it.text.should == l
|
1585
|
+
it.foreground.color.should == @color
|
1586
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
it 'counts lines and columns backwards if they\'re negative' do
|
1592
|
+
text = "a\nb\nc"
|
1593
|
+
flexmock(@mod).should_receive(:insert).with('a', :message, -5, :col => -2).once
|
1594
|
+
flexmock(@mod).should_receive(:insert).with('b', :message, -4, :col => -2).once
|
1595
|
+
flexmock(@mod).should_receive(:insert).with('c', :message, -3, :col => -2).once
|
1596
|
+
@mod.insert_lines text, :message, -5, :col => -2
|
1597
|
+
|
1598
|
+
it = Qt::StandardItem.new 'x'
|
1599
|
+
@mod.append_row it
|
1600
|
+
flexmock(@mod).should_receive(:insert).with('a', :message, -5, :col => -2, :parent => it).once
|
1601
|
+
flexmock(@mod).should_receive(:insert).with('b', :message, -4, :col => -2, :parent => it).once
|
1602
|
+
flexmock(@mod).should_receive(:insert).with('c', :message, -3, :col => -2, :parent => it).once
|
1603
|
+
@mod.insert_lines text, :message, -5, :col => -2, :parent => it
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
it 'appends the rows at the and if the third argument is nil' do
|
1607
|
+
text = "a\nb\nc"
|
1608
|
+
flexmock(@mod).should_receive(:insert).with('a', :message, nil,{}).once
|
1609
|
+
flexmock(@mod).should_receive(:insert).with('b', :message, nil, {}).once
|
1610
|
+
flexmock(@mod).should_receive(:insert).with('c', :message, nil, {}).once
|
1611
|
+
@mod.insert_lines text, :message, nil
|
1612
|
+
|
1613
|
+
it = Qt::StandardItem.new 'x'
|
1614
|
+
@mod.append_row it
|
1615
|
+
flexmock(@mod).should_receive(:insert).with('a', :message, nil, :parent => it).once
|
1616
|
+
flexmock(@mod).should_receive(:insert).with('b', :message, nil, :parent => it).once
|
1617
|
+
flexmock(@mod).should_receive(:insert).with('c', :message, nil, :parent => it).once
|
1618
|
+
@mod.insert_lines text, :message, nil, :parent => it
|
1619
|
+
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
describe 'if the first argument is an array' do
|
1623
|
+
|
1624
|
+
it 'inserts each entry as a separate item (one below the other), using the #insert method' do
|
1625
|
+
text = %w[a b c]
|
1626
|
+
@mod.insert_lines text, :message, 2
|
1627
|
+
lines = %w[a b c]
|
1628
|
+
lines.each_with_index do |l, i|
|
1629
|
+
it = @mod.item(2+i)
|
1630
|
+
it.text.should == l
|
1631
|
+
it.foreground.color.should == @color
|
1632
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
1633
|
+
end
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
it 'doesn\'t attempt to separate an entry into lines' do
|
1637
|
+
text = %w[a\n b\n c]
|
1638
|
+
@mod.insert_lines text, :message, 2
|
1639
|
+
lines = %w[a\n b\n c]
|
1640
|
+
lines.each_with_index do |l, i|
|
1641
|
+
it = @mod.item(2+i)
|
1642
|
+
it.text.should == l
|
1643
|
+
it.foreground.color.should == @color
|
1644
|
+
it.data(Ruber::OutputWidget::OutputTypeRole).to_string.should == 'message'
|
1645
|
+
end
|
1646
|
+
end
|
1647
|
+
|
1648
|
+
end
|
1649
|
+
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
end
|
1653
|
+
|
1654
|
+
describe Ruber::OutputWidget::ListView do
|
1655
|
+
|
1656
|
+
describe '#contextMenuEvent' do
|
1657
|
+
|
1658
|
+
it 'emits the "context_menu_requested(QPoint)" signal' do
|
1659
|
+
e = Qt::ContextMenuEvent.new Qt::ContextMenuEvent::Other, Qt::Point.new(1,2)
|
1660
|
+
flexmock(e).should_receive(:global_pos).once.and_return Qt::Point.new(2,3)
|
1661
|
+
view = Ruber::OutputWidget::ListView.new
|
1662
|
+
m = flexmock{|mk| mk.should_receive(:test).once.with(Qt::Point.new(2,3))}
|
1663
|
+
view.connect(SIGNAL('context_menu_requested(QPoint)')){|pt| m.test pt}
|
1664
|
+
view.send :contextMenuEvent, e
|
1665
|
+
end
|
1666
|
+
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
end
|
1670
|
+
|
1671
|
+
describe Ruber::OutputWidget::TreeView do
|
1672
|
+
|
1673
|
+
describe '#contextMenuEvent' do
|
1674
|
+
|
1675
|
+
it 'emits the "context_menu_requested(QPoint)" signal' do
|
1676
|
+
e = Qt::ContextMenuEvent.new Qt::ContextMenuEvent::Other, Qt::Point.new(1,2)
|
1677
|
+
flexmock(e).should_receive(:global_pos).once.and_return Qt::Point.new(2,3)
|
1678
|
+
view = Ruber::OutputWidget::TreeView.new
|
1679
|
+
m = flexmock{|mk| mk.should_receive(:test).once.with(Qt::Point.new(2,3))}
|
1680
|
+
view.connect(SIGNAL('context_menu_requested(QPoint)')){|pt| m.test pt}
|
1681
|
+
view.send :contextMenuEvent, e
|
1682
|
+
end
|
1683
|
+
|
1684
|
+
end
|
1685
|
+
|
1686
|
+
end
|
1687
|
+
|
1688
|
+
describe Ruber::OutputWidget::TableView do
|
1689
|
+
|
1690
|
+
describe '#contextMenuEvent' do
|
1691
|
+
|
1692
|
+
it 'emits the "context_menu_requested(QPoint)" signal' do
|
1693
|
+
e = Qt::ContextMenuEvent.new Qt::ContextMenuEvent::Other, Qt::Point.new(1,2)
|
1694
|
+
view = Ruber::OutputWidget::TableView.new
|
1695
|
+
flexmock(e).should_receive(:global_pos).once.and_return Qt::Point.new(2,3)
|
1696
|
+
m = flexmock{|mk| mk.should_receive(:test).once.with(Qt::Point.new(2,3))}
|
1697
|
+
view.connect(SIGNAL('context_menu_requested(QPoint)')){|pt| m.test pt}
|
1698
|
+
view.send :contextMenuEvent, e
|
1699
|
+
end
|
1700
|
+
|
1701
|
+
end
|
1702
|
+
|
1703
|
+
end
|