metaruby 1.0.0.rc1 → 1.0.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,9 +5,12 @@
5
5
  <link rel="stylesheet" href="<%= prefix %><%= File.join(ressource_dir, 'page.css') %>" type="text/css" />
6
6
  <script type="text/javascript" src="<%= prefix %><%= File.join(ressource_dir, 'jquery.min.js') %>"></script>
7
7
  <script type="text/javascript" src="<%= prefix %><%= File.join(ressource_dir, 'jquery.selectfilter.js') %>"></script>
8
+ <% javascript.each do |js| %>
9
+ <script type="text/javascript" src="<%= prefix %><%= File.expand_path(js, ressource_dir) %>"></script>
10
+ <% end %>
8
11
  <title><%= page_name %></title>
9
12
  </html>
10
13
  <body>
11
- <%= html_body(:ressource_dir => ressource_dir) %>
14
+ <%= html_body(ressource_dir: ressource_dir) %>
12
15
  </body>
13
16
 
@@ -1,17 +1,10 @@
1
1
  <% if title %>
2
- <h1><%= title %></h1>
2
+ <h1><%= title %></h1>
3
3
  <% end %>
4
4
  <% fragments.each do |fragment| %>
5
- <% if fragment.title %>
6
- <h2><%= fragment.title %></h2>
7
- <% end %>
8
- <%= HTML.render_button_bar(fragment.buttons) %>
9
- <% if fragment.id %>
10
- <div id="<%= fragment.id %>">
11
- <% end %>
12
- <%= fragment.html %>
5
+ <%= html_fragment(fragment, ressource_dir: ressource_dir) %>
13
6
  <% if fragment.id %>
14
- </div>
7
+ </div>
15
8
  <% end %>
16
9
  <% end %>
17
10
 
@@ -32,8 +32,6 @@ module MetaRuby
32
32
  # @return [ExceptionView] view that allows to display errors to the
33
33
  # user
34
34
  attr_reader :exception_view
35
- # @return [Qt::PushButton] button that causes model reloading
36
- attr_reader :btn_reload_models
37
35
  # @return [RenderingManager] the object that manages all the
38
36
  # rendering objects available
39
37
  attr_reader :manager
@@ -46,12 +44,21 @@ module MetaRuby
46
44
  attr_reader :history
47
45
  # @return [Integer] the index of the current link in the history
48
46
  attr_reader :history_index
47
+ # @return [Qt::BoxLayout] the main layout
48
+ attr_reader :main_layout
49
+
50
+ # @return [Qt::Splitter] the toplevel splitter (between model
51
+ # browser and exception view)
52
+ attr_reader :vertical_splitter
53
+ # @return [Qt::Splitter] the horizontal splitter between the model browser and
54
+ # the model view
55
+ attr_reader :central_splitter
49
56
 
50
57
  # A Page object with a #link_to method that is suitable for the
51
58
  # model browser
52
59
  class Page < HTML::Page
53
60
  def uri_for(object)
54
- if (obj_name = object.name) && (obj_name =~ /^[\w:]+$/)
61
+ if object.respond_to?(:name) && (obj_name = object.name) && (obj_name =~ /^[\w:]+$/)
55
62
  path = obj_name.split("::")
56
63
  "/" + path.join("/")
57
64
  else super
@@ -60,36 +67,52 @@ module MetaRuby
60
67
  end
61
68
 
62
69
 
63
- def initialize(main = nil)
64
- super
70
+ def initialize(main = nil, exception_view: nil)
71
+ super(main)
72
+
73
+ @available_renderers = Hash.new
74
+ @registered_exceptions = Array.new
75
+
76
+ @history = Array.new
77
+ @history_index = -1
65
78
 
66
79
  @manager = RenderingManager.new
67
80
 
68
- main_layout = Qt::VBoxLayout.new(self)
81
+ @main_layout = Qt::VBoxLayout.new(self)
82
+ @vertical_splitter = Qt::Splitter.new(Qt::Vertical, self)
83
+ main_layout.add_widget(vertical_splitter)
69
84
 
70
- menu_layout = Qt::HBoxLayout.new
71
- main_layout.add_layout(menu_layout)
72
- central_layout = Qt::HBoxLayout.new
73
- main_layout.add_layout(central_layout, 3)
74
- splitter = Qt::Splitter.new(self)
75
- central_layout.add_widget(splitter)
76
- @exception_view = ExceptionView.new
77
- main_layout.add_widget(exception_view, 1)
85
+ @central_splitter = Qt::Splitter.new(vertical_splitter)
86
+ @exception_view = (exception_view ||= ExceptionView.new)
87
+ exception_view.parent = vertical_splitter
88
+ connect(exception_view, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
89
+ add_central_widgets(central_splitter)
78
90
 
79
- @available_renderers = Hash.new
80
- @registered_exceptions = Array.new
91
+ vertical_splitter.add_widget(central_splitter)
92
+ vertical_splitter.add_widget(exception_view)
93
+ setTabOrder(model_selector, display)
81
94
 
82
- @btn_reload_models = Qt::PushButton.new("Reload", self)
83
- menu_layout.add_widget(btn_reload_models)
84
- menu_layout.add_stretch(1)
85
95
  update_exceptions
96
+ end
86
97
 
87
- @history = Array.new
88
- @history_index = -1
98
+ def restore_from_settings(settings)
99
+ %w{central_splitter vertical_splitter}.each do |object_name|
100
+ sizes = settings.value(object_name)
101
+ if !sizes.null?
102
+ sizes = sizes.to_list.map do |obj|
103
+ obj.to_int
104
+ end
105
+ send(object_name).sizes = sizes
106
+ end
107
+ end
108
+ end
89
109
 
90
- add_central_widgets(splitter)
91
- setTabOrder(model_selector, display)
92
- setTabOrder(display, btn_reload_models)
110
+ def save_to_settings(settings)
111
+ %w{central_splitter vertical_splitter}.each do |object_name|
112
+ sizes = send(object_name).sizes
113
+ sizes = sizes.map { |o| Qt::Variant.new(o) }
114
+ settings.set_value(object_name, Qt::Variant.new(sizes))
115
+ end
93
116
  end
94
117
 
95
118
  # Update the model selector after {register_type} got called
@@ -171,10 +194,13 @@ module MetaRuby
171
194
  end
172
195
  end
173
196
  connect(page, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
197
+ connect(page, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
174
198
  connect(manager, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
175
199
  @page = page
176
200
  end
177
201
 
202
+ signals 'fileOpenClicked(const QUrl&)'
203
+
178
204
  # Call to render the given model
179
205
  #
180
206
  # @param [Model] mod the model that should be rendered
@@ -257,6 +283,11 @@ module MetaRuby
257
283
  else select_by_module(h)
258
284
  end
259
285
  end
286
+
287
+ # Update the model list
288
+ def reload
289
+ model_selector.reload
290
+ end
260
291
  end
261
292
  end
262
293
  end
@@ -19,6 +19,9 @@ module MetaRuby
19
19
  super
20
20
 
21
21
  @type_info = Hash.new
22
+ @browser_model = RubyConstantsItemModel.new(type_info) do |mod|
23
+ model?(mod)
24
+ end
22
25
  @type_filters = Hash.new
23
26
 
24
27
  layout = Qt::VBoxLayout.new(self)
@@ -141,6 +144,7 @@ module MetaRuby
141
144
  model_filter.dynamic_sort_filter = true
142
145
  model_filter.filter_role = Qt::UserRole
143
146
  model_list.model = model_filter
147
+ model_filter.source_model = browser_model
144
148
 
145
149
  @filter_box = Qt::LineEdit.new(self)
146
150
  filter_box.connect(SIGNAL('textChanged(QString)')) do |text|
@@ -175,11 +179,7 @@ module MetaRuby
175
179
  end
176
180
  end
177
181
 
178
- @browser_model = RubyConstantsItemModel.new(type_info) do |mod|
179
- model?(mod)
180
- end
181
182
  browser_model.reload
182
- model_filter.source_model = browser_model
183
183
 
184
184
  if current_path && !select_by_path(*current_path)
185
185
  select_by_module(current_module)
@@ -229,7 +229,7 @@ module MetaRuby
229
229
  def select_by_path(*path)
230
230
  if index = browser_model.find_index_by_path(*path)
231
231
  index = map_index_from_source(index)
232
- model_list.selection_model.set_current_index(index, Qt::ItemSelectionModel::ClearAndSelect)
232
+ model_list.current_index = index
233
233
  true
234
234
  end
235
235
  end
@@ -242,7 +242,7 @@ module MetaRuby
242
242
  def select_by_module(model)
243
243
  if index = browser_model.find_index_by_model(model)
244
244
  index = map_index_from_source(index)
245
- model_list.selection_model.set_current_index(index, Qt::ItemSelectionModel::ClearAndSelect)
245
+ model_list.current_index = index
246
246
  true
247
247
  end
248
248
  end
@@ -29,6 +29,7 @@ module MetaRuby
29
29
  end
30
30
 
31
31
  def reload
32
+ begin_reset_model
32
33
  @id_to_module = []
33
34
  @filtered_out_modules = Set.new
34
35
 
@@ -41,8 +42,12 @@ module MetaRuby
41
42
 
42
43
  @object_paths = Hash.new
43
44
  generate_paths(object_paths, info, "")
45
+ ensure
46
+ end_reset_model
47
+ end
44
48
 
45
- emit dataChanged(Qt::ModelIndex.new, Qt::ModelIndex.new)
49
+ def root_info
50
+ id_to_module.last
46
51
  end
47
52
 
48
53
  def generate_paths(paths, info, current)
@@ -176,7 +181,7 @@ module MetaRuby
176
181
  type_info[type].name
177
182
  end.sort.join(",")
178
183
  paths = [compute_path(info)]
179
- paths.concat info.children.map { |child| compute_path(child) }
184
+ paths.concat info.children.map { |child| compute_keyword_string(child) }
180
185
  info.keyword_string = "#{types};#{paths.join(",")}"
181
186
  end
182
187
  end
@@ -205,7 +210,7 @@ module MetaRuby
205
210
 
206
211
  def parent(child)
207
212
  if info = info_from_index(child)
208
- if info.parent
213
+ if info.parent && info.parent != root_info
209
214
  return create_index(info.parent.row, 0, info.parent.id)
210
215
  end
211
216
  end
@@ -239,6 +244,10 @@ module MetaRuby
239
244
 
240
245
  def find_index_by_path(*path)
241
246
  current = id_to_module.last
247
+ if path.first == current.name
248
+ path.shift
249
+ end
250
+
242
251
  path.each do |name|
243
252
  current = id_to_module.find do |info|
244
253
  info.name == name && info.parent == current
@@ -280,6 +280,12 @@ module MetaRuby
280
280
  false
281
281
  end
282
282
  EOF
283
+ else
284
+ class_eval <<-EOF, __FILE__, __LINE__+1
285
+ def has_#{name}?(key)
286
+ each_#{name}.any? { |obj| obj == key }
287
+ end
288
+ EOF
283
289
  end
284
290
 
285
291
  class_eval <<-EOF, __FILE__, __LINE__+1
@@ -1,5 +1,5 @@
1
- require 'utilrb/value_set'
2
1
  require 'utilrb/module/const_defined_here_p'
2
+
3
3
  module MetaRuby
4
4
  # Extend in modules that are used as models
5
5
  #
@@ -150,7 +150,7 @@ module MetaRuby
150
150
  self.supermodel = model.supermodel
151
151
  end
152
152
  self.supermodel.register_submodel(self)
153
- self.parent_models |= model.parent_models
153
+ self.parent_models.merge(model.parent_models)
154
154
  self.parent_models << model
155
155
  end
156
156
  end
@@ -21,7 +21,7 @@ module MetaRuby
21
21
  # @return [Boolean]
22
22
  attr_predicate :permanent_model?, true
23
23
 
24
- # [Set] the set of models that are children of this one
24
+ # @return [Set] the set of models that are children of this one
25
25
  attribute(:submodels) { Set.new }
26
26
 
27
27
  # Returns the model that is parent of this one
@@ -141,10 +141,10 @@ module MetaRuby
141
141
  #
142
142
  # This is usually not called directly. Use #clear_submodels instead
143
143
  #
144
- # @param [Set] set the set of submodels to remove
144
+ # @param [ValueSet] set the set of submodels to remove
145
145
  def deregister_submodels(set)
146
146
  current_size = submodels.size
147
- submodels.subtract(set)
147
+ submodels.subtract(set.to_value_set)
148
148
  if m = supermodel
149
149
  m.deregister_submodels(set)
150
150
  end
@@ -3,7 +3,9 @@
3
3
  if ENV['TEST_ENABLE_COVERAGE'] == '1'
4
4
  begin
5
5
  require 'simplecov'
6
- SimpleCov.start
6
+ SimpleCov.start do
7
+ add_filter "test"
8
+ end
7
9
  rescue LoadError
8
10
  require 'metaruby'
9
11
  MetaRuby.warn "coverage is disabled because the 'simplecov' gem cannot be loaded"
@@ -16,7 +18,7 @@ end
16
18
  require 'metaruby'
17
19
  require 'minitest/autorun'
18
20
  require 'minitest/spec'
19
- require 'flexmock/test_unit'
21
+ require 'flexmock/minitest'
20
22
 
21
23
  if ENV['TEST_ENABLE_PRY'] != '0'
22
24
  begin
@@ -41,33 +43,15 @@ module MetaRuby
41
43
  # end
42
44
  #
43
45
  module SelfTest
44
- if defined? FlexMock
45
- include FlexMock::ArgumentTypes
46
- include FlexMock::MockContainer
47
- end
48
-
49
46
  def setup
50
47
  # Setup code for all the tests
51
48
  end
52
49
 
53
50
  def teardown
54
- if defined? FlexMock
55
- flexmock_teardown
56
- end
57
- # Teardown code for all the tests
58
51
  end
59
52
  end
60
53
  end
61
54
 
62
- # Workaround a problem with flexmock and minitest not being compatible with each
63
- # other (currently). See github.com/jimweirich/flexmock/issues/15.
64
- if defined?(FlexMock) && !FlexMock::TestUnitFrameworkAdapter.method_defined?(:assertions)
65
- class FlexMock::TestUnitFrameworkAdapter
66
- attr_accessor :assertions
67
- end
68
- FlexMock.framework_adapter.assertions = 0
69
- end
70
-
71
55
  module Minitest
72
56
  class Spec
73
57
  include MetaRuby::SelfTest
@@ -0,0 +1,3 @@
1
+ module MetaRuby
2
+ VERSION = "1.0.0.rc2"
3
+ end
@@ -0,0 +1,117 @@
1
+ require 'pp'
2
+ module MetaRuby
3
+ module YARD
4
+ include ::YARD
5
+ class InheritedAttributeHandler < YARD::Handlers::Ruby::AttributeHandler
6
+ handles method_call(:inherited_attribute)
7
+ namespace_only
8
+
9
+ def self.process(handler, name, attr_name, is_map, key_name = nil, return_type = nil)
10
+ end
11
+
12
+ def process
13
+ name = statement.parameters[0].jump(:tstring_content, :ident).source
14
+ if statement.parameters.size == 4
15
+ attr_name = statement.parameters[1].jump(:tstring_content, :ident).source
16
+ else
17
+ attr_name = name
18
+ end
19
+ options = statement.parameters.jump(:assoc)
20
+
21
+ is_map = false
22
+ if options != statement.parameters
23
+ key = options[0].jump(:ident).source
24
+ value = options[1].jump(:ident).source
25
+ if key == "map" && value == "true"
26
+ is_map = true
27
+ end
28
+ end
29
+
30
+ key_type, value_type = nil
31
+
32
+ object = YARD::CodeObjects::MethodObject.new(namespace, attr_name, scope) do |o|
33
+ o.dynamic = true
34
+ o.aliases << "self_#{name}"
35
+ end
36
+ register(object)
37
+ key_name ||=
38
+ if object.docstring.has_tag?('key_name')
39
+ object.docstring.tag('key_name').text
40
+ else
41
+ 'key'
42
+ end
43
+ return_type ||=
44
+ if object.docstring.has_tag?('return')
45
+ object.docstring.tag('return').types.first
46
+ elsif is_map
47
+ 'Hash<Object,Object>'
48
+ else
49
+ 'Array<Object>'
50
+ end
51
+ if return_type =~ /^\w+\<(.*)\>$/
52
+ if is_map
53
+ key_type, value_type = $1.split(',')
54
+ else
55
+ value_type = $1
56
+ end
57
+ else
58
+ key_type = "Object"
59
+ value_type = "Object"
60
+ end
61
+
62
+ object = YARD::CodeObjects::MethodObject.new(namespace, "all_#{name}", scope)
63
+ object.dynamic = true
64
+ register(object)
65
+ object.docstring.replace("The union, along the class hierarchy, of all the values stored in #{name}\n@return [Array<#{value_type}>]")
66
+
67
+ if is_map
68
+ object = YARD::CodeObjects::MethodObject.new(namespace, "find_#{name}", scope)
69
+ object.dynamic = true
70
+ register(object)
71
+ object.parameters << [key_name]
72
+ object.docstring.replace("
73
+ Looks for objects registered in #{name} under the given key, and returns the first one in the ancestor chain
74
+ (i.e. the one tha thas been registered in the most specialized class)
75
+
76
+ @return [#{value_type},nil] the found object, or nil if none is registered under that key")
77
+
78
+ object = YARD::CodeObjects::MethodObject.new(namespace, "has_#{name}?", scope)
79
+ object.dynamic = true
80
+ register(object)
81
+ object.parameters << [key_name]
82
+ object.docstring.replace("Returns true if an object is registered in #{name} anywhere in the class hierarchy\n@return [Boolean]")
83
+ object.signature = "def has_#{name}?(key)"
84
+
85
+ object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
86
+ object.dynamic = true
87
+ register(object)
88
+ object.parameters << [key_name, "nil"] << ["uniq", "true"]
89
+ object.docstring.replace("
90
+ @overload each_#{name}(#{key_name}, uniq = true)
91
+ Enumerates all objects registered in #{name} under the given key
92
+ @yield [element]
93
+ @yieldparam [#{value_type}] element
94
+ @overload each_#{name}(nil, uniq = true)
95
+ Enumerates all objects registered in #{name}
96
+ @yield [#{key_name}, element]
97
+ @yieldparam [#{key_type}] #{key_name}
98
+ @yieldparam [#{value_type}] element
99
+ ")
100
+ else
101
+ object = YARD::CodeObjects::MethodObject.new(namespace, "each_#{name}", scope)
102
+ object.dynamic = true
103
+ register(object)
104
+ object.docstring.replace("Enumerates all objects registered in #{name}\n@return []\n@yield [element]\n@yieldparam [#{value_type}] element")
105
+ end
106
+
107
+ if is_map
108
+ return key_type, value_type
109
+ else
110
+ return value_type
111
+ end
112
+ end
113
+ end
114
+ YARD::Tags::Library.define_tag("Key for inherited_attribute(_, :map => true)", :key_name)
115
+ end
116
+ end
117
+