ruber 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,642 @@
1
+ require 'spec/common'
2
+
3
+ require 'ruber/filtered_output_widget'
4
+
5
+ describe Ruber::FilteredOutputWidget do
6
+
7
+ it 'inherits from Ruber::OutputWidget' do
8
+ Ruber::FilteredOutputWidget.ancestors.should include(Ruber::OutputWidget)
9
+ end
10
+
11
+ describe ', when created' do
12
+
13
+ it 'can take up to two arguments' do
14
+ lambda{Ruber::FilteredOutputWidget.new}.should_not raise_error
15
+ lambda{Ruber::FilteredOutputWidget.new Qt::Widget.new}.should_not raise_error
16
+ lambda{Ruber::FilteredOutputWidget.new Qt::Widget.new, {}}.should_not raise_error
17
+ end
18
+
19
+ it 'stores the contnet of the :filter optional entry in the @filter_model instance variable, if the :filter entry is given' do
20
+ mod = Qt::SortFilterProxyModel.new
21
+ ow = Ruber::FilteredOutputWidget.new nil, :filter => mod
22
+ ow.instance_variable_get(:@filter_model).should be_the_same_as(mod)
23
+ end
24
+
25
+ it 'takes ownership of the filter model, if the :filter entry is given' do
26
+ mod = Qt::SortFilterProxyModel.new
27
+ ow = Ruber::FilteredOutputWidget.new nil, :filter => mod
28
+ ow.filter_model.parent.should be_the_same_as(ow)
29
+ end
30
+
31
+ it 'creates a new instance of Ruber::FilteredOutputWidget::FilterModel and uses it as model, if the :filter entry isn\'t given' do
32
+ ow = Ruber::FilteredOutputWidget.new
33
+ ow.filter.should be_a(Ruber::FilteredOutputWidget::FilterModel)
34
+ ow.filter.parent.should be_the_same_as(ow)
35
+ end
36
+
37
+ it 'sets the dynamic_sort_filter property of the filter model to true' do
38
+ ow = Ruber::FilteredOutputWidget.new
39
+ ow.filter.dynamic_sort_filter.should be_true
40
+ end
41
+
42
+ it 'associates the model with the filter model' do
43
+ ow = Ruber::FilteredOutputWidget.new
44
+ ow.filter.source_model.should be_the_same_as(ow.model)
45
+ end
46
+
47
+ it 'associates the view with the filter model' do
48
+ ow = Ruber::FilteredOutputWidget.new
49
+ ow.view.model.should be_a(Ruber::FilteredOutputWidget::FilterModel)
50
+ end
51
+
52
+ it 'connects the view\'s selection model\'s selectionChanged signal with its own selection_changed slot' do
53
+ ow = Ruber::FilteredOutputWidget.new
54
+ flexmock(ow).should_receive(:selection_changed).once.with(Qt::ItemSelection, Qt::ItemSelection)
55
+ ow.view.selection_model.instance_eval{emit selectionChanged(Qt::ItemSelection.new, Qt::ItemSelection.new)}
56
+ end
57
+
58
+ it 'creates a KDE::LineEdit below the view and hides it' do
59
+ editor = KDE::LineEdit.new
60
+ flexmock(editor).should_receive(:hide).once
61
+ flexmock(KDE::LineEdit).should_receive(:new).once.with(Ruber::FilteredOutputWidget).and_return editor
62
+ ow = Ruber::FilteredOutputWidget.new
63
+ ow.layout.item_at_position(1,0).widget.should be_the_same_as(editor)
64
+ end
65
+
66
+ it 'overrides the editor\'s keyReleasedEvent method so that it hides the editor itself if the ESC key (without modifiers) is pressed' do
67
+ ow = Ruber::FilteredOutputWidget.new
68
+ ed = ow.instance_variable_get(:@editor)
69
+ flexmock(ed).should_receive(:hide).once
70
+ ev = Qt::KeyEvent.new Qt::KeyEvent::KeyRelease, Qt::Key_Escape, 0
71
+ ed.send :keyReleaseEvent, ev
72
+ ev = Qt::KeyEvent.new Qt::KeyEvent::KeyRelease, Qt::Key_A, 0, 'A'
73
+ ed.send :keyReleaseEvent, ev
74
+ mods = [
75
+ Qt::ControlModifier,
76
+ Qt::ShiftModifier,
77
+ Qt::AltModifier,
78
+ Qt::MetaModifier,
79
+ Qt::ControlModifier | Qt::ShiftModifier
80
+ ]
81
+ mods.each do |m|
82
+ ev = Qt::KeyEvent.new Qt::KeyEvent::KeyRelease, Qt::Key_Escape, m.to_i
83
+ ed.send :keyReleaseEvent, ev
84
+ end
85
+ end
86
+
87
+ it 'gives a completion object to the editor' do
88
+ ow = Ruber::FilteredOutputWidget.new
89
+ ow.instance_variable_get(:@editor).completion_object.should be_a(KDE::Completion)
90
+ end
91
+
92
+ it 'connects the editor\'s returnPressed(QString) signal with its own "create_filter_from_editor()" slot' do
93
+ ow = Ruber::FilteredOutputWidget.new
94
+ flexmock(ow).should_receive(:create_filter_from_editor).once
95
+ ow.instance_variable_get(:@editor).instance_eval{emit returnPressed('xyz')}
96
+ end
97
+
98
+ it 'adds the "Create Filter", "Ignore Filter" and "Clear Filter" entries to the action list, before the last separator' do
99
+ ow = Ruber::FilteredOutputWidget.new
100
+ ow.instance_variable_get(:@action_list).should == ['copy', 'copy_selected', nil, 'create_filter', 'ignore_filter', 'clear_filter', nil, 'clear']
101
+ end
102
+
103
+ it 'adds the "copy" and "clear_filter" actions to the actions hash' do
104
+ ow = Ruber::FilteredOutputWidget.new
105
+ hash = ow.instance_variable_get :@actions
106
+ hash['create_filter'].should be_a(KDE::Action)
107
+ hash['clear_filter'].should be_a(KDE::Action)
108
+ end
109
+
110
+ it 'adds a toggle "ignore_filter" action to the actions hash' do
111
+ ow = Ruber::FilteredOutputWidget.new
112
+ hash = ow.instance_variable_get :@actions
113
+ hash['ignore_filter'].should be_a(KDE::ToggleAction)
114
+ end
115
+
116
+ it 'connects the "create_filter" action with the show_editor slot' do
117
+ ow = Ruber::FilteredOutputWidget.new
118
+ flexmock(ow).should_receive(:show_editor).once
119
+ ow.instance_variable_get(:@actions)['create_filter'].instance_eval{emit triggered}
120
+ end
121
+
122
+ it 'connects the "clear_filter" action with the clear_filter slot' do
123
+ ow = Ruber::FilteredOutputWidget.new
124
+ flexmock(ow).should_receive(:clear_filter).once
125
+ ow.instance_variable_get(:@actions)['clear_filter'].instance_eval{emit triggered}
126
+ end
127
+
128
+ it 'connects the "ignore_filter" action\'s toggled(bool) signal with the ignore_filter(bool) slot' do
129
+ ow = Ruber::FilteredOutputWidget.new
130
+ flexmock(ow).should_receive(:ignore_filter).once.with(false)
131
+ ow.instance_variable_get(:@actions)['ignore_filter'].instance_eval{emit toggled(false)}
132
+ end
133
+
134
+ it 'creates a gui state handler for the clear_filter action which returns true if the no_filter state is false and false if the no_filter state is true' do
135
+ ow = Ruber::FilteredOutputWidget.new
136
+ handlers = ow.instance_variable_get(:@gui_state_handler_handlers)
137
+ handlers['no_filter'].find{|h| h.action.object_name == 'clear_filter'}.handler.call('no_filter' => true).should be_false
138
+ handlers['no_filter'].find{|h| h.action.object_name == 'clear_filter'}.handler.call('no_filter' => false).should be_true
139
+ end
140
+
141
+ it 'creates a gui state handler for the ignore_filter action which returns true if the no_filter state is false and false if the no_filter state is true' do
142
+ ow = Ruber::FilteredOutputWidget.new
143
+ handlers = ow.instance_variable_get(:@gui_state_handler_handlers)
144
+ handlers['no_filter'].find{|h| h.action.object_name == 'ignore_filter'}.handler.call('no_filter' => true).should be_false
145
+ handlers['no_filter'].find{|h| h.action.object_name == 'ignore_filter'}.handler.call('no_filter' => false).should be_true
146
+ end
147
+
148
+ it 'sets the "no_filter" gui state to true' do
149
+ ow = Ruber::FilteredOutputWidget.new
150
+ ow.gui_state('no_filter').should be_true
151
+ end
152
+
153
+ it 'disconnects the do_auto_scroll signal from the model and connects it to the filter model' do
154
+ ow = Ruber::FilteredOutputWidget.new
155
+ flexmock(ow).should_receive(:do_auto_scroll).once
156
+ ow.model.append_row Qt::StandardItem.new('x')
157
+ ow.filter.source_model = nil
158
+ ow.model.append_row Qt::StandardItem.new('y')
159
+ end
160
+
161
+ end
162
+
163
+ describe '#show_editor' do
164
+
165
+ before do
166
+ @ow = Ruber::FilteredOutputWidget.new
167
+ @ed = @ow.instance_variable_get(:@editor)
168
+ end
169
+
170
+ it 'shows the editor' do
171
+ flexmock(@ed).should_receive(:show).once
172
+ @ow.send :show_editor
173
+ end
174
+
175
+ it 'gives focus to the editor' do
176
+ flexmock(@ed).should_receive(:set_focus).once
177
+ @ow.send :show_editor
178
+ end
179
+
180
+ end
181
+
182
+ describe '#create_filter_from_editor' do
183
+
184
+ before do
185
+ @ow = Ruber::FilteredOutputWidget.new
186
+ @ed = @ow.instance_variable_get(:@editor)
187
+ @ed.text = 'xyz'
188
+ end
189
+
190
+ describe ', when the editor is not empty' do
191
+
192
+ it 'adds the text in the editor widget to the completion object' do
193
+ @ow.send :create_filter_from_editor
194
+ @ed.completion_object.items[0].should == 'xyz'
195
+ @ed.text = 'abc'
196
+ @ow.send :create_filter_from_editor
197
+ @ed.completion_object.items.should == %w[xyz abc]
198
+ end
199
+
200
+ it 'doesn\'t add an existing item' do
201
+ @ow.send :create_filter_from_editor
202
+ @ow.send :create_filter_from_editor
203
+ @ed.completion_object.items.size.should == 1
204
+ end
205
+
206
+ it 'passes the text in the editor to the filter_reg_exp= method of the filter model' do
207
+ flexmock(@ow.filter).should_receive(:filter_reg_exp=).once.with('xyz')
208
+ @ow.send :create_filter_from_editor
209
+ end
210
+
211
+ it 'sets the "no_filter" gui state to false' do
212
+ @ow.send :create_filter_from_editor
213
+ @ow.gui_state('no_filter').should be_false
214
+ end
215
+
216
+ it 'doesn\'t call the "clear_filter" method' do
217
+ flexmock(@ow).should_receive(:clear_filter).never
218
+ @ow.send :create_filter_from_editor
219
+ end
220
+
221
+ end
222
+
223
+ describe ', when the editor is empty' do
224
+
225
+ before do
226
+ @ed.clear
227
+ end
228
+
229
+ it 'doesn\'t add entries to the editor\'s completion object' do
230
+ @ed.text = 'xyz'
231
+ @ow.send :create_filter_from_editor
232
+ @ed.clear
233
+ @ow.send :create_filter_from_editor
234
+ @ed.completion_object.items.should == ['xyz']
235
+ end
236
+
237
+ it 'calls the "clear_filter" method' do
238
+ flexmock(@ow).should_receive(:clear_filter).once
239
+ @ow.send :create_filter_from_editor
240
+ end
241
+
242
+ it 'doesn\'t call the filter model\'s filter_reg_exp= method' do
243
+ flexmock(@ow).should_receive(:clear_filter)
244
+ flexmock(@ow.filter).should_receive(:filter_reg_exp=).never
245
+ @ow.send :create_filter_from_editor
246
+ end
247
+
248
+ end
249
+
250
+ it 'hides the editor' do
251
+ flexmock(@ed).should_receive(:hide).twice
252
+ @ow.send :create_filter_from_editor
253
+ @ed.clear
254
+ @ow.send :create_filter_from_editor
255
+ end
256
+
257
+ end
258
+
259
+ describe '#clear_filter' do
260
+
261
+ before do
262
+ @ow = Ruber::FilteredOutputWidget.new
263
+ end
264
+
265
+ it 'calls the filter model\'s filter_reg_exp= method passing it an empty string' do
266
+ flexmock(@ow.filter).should_receive(:filter_reg_exp=).once.with('')
267
+ @ow.send :clear_filter
268
+ end
269
+
270
+ it 'sets the "no_filter" gui state to true' do
271
+ @ow.set_state 'no_filter', false
272
+ @ow.send :clear_filter
273
+ @ow.gui_state('no_filter').should be_true
274
+ end
275
+
276
+ end
277
+
278
+ describe '#toggle_ignore_filter' do
279
+
280
+ it 'calls the ignore_filter= method of the filter model passing the argument' do
281
+ ow = Ruber::FilteredOutputWidget.new
282
+ flexmock(ow.filter).should_receive(:ignore_filter=).once.with true
283
+ flexmock(ow.filter).should_receive(:ignore_filter=).once.with false
284
+ ow.send :ignore_filter, true
285
+ ow.send :ignore_filter, false
286
+ end
287
+
288
+ end
289
+
290
+ describe '#copy' do
291
+
292
+ before do
293
+ @ow = Ruber::FilteredOutputWidget.new
294
+ @mod = @ow.model
295
+ @filter = @ow.filter
296
+ def @filter.filterAcceptsRow r, parent
297
+ return true if parent.valid?
298
+ idx = source_model.index(r, 0)
299
+ idx.data.to_int < 4
300
+ end
301
+ 5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
302
+ @filter.invalidate
303
+ end
304
+
305
+ it 'calls the text_for_clipboard method passing it an array containing all the indexes in the filter model, but referred to the source model' do
306
+ c1 = Qt::StandardItem.new 'c1'
307
+ c2 = Qt::StandardItem.new 'c2'
308
+ c3 = Qt::StandardItem.new 'c3'
309
+ it = @mod.item(3,0)
310
+ # Somehow, autoscrolling messes up the indexes
311
+ @ow.with_auto_scrolling(false) do
312
+ c1.append_row c3
313
+ it.append_row c1
314
+ it.append_row c2
315
+ end
316
+ exp = [@mod.index(0,0), @mod.index(1,0), @mod.index(2,0), it.index, c1.index, c3.index, c2.index]
317
+ flexmock(@ow).should_receive(:text_for_clipboard).once.with(exp)
318
+ @ow.send :copy
319
+ end
320
+
321
+ it 'inserts the value returned by text_for_clipboard in the clipboard' do
322
+ text = random_string
323
+ flexmock(@ow).should_receive(:text_for_clipboard).once.with(4.times.map{|i| @mod.index(i,0)}).and_return text
324
+ @ow.send :copy
325
+ KDE::Application.clipboard.text.should == text
326
+ end
327
+
328
+ end
329
+
330
+ describe '#copy_selected' do
331
+
332
+ before do
333
+ @ow = Ruber::FilteredOutputWidget.new
334
+ @mod = @ow.model
335
+ @filter = @ow.filter
336
+ 5.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
337
+ @mod.append_column 5.times.map{|i| Qt::StandardItem.new (i+5).to_s}
338
+ def @filter.filterAcceptsRow r, parent
339
+ return true if parent.valid?
340
+ idx = source_model.index(r, 0)
341
+ idx.data.to_int < 4
342
+ end
343
+ @filter.invalidate
344
+ sm = @ow.view.selection_model
345
+ @exp = [[1,0], [2,1], [3,1]].map{|i, j| @mod.index i, j}
346
+ @exp.each{|i| sm.select @filter.map_from_source(i), Qt::ItemSelectionModel::Select}
347
+ end
348
+
349
+ it 'calls the text_for_clipboard method passing the list of selected items in the source model as argument' do
350
+ flexmock(@ow).should_receive(:text_for_clipboard).once.with @exp
351
+ @ow.send :copy_selected
352
+ end
353
+
354
+ it 'inserts the value returned by text_for_clipboard in the clipboard' do
355
+ text = random_string
356
+ flexmock(@ow).should_receive(:text_for_clipboard).once.with(@exp).and_return text
357
+ @ow.send :copy_selected
358
+ KDE::Application.clipboard.text.should == text
359
+ end
360
+
361
+ end
362
+
363
+ describe '#scroll_to' do
364
+
365
+ before do
366
+ @ow = Ruber::FilteredOutputWidget.new
367
+ @mod = @ow.model
368
+ @filter = @ow.filter
369
+ def @filter.filterAcceptsRow row, parent
370
+ idx = source_model.index(row, 0)
371
+ idx.data.to_int % 2 != 0
372
+ end
373
+ 10.times{|i| @mod.append_row Qt::StandardItem.new(i.to_s)}
374
+ @filter.invalidate
375
+ end
376
+
377
+ describe ', when called with a positive integer' do
378
+
379
+ it 'it scrolls the view so that the row with the argument as index (in the filter model) is visible' do
380
+ idx = @filter.index(3, 0)
381
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
382
+ @ow.scroll_to 3
383
+ end
384
+
385
+ it 'scrolls to the last item if the argument is greater than the index of the last row of the filter model' do
386
+ idx = @filter.index(@filter.row_count - 1, 0)
387
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
388
+ @ow.scroll_to @filter.row_count + 3
389
+ end
390
+
391
+ end
392
+
393
+ describe ', when called with a negative integer' do
394
+
395
+ it 'scrolls the view so that the row with index the argument (in the filter model), counting from below, is visible' do
396
+ idx = @filter.index(3, 0)
397
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
398
+ @ow.scroll_to -2
399
+ end
400
+
401
+ it 'scrolls to the first item if the absolute value of the argument is greater than the index of the last row - 1 (in the filter model)' do
402
+ idx = @filter.index(0, 0)
403
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
404
+ @ow.scroll_to -8
405
+ end
406
+
407
+ end
408
+
409
+ describe ', when called with a Qt::ModelIndex' do
410
+
411
+ it 'converts the index to the filter model, if it refers to the source model' do
412
+ src_idx = @mod.index(1,0)
413
+ idx = @filter.map_from_source src_idx
414
+ flexmock(@filter).should_receive(:map_from_source).once.with(src_idx).and_return idx
415
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
416
+ @ow.scroll_to src_idx
417
+ end
418
+
419
+ it 'doesn\'t attempt to convert the index if it already refers to the filter model' do
420
+ idx = @filter.index(2,0)
421
+ flexmock(@filter).should_receive(:map_from_source).never
422
+ @ow.scroll_to idx
423
+ end
424
+
425
+ it 'scrolls the view so that the item corresponding to the index is visible' do
426
+ @mod.append_column(5.times.map{|i| Qt::StandardItem.new (2*i).to_s})
427
+ @filter.invalidate
428
+ idx = @filter.map_from_source @mod.index(3,1)
429
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
430
+ @ow.scroll_to idx
431
+ end
432
+
433
+ it 'scrolls to the last element of the filter model if the index is invalid' do
434
+ idx = @filter.index(@filter.row_count - 1,0)
435
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
436
+ @ow.scroll_to Qt::ModelIndex.new
437
+ end
438
+
439
+ end
440
+
441
+ describe ', when called with nil' do
442
+
443
+ it 'scrolls to the last element of the filter model' do
444
+ idx = @filter.index(@filter.row_count - 1,0)
445
+ flexmock(@ow.view).should_receive(:scroll_to).with(idx).once
446
+ @ow.scroll_to nil
447
+ end
448
+
449
+ end
450
+
451
+ end
452
+
453
+ describe '#maybe_open_file' do
454
+
455
+ before do
456
+ unless Ruber.constants.include? :Application
457
+ Ruber::Application = flexmock(:keyboard_modifiers => 0)
458
+ end
459
+ @ow = Ruber::FilteredOutputWidget.new
460
+ @mod = @ow.model
461
+ @filter = @ow.filter
462
+ @mod.append_row Qt::StandardItem.new('x')
463
+ end
464
+
465
+ it 'converts the index from the filter model to the source model before calling super' do
466
+ flexmock(@ow).should_receive(:find_filename_in_index).with(FlexMock.on{|i| i.model.equal?(@mod) and i.data.to_string == 'x'}).once
467
+ @ow.send :maybe_open_file, @filter.index(0,0)
468
+ end
469
+
470
+ it 'doesn\'t attempt to convert the index if it already refers to the source model' do
471
+ flexmock(@filter).should_receive(:map_to_source).never
472
+ flexmock(@ow).should_receive(:find_filename_in_index).with(FlexMock.on{|i| i.model.equal?(@mod) and i.data.to_string == 'x'}).once
473
+ @ow.send :maybe_open_file, @mod.index(0,0)
474
+ end
475
+
476
+ after do
477
+ Ruber.send :remove_const, :Application unless Ruber::Application.is_a?(KDE::Application)
478
+ end
479
+
480
+ end
481
+
482
+
483
+ end
484
+
485
+ describe Ruber::FilteredOutputWidget::FilterModel do
486
+
487
+ it 'inherits Qt::SortFilterProxyModel' do
488
+ Ruber::FilteredOutputWidget::FilterModel.ancestors.should include(Qt::SortFilterProxyModel)
489
+ end
490
+
491
+ describe ', when created' do
492
+
493
+ it 'takes up to two arguments' do
494
+ lambda{Ruber::FilteredOutputWidget::FilterModel.new}.should_not raise_error
495
+ lambda{Ruber::FilteredOutputWidget::FilterModel.new Qt::Widget.new}.should_not raise_error
496
+ lambda{Ruber::FilteredOutputWidget::FilterModel.new nil, :top_level}.should_not raise_error
497
+ end
498
+
499
+ it 'stores the second argument passed to the constructor in the @exclude instance variable' do
500
+ mod = Ruber::FilteredOutputWidget::FilterModel.new nil, :top_level
501
+ mod.exclude.should == :top_level
502
+ end
503
+
504
+ it 'doesn\'t ignore the filter' do
505
+ mod = Ruber::FilteredOutputWidget::FilterModel.new nil, :top_level
506
+ mod.filter_ignored?.should be_false
507
+ end
508
+
509
+ end
510
+
511
+ describe '#ignore_filter=' do
512
+
513
+ before do
514
+ @mod = Ruber::FilteredOutputWidget::FilterModel.new
515
+ end
516
+
517
+ it 'sets the @ignore_filter instance variable to the argument' do
518
+ @mod.ignore_filter = true
519
+ @mod.filter_ignored?.should be_true
520
+ end
521
+
522
+ it 'invalidates the model' do
523
+ flexmock(@mod).should_receive(:invalidate).once
524
+ @mod.ignore_filter = true
525
+ end
526
+
527
+ end
528
+
529
+ describe '#filter_reg_exp=' do
530
+
531
+ before do
532
+ @mod = Ruber::FilteredOutputWidget::FilterModel.new
533
+ end
534
+
535
+ it 'sets the filter reg exp to the argument' do
536
+ @mod.filter_reg_exp = 'a.*'
537
+ @mod.filter_reg_exp.should == Qt::RegExp.new('a.*')
538
+ end
539
+
540
+ it 'emits the filter_changed(QString) signal' do
541
+ m = flexmock{|mk| mk.should_receive(:test).once.with('a.*')}
542
+ @mod.connect(SIGNAL('filter_changed(QString)')){|s| m.test s}
543
+ @mod.filter_reg_exp = 'a.*'
544
+ end
545
+
546
+ end
547
+
548
+ describe '#filterAcceptsRow' do
549
+
550
+ before do
551
+ @source = Qt::StandardItemModel.new
552
+ 5.times{|i| @source.append_row Qt::StandardItem.new(i.to_s)}
553
+ @mod = Ruber::FilteredOutputWidget::FilterModel.new
554
+ @mod.source_model = @source
555
+ end
556
+
557
+ it 'always returns true if the filter is ignored' do
558
+ @mod.ignore_filter = true
559
+ @mod.filter_reg_exp = '[12]'
560
+ 5.times do |i|
561
+ @mod.send(:filterAcceptsRow, i, Qt::ModelIndex.new).should be_true
562
+ end
563
+ end
564
+
565
+ it 'always returns true if calling the exclude_from_filtering? method with the given row and parent returns true' do
566
+ 5.times{|i| flexmock(@mod).should_receive(:exclude_from_filtering?).once.with(i, Qt::ModelIndex).and_return(true)}
567
+ @mod.filter_reg_exp = '[12]'
568
+ 5.times do |i|
569
+ @mod.send(:filterAcceptsRow, i, Qt::ModelIndex.new).should be_true
570
+ end
571
+ end
572
+
573
+ it 'filters any row for which exclude_from_filtering? returns false according to the regexp' do
574
+ @mod.filter_reg_exp = '[12]'
575
+ flexmock(@mod).should_receive(:exclude_from_filtering?).once.with(0, Qt::ModelIndex).and_return(true)
576
+ flexmock(@mod).should_receive(:exclude_from_filtering?).and_return(false)
577
+ @mod.send(:filterAcceptsRow, 0, Qt::ModelIndex.new).should be_true
578
+ @mod.send(:filterAcceptsRow, 1, Qt::ModelIndex.new).should be_true
579
+ @mod.send(:filterAcceptsRow, 2, Qt::ModelIndex.new).should be_true
580
+ @mod.send(:filterAcceptsRow, 3, Qt::ModelIndex.new).should be_false
581
+ @mod.send(:filterAcceptsRow, 4, Qt::ModelIndex.new).should be_false
582
+ end
583
+
584
+ end
585
+
586
+ describe '#exclude=' do
587
+
588
+ before do
589
+ @source = Qt::StandardItemModel.new
590
+ 5.times{|i| @source.append_row Qt::StandardItem.new(i.to_s)}
591
+ @source.item(0,0).append_row Qt::StandardItem.new('c')
592
+ @mod = Ruber::FilteredOutputWidget::FilterModel.new
593
+ @mod.source_model = @source
594
+ end
595
+
596
+ it 'replaces the @exclude instance variable with the argument' do
597
+ @mod.instance_variable_set :@exclude, :children
598
+ @mod.exclude = :toplevel
599
+ @mod.instance_variable_get(:@exclude).should == :toplevel
600
+ end
601
+
602
+ it 'invalidates the filter' do
603
+ flexmock(@mod).should_receive(:invalidate_filter).once
604
+ @mod.exclude = :toplevel
605
+ end
606
+
607
+ end
608
+
609
+ describe '#exclude_from_filtering?' do
610
+
611
+ before do
612
+ @source = Qt::StandardItemModel.new
613
+ 5.times{|i| @source.append_row Qt::StandardItem.new(i.to_s)}
614
+ @source.item(0,0).append_row Qt::StandardItem.new('c')
615
+ @mod = Ruber::FilteredOutputWidget::FilterModel.new
616
+ @mod.source_model = @source
617
+ end
618
+
619
+ it 'returns false for child items and true for toplevel items if the @exclude instance variable is :toplevel' do
620
+ @mod.exclude = :toplevel
621
+ @mod.send(:exclude_from_filtering?, 0, Qt::ModelIndex.new).should be_true
622
+ @mod.send(:exclude_from_filtering?, 0, @source.index(0,0)).should be_false
623
+ end
624
+
625
+ it 'returns true for child items and false for toplevel items if the @exclude instance variable is :children' do
626
+ @mod.exclude = :children
627
+ @mod.send(:exclude_from_filtering?, 0, Qt::ModelIndex.new).should be_false
628
+ @mod.send(:exclude_from_filtering?, 0, @source.index(0,0)).should be_true
629
+ end
630
+
631
+ it 'always returns false for other values of the @exclude instance variable' do
632
+ @mod.exclude = :nil
633
+ @mod.send(:exclude_from_filtering?, 0, Qt::ModelIndex.new).should be_false
634
+ @mod.send(:exclude_from_filtering?, 0, @source.index(0,0)).should be_false
635
+ @mod.exclude = :x
636
+ @mod.send(:exclude_from_filtering?, 0, Qt::ModelIndex.new).should be_false
637
+ @mod.send(:exclude_from_filtering?, 0, @source.index(0,0)).should be_false
638
+ end
639
+
640
+ end
641
+
642
+ end