metaruby 1.0.0.rc1

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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/History.txt +1 -0
  4. data/Manifest.txt +40 -0
  5. data/README.md +318 -0
  6. data/Rakefile +39 -0
  7. data/lib/metaruby/class.rb +120 -0
  8. data/lib/metaruby/dsls/doc.rb +78 -0
  9. data/lib/metaruby/dsls/find_through_method_missing.rb +76 -0
  10. data/lib/metaruby/dsls.rb +2 -0
  11. data/lib/metaruby/gui/exception_view.rb +124 -0
  12. data/lib/metaruby/gui/html/button.rb +65 -0
  13. data/lib/metaruby/gui/html/collection.rb +103 -0
  14. data/lib/metaruby/gui/html/exception_view.css +8 -0
  15. data/lib/metaruby/gui/html/jquery.min.js +154 -0
  16. data/lib/metaruby/gui/html/jquery.selectfilter.js +65 -0
  17. data/lib/metaruby/gui/html/jquery.tagcloud.min.js +8 -0
  18. data/lib/metaruby/gui/html/jquery.tinysort.min.js +8 -0
  19. data/lib/metaruby/gui/html/list.rhtml +24 -0
  20. data/lib/metaruby/gui/html/page.css +55 -0
  21. data/lib/metaruby/gui/html/page.rb +283 -0
  22. data/lib/metaruby/gui/html/page.rhtml +13 -0
  23. data/lib/metaruby/gui/html/page_body.rhtml +17 -0
  24. data/lib/metaruby/gui/html/rock-website.css +694 -0
  25. data/lib/metaruby/gui/html.rb +16 -0
  26. data/lib/metaruby/gui/model_browser.rb +262 -0
  27. data/lib/metaruby/gui/model_selector.rb +266 -0
  28. data/lib/metaruby/gui/rendering_manager.rb +112 -0
  29. data/lib/metaruby/gui/ruby_constants_item_model.rb +253 -0
  30. data/lib/metaruby/gui.rb +9 -0
  31. data/lib/metaruby/inherited_attribute.rb +482 -0
  32. data/lib/metaruby/module.rb +158 -0
  33. data/lib/metaruby/registration.rb +157 -0
  34. data/lib/metaruby/test.rb +79 -0
  35. data/lib/metaruby.rb +17 -0
  36. data/manifest.xml +12 -0
  37. data/test/suite.rb +15 -0
  38. data/test/test_attributes.rb +323 -0
  39. data/test/test_class.rb +68 -0
  40. data/test/test_dsls.rb +49 -0
  41. data/test/test_module.rb +105 -0
  42. data/test/test_registration.rb +182 -0
  43. metadata +160 -0
data/test/test_dsls.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'metaruby/test'
2
+ require 'metaruby/dsls/find_through_method_missing'
3
+
4
+ describe MetaRuby::DSLs do
5
+ include MetaRuby::SelfTest
6
+
7
+ describe "#find_through_method_missing" do
8
+ it "should call the corresponding find method when matching" do
9
+ obj = flexmock
10
+ obj.should_receive(:find_obj).with("test").once.and_return(found = flexmock)
11
+ assert_equal found, MetaRuby::DSLs.find_through_method_missing(obj, :test_obj, [], "obj")
12
+ end
13
+ it "should allow specifying the find method name" do
14
+ obj = flexmock
15
+ obj.should_receive(:find_obj).with("test").once.and_return(found = flexmock)
16
+ assert_equal found, MetaRuby::DSLs.find_through_method_missing(obj, :test_bla, [], "bla" => 'find_obj')
17
+ end
18
+ it "should raise NoMethodError if the requested object is not found" do
19
+ obj = flexmock
20
+ obj.should_receive(:find_obj).with("test").once.and_return(nil)
21
+ assert_raises(NoMethodError) do
22
+ MetaRuby::DSLs.find_through_method_missing(obj, :test_obj, [], "obj")
23
+ end
24
+ end
25
+ it "should raise ArgumentError if some arguments are given regardless of whether the object exists" do
26
+ obj = flexmock
27
+ obj.should_receive(:find_obj).never
28
+ assert_raises(ArgumentError) do
29
+ MetaRuby::DSLs.find_through_method_missing(obj, :test_obj, [10], "obj")
30
+ end
31
+ end
32
+ it "should ignore non-matching methods and return nil" do
33
+ obj = flexmock
34
+ assert !MetaRuby::DSLs.find_through_method_missing(obj, :test_bla, [10], "obj")
35
+ end
36
+ it "should raise if the missing method is one of the expected find methods" do
37
+ # NOTE: do not use flexmock here, as specifying 'never' on a call
38
+ # spec makes flexmock raise a NoMethodError !!!
39
+ called = false
40
+ obj = Class.new do
41
+ define_method(:find_obj) { |name| called = true }
42
+ end.new
43
+ assert_raises(NoMethodError) do
44
+ MetaRuby::DSLs.find_through_method_missing(obj, :find_obj, [], "obj")
45
+ end
46
+ assert !called
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,105 @@
1
+ require 'metaruby/test'
2
+
3
+ describe MetaRuby::ModelAsModule do
4
+ include MetaRuby::SelfTest
5
+
6
+ attr_reader :root_m
7
+ before do
8
+ @root_m = Module.new { extend MetaRuby::ModelAsModule }
9
+ end
10
+
11
+ describe "#provides" do
12
+ it "sets the supermodel to the provided model if it is root" do
13
+ root_m.root = true
14
+ submodel = Module.new { extend MetaRuby::ModelAsModule }
15
+ submodel.provides root_m
16
+ assert_equal root_m, submodel.supermodel
17
+ end
18
+ it "sets root_model to the provided model's supermodel if the provided model is not root itself" do
19
+ flexmock(root_m).should_receive(:supermodel).once.
20
+ and_return(root = flexmock)
21
+ submodel = Module.new { extend MetaRuby::ModelAsModule }
22
+ root.should_receive(:register_submodel).with(submodel).once
23
+ submodel.provides root_m
24
+ assert_equal root, submodel.supermodel
25
+ end
26
+ end
27
+
28
+ describe "Using modules as metamodel" do
29
+ it "should apply the Attribute module on sub-metamodels for modules" do
30
+ mod = Module.new { include MetaRuby::ModelAsModule }
31
+ sub = Module.new { include mod }
32
+ assert mod.respond_to?(:inherited_attribute)
33
+ assert sub.respond_to?(:inherited_attribute)
34
+ end
35
+ end
36
+
37
+ describe "#new_submodel" do
38
+ it "should mark the model as non-permanent" do
39
+ root = Module.new do
40
+ extend MetaRuby::ModelAsModule
41
+ self.root = true
42
+ end
43
+ sub = root.new_submodel
44
+ assert !sub.new_submodel.permanent_model?
45
+ end
46
+ end
47
+
48
+ describe "#create_and_register_submodel" do
49
+ attr_reader :definition_context, :base_m
50
+ before do
51
+ @definition_context = Module.new
52
+ @base_m = Module.new do
53
+ extend MetaRuby::ModelAsModule
54
+ def self.root?; true end
55
+ end
56
+ end
57
+
58
+ it "should set permanent_model to true if the enclosing module is a Ruby module that is accessible by name" do
59
+ flexmock(MetaRuby::Registration).should_receive(:accessible_by_name?).with(definition_context).and_return(true)
60
+ result = MetaRuby::ModelAsModule.create_and_register_submodel(definition_context, 'Test', base_m)
61
+ assert result.permanent_model?
62
+ end
63
+ it "should set permanent_model to false if the enclosing module is a Ruby module that is not accessible by name" do
64
+ flexmock(definition_context).should_receive(:accessible_by_name?).and_return(false)
65
+ result = MetaRuby::ModelAsModule.create_and_register_submodel(definition_context, 'Test', base_m)
66
+ assert !result.permanent_model?
67
+ end
68
+ it "should set permanent_model to true if the enclosing module is permanent" do
69
+ flexmock(definition_context).should_receive(:permanent_model?).and_return(true)
70
+ result = MetaRuby::ModelAsModule.create_and_register_submodel(definition_context, 'Test', base_m)
71
+ assert result.permanent_model?
72
+ end
73
+ it "should set permanent_model to false if the enclosing module is non-permanent" do
74
+ flexmock(definition_context).should_receive(:permanent_model?).and_return(false)
75
+ result = MetaRuby::ModelAsModule.create_and_register_submodel(definition_context, 'Test', base_m)
76
+ assert !result.permanent_model?
77
+ end
78
+ end
79
+
80
+ describe "#clear_model" do
81
+ attr_reader :root_m, :model_m
82
+ before do
83
+ @root_m = Module.new do
84
+ extend MetaRuby::ModelAsModule
85
+ self.root = true
86
+ self.permanent_model = true
87
+ end
88
+ @model_m = root_m.new_submodel
89
+ model_m.permanent_model = true
90
+ end
91
+
92
+ it "deregisters the module regardless of the permanent_model flag" do
93
+ flexmock(root_m).should_receive(:deregister_submodels).with([model_m]).once
94
+ model_m.permanent_model = true
95
+ model_m.clear_model
96
+ end
97
+ it "clears its parent model set" do
98
+ flexmock(root_m).should_receive(:deregister_submodels).with([model_m]).once
99
+ model_m.permanent_model = true
100
+ model_m.clear_model
101
+ assert model_m.parent_models.empty?
102
+ end
103
+ end
104
+ end
105
+
@@ -0,0 +1,182 @@
1
+ require 'metaruby/test'
2
+
3
+ class Constant
4
+ extend MetaRuby::Registration
5
+ end
6
+ module Mod
7
+ class Constant
8
+ extend MetaRuby::Registration
9
+ end
10
+ end
11
+
12
+ describe MetaRuby::Registration do
13
+ include MetaRuby::SelfTest
14
+
15
+ class ModelStub
16
+ extend MetaRuby::Registration
17
+ end
18
+
19
+ def model_stub(parent_model = nil)
20
+ result = Class.new(ModelStub)
21
+ result.permanent_model = false
22
+ flexmock(result).should_receive(:supermodel).and_return(parent_model).by_default
23
+ if parent_model
24
+ parent_model.register_submodel(result)
25
+ end
26
+ result
27
+ end
28
+
29
+ describe "#register_submodel" do
30
+ attr_reader :base_model
31
+ before do
32
+ @base_model = model_stub
33
+ end
34
+
35
+ it "registers the model on the receiver" do
36
+ sub_model = Class.new(ModelStub)
37
+ base_model.register_submodel(sub_model)
38
+ assert(base_model.each_submodel.find { |m| m == sub_model })
39
+ end
40
+ it "registers the model on the receiver's parent model" do
41
+ parent_model = Class.new(ModelStub)
42
+ sub_model = Class.new(ModelStub)
43
+ flexmock(base_model).should_receive(:supermodel).and_return(parent_model)
44
+ flexmock(parent_model).should_receive(:register_submodel).with(sub_model).once
45
+ base_model.register_submodel(sub_model)
46
+ end
47
+ end
48
+
49
+ describe "#deregister_submodel" do
50
+ attr_reader :base_model, :sub_model
51
+ before do
52
+ @base_model = model_stub
53
+ @sub_model = model_stub(base_model)
54
+ end
55
+
56
+ it "deregisters the models on the receiver" do
57
+ flexmock(base_model).should_receive(:supermodel).and_return(nil).once
58
+ base_model.deregister_submodels([sub_model])
59
+ assert(base_model.each_submodel.to_a.empty?)
60
+ end
61
+ it "deregisters the models on the receiver's parent model" do
62
+ parent_model = flexmock
63
+ flexmock(base_model).should_receive(:supermodel).and_return(parent_model)
64
+ flexmock(parent_model).should_receive(:deregister_submodels).with([sub_model]).once
65
+ base_model.deregister_submodels([sub_model])
66
+ end
67
+ it "always calls the parent model's deregister method" do
68
+ parent_model = flexmock
69
+ flexmock(base_model).should_receive(:supermodel).and_return(parent_model)
70
+ flexmock(base_model).should_receive(:deregister_submodels).with([sub_model]).pass_thru
71
+ flexmock(parent_model).should_receive(:deregister_submodels).with([sub_model]).once
72
+ base_model.deregister_submodels([sub_model])
73
+ end
74
+ it "returns true if a model got deregistered" do
75
+ flexmock(base_model).should_receive(:supermodel).and_return(nil).once
76
+ assert base_model.deregister_submodels([sub_model])
77
+ end
78
+ it "returns false if no models got deregistered" do
79
+ assert !base_model.deregister_submodels([flexmock])
80
+ end
81
+ end
82
+
83
+ describe "#clear_models" do
84
+ attr_reader :base_model, :sub_model
85
+ before do
86
+ @base_model = model_stub
87
+ @sub_model = model_stub(base_model)
88
+ end
89
+ it "deregisters the non-permanent models, and calls #clear_submodels on them" do
90
+ base_model.should_receive(:deregister_submodels).with([sub_model]).once.pass_thru
91
+ sub_model.should_receive(:clear_submodels).once
92
+ base_model.clear_submodels
93
+ end
94
+ it "does not deregister the permanent models, but still calls #clear_submodels on them" do
95
+ base_model.should_receive(:deregister_submodels).with([]).never
96
+ sub_model.should_receive(:permanent_model?).and_return(true).once
97
+ sub_model.should_receive(:clear_submodels).once
98
+ base_model.clear_submodels
99
+ end
100
+ it "calls #clear_submodels on non-permanent submodels" do
101
+ flexmock(sub_model).should_receive(:permanent_model?).and_return(false).once
102
+ flexmock(sub_model).should_receive(:clear_submodels).once
103
+ base_model.clear_submodels
104
+ end
105
+ it "calls #clear_submodels on permanent submodels" do
106
+ flexmock(sub_model).should_receive(:permanent_model?).and_return(true).once
107
+ flexmock(sub_model).should_receive(:clear_submodels).once
108
+ # Create another submodel so that there is something to clear
109
+ model_stub(base_model)
110
+ base_model.clear_submodels
111
+ end
112
+ it "does not deregister the permanent models" do
113
+ flexmock(sub_model).should_receive(:permanent_model?).and_return(true).once
114
+ flexmock(base_model).should_receive(:deregister_submodels).with([]).never
115
+ base_model.clear_submodels
116
+ end
117
+ it "should deregister before it clears" do
118
+ flexmock(sub_model).should_receive(:permanent_model?).and_return(false).once
119
+ flexmock(base_model).should_receive(:deregister_submodels).once.ordered.pass_thru
120
+ flexmock(sub_model).should_receive(:clear_submodels).once.ordered
121
+ base_model.clear_submodels
122
+ end
123
+ end
124
+
125
+ describe "#accessible_by_name?" do
126
+ it "should be true for toplevel classes / modules" do
127
+ assert Constant.accessible_by_name?
128
+ end
129
+
130
+ it "should be true for classes / modules defined in namespaces" do
131
+ assert Mod::Constant.accessible_by_name?
132
+ end
133
+
134
+ it "should be false for anonymous classes / modules" do
135
+ klass = Class.new { extend MetaRuby::Registration }
136
+ assert !klass.accessible_by_name?
137
+ end
138
+ end
139
+
140
+ describe "#clear_model" do
141
+ attr_reader :obj, :supermodel
142
+ before do
143
+ @obj = Class.new do
144
+ extend MetaRuby::Registration
145
+ end
146
+ @supermodel = flexmock
147
+ supermodel.should_receive(:deregister_submodels).by_default
148
+ flexmock(obj).should_receive(:supermodel).and_return(supermodel)
149
+ end
150
+
151
+ it "should deregister itself from its parent models if it is non-permanent and has supermodels" do
152
+ supermodel.should_receive(:deregister_submodels).once.with([obj])
153
+ obj.permanent_model = false
154
+ obj.clear_model
155
+ end
156
+
157
+ it "should deregister itself from the constant hierarchy if non-permanent" do
158
+ obj.permanent_model = false
159
+ flexmock(MetaRuby::Registration).should_receive(:accessible_by_name?).once.with(obj).and_return(true)
160
+ flexmock(MetaRuby::Registration).should_receive(:deregister_constant).once.with(obj)
161
+ obj.clear_model
162
+ end
163
+
164
+ it "should not touch the receiver's registration if permanent" do
165
+ obj.permanent_model = true
166
+ flexmock(MetaRuby::Registration).should_receive(:deregister_constant).never
167
+ supermodel.should_receive(:deregister_submodels).never
168
+ obj.clear_model
169
+ end
170
+ end
171
+
172
+ describe "#deregister_constant" do
173
+ it "should deregister the object on the enclosing context" do
174
+ obj = flexmock(:basename => "Name", :spacename => "Test")
175
+ context = flexmock
176
+ flexmock(MetaRuby::Registration).should_receive(:constant).with("::Test").and_return(context)
177
+ context.should_receive(:remove_const).with('Name').once
178
+ MetaRuby::Registration.deregister_constant(obj)
179
+ end
180
+ end
181
+ end
182
+
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: metaruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.rc1
5
+ platform: ruby
6
+ authors:
7
+ - Sylvain Joyeux
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: utilrb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: hoe-yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hoe
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.13'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.13'
69
+ description: |-
70
+ This page will describe the various functionality that metaruby provides to help
71
+ modelling in Ruby.
72
+
73
+ This page will reuse one of the most overused example of modelling: a car and
74
+ colors.
75
+
76
+ ## Models
77
+
78
+ Using MetaRuby, models can either be represented by Ruby classes or by Ruby
79
+ modules. You use the first one when you want to model something from which an
80
+ object can be created, in our example: a car. You use the second for things that
81
+ cannot be instanciated, but can be used as attributes of another object, in our
82
+ example: a color.
83
+ email:
84
+ - sylvain.joyeux@m4x.org
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files:
88
+ - History.txt
89
+ - Manifest.txt
90
+ - README.md
91
+ files:
92
+ - ".gemtest"
93
+ - History.txt
94
+ - Manifest.txt
95
+ - README.md
96
+ - Rakefile
97
+ - lib/metaruby.rb
98
+ - lib/metaruby/class.rb
99
+ - lib/metaruby/dsls.rb
100
+ - lib/metaruby/dsls/doc.rb
101
+ - lib/metaruby/dsls/find_through_method_missing.rb
102
+ - lib/metaruby/gui.rb
103
+ - lib/metaruby/gui/exception_view.rb
104
+ - lib/metaruby/gui/html.rb
105
+ - lib/metaruby/gui/html/button.rb
106
+ - lib/metaruby/gui/html/collection.rb
107
+ - lib/metaruby/gui/html/exception_view.css
108
+ - lib/metaruby/gui/html/jquery.min.js
109
+ - lib/metaruby/gui/html/jquery.selectfilter.js
110
+ - lib/metaruby/gui/html/jquery.tagcloud.min.js
111
+ - lib/metaruby/gui/html/jquery.tinysort.min.js
112
+ - lib/metaruby/gui/html/list.rhtml
113
+ - lib/metaruby/gui/html/page.css
114
+ - lib/metaruby/gui/html/page.rb
115
+ - lib/metaruby/gui/html/page.rhtml
116
+ - lib/metaruby/gui/html/page_body.rhtml
117
+ - lib/metaruby/gui/html/rock-website.css
118
+ - lib/metaruby/gui/model_browser.rb
119
+ - lib/metaruby/gui/model_selector.rb
120
+ - lib/metaruby/gui/rendering_manager.rb
121
+ - lib/metaruby/gui/ruby_constants_item_model.rb
122
+ - lib/metaruby/inherited_attribute.rb
123
+ - lib/metaruby/module.rb
124
+ - lib/metaruby/registration.rb
125
+ - lib/metaruby/test.rb
126
+ - manifest.xml
127
+ - test/suite.rb
128
+ - test/test_attributes.rb
129
+ - test/test_class.rb
130
+ - test/test_dsls.rb
131
+ - test/test_module.rb
132
+ - test/test_registration.rb
133
+ homepage: https://gitorious.org/rock-toolchain/metaruby
134
+ licenses:
135
+ - LGPLv3+
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options:
139
+ - "--title"
140
+ - TestMetaruby Documentation
141
+ - "--quiet"
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">"
152
+ - !ruby/object:Gem::Version
153
+ version: 1.3.1
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.2.2
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: Modelling using the Ruby language as a metamodel
160
+ test_files: []