proteus 0.9.0

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. data/COPYING +674 -0
  2. data/README +88 -0
  3. data/Rakefile +33 -0
  4. data/bin/pro +189 -0
  5. data/lib/ClassParser.rb +84 -0
  6. data/lib/ComponentClass.rb +51 -0
  7. data/lib/ComponentInstance.rb +76 -0
  8. data/lib/DefinitionHelper.rb +157 -0
  9. data/lib/DefinitionParser.rb +107 -0
  10. data/lib/Facade.rb +116 -0
  11. data/lib/FileHelper.rb +80 -0
  12. data/lib/InputParser.rb +241 -0
  13. data/lib/InstanceParser.rb +65 -0
  14. data/lib/InstanceProxy.rb +100 -0
  15. data/lib/PropertyHash.rb +64 -0
  16. data/lib/TemplateRenderer.rb +128 -0
  17. data/lib/exceptions.rb +50 -0
  18. data/test/spec/ClassParser_spec.rb +314 -0
  19. data/test/spec/ComponentClass_spec.rb +44 -0
  20. data/test/spec/ComponentInstance_spec.rb +50 -0
  21. data/test/spec/DefinitionHelper_spec.rb +134 -0
  22. data/test/spec/DefinitionParser_spec.rb +236 -0
  23. data/test/spec/Facade_spec.rb +44 -0
  24. data/test/spec/FileHelper_spec.rb +113 -0
  25. data/test/spec/InputParser_spec.rb +424 -0
  26. data/test/spec/InstanceParser_spec.rb +125 -0
  27. data/test/spec/TemplateRenderer_spec.rb +54 -0
  28. data/test/spec/lib/NS1/TestComponent10.def +4 -0
  29. data/test/spec/lib/NS1/TestComponent11.def +4 -0
  30. data/test/spec/lib/NS1/TestComponent4.def +4 -0
  31. data/test/spec/lib/NS1/TestComponent5.def +4 -0
  32. data/test/spec/lib/NS1/TestComponent8.def +4 -0
  33. data/test/spec/lib/NS1/TestComponent9.def +4 -0
  34. data/test/spec/lib/NS2/TestComponent6.def +4 -0
  35. data/test/spec/lib/TestComponent1.def +4 -0
  36. data/test/spec/lib/TestComponent3.def +4 -0
  37. data/test/spec/test_lib_dir1/File1.def +0 -0
  38. data/test/spec/test_lib_dir1/File3.def +0 -0
  39. data/test/spec/test_lib_dir1/NS1/File4.def +0 -0
  40. data/test/spec/test_lib_dir1/NS1/NS2/File5.def +0 -0
  41. data/test/spec/test_lib_dir2/File1.def +0 -0
  42. data/test/spec/test_lib_dir2/File2.def +0 -0
  43. metadata +113 -0
@@ -0,0 +1,64 @@
1
+ ################################################################################
2
+ # PropertyHash.rb
3
+ #
4
+ # Wraps the properties of an instance used in the InstanceProxy, rendering its
5
+ # values before returning them.
6
+ # -----------------------------------------------------------------------------
7
+ # (C) Copyright 2009 William Madden
8
+ #
9
+ # This file is part of Proteus.
10
+ #
11
+ # Proteus is free software: you can redistribute it and/or modify it under the
12
+ # terms of the GNU General Public License as published by the Free Software
13
+ # Foundation, either version 3 of the License, or (at your option) any later
14
+ # version.
15
+ #
16
+ # Proteus is distributed in the hope that it will be useful, but WITHOUT ANY
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
+ #
20
+ # You should have received a copy of the GNU General Public License along with
21
+ # Proteus. If not, see <http://www.gnu.org/licenses/>.
22
+ ################################################################################
23
+
24
+
25
+ module Proteus
26
+
27
+ #
28
+ # Wraps the properties of an instance used in the InstanceProxy, rendering its
29
+ # values before returning them.
30
+ #
31
+ class PropertyHash < Hash
32
+
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ # Constructor
36
+ #
37
+ #---------------------------------------------------------------------------
38
+
39
+ def initialize( properties, renderer )
40
+ super( properties )
41
+ @renderer = renderer
42
+ end
43
+
44
+ #---------------------------------------------------------------------------
45
+ #
46
+ # Methods
47
+ #
48
+ #---------------------------------------------------------------------------
49
+
50
+ public
51
+
52
+ #
53
+ # Overrides the default [] operator to render values before they're
54
+ # returned.
55
+ #
56
+ def []( val )
57
+ result = super[val]
58
+ return @renderer.render( result )
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
@@ -0,0 +1,128 @@
1
+ ################################################################################
2
+ # TemplateRenderer.rb
3
+ #
4
+ # Renders the document tree using component templates and ERB.
5
+ # -----------------------------------------------------------------------------
6
+ # (C) Copyright 2009 William Madden
7
+ #
8
+ # This file is part of Proteus.
9
+ #
10
+ # Proteus is free software: you can redistribute it and/or modify it under the
11
+ # terms of the GNU General Public License as published by the Free Software
12
+ # Foundation, either version 3 of the License, or (at your option) any later
13
+ # version.
14
+ #
15
+ # Proteus is distributed in the hope that it will be useful, but WITHOUT ANY
16
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License along with
20
+ # Proteus. If not, see <http://www.gnu.org/licenses/>.
21
+ ################################################################################
22
+
23
+ require 'erb'
24
+
25
+ require File.expand_path( File.join(File.dirname(__FILE__), 'ComponentInstance.rb') )
26
+ require File.expand_path( File.join(File.dirname(__FILE__), 'InstanceProxy.rb') )
27
+
28
+
29
+ module Proteus
30
+
31
+ #
32
+ # Renders a document tree.
33
+ #
34
+ class TemplateRenderer
35
+
36
+ TEMPLATE_PROPERTY = "template"
37
+
38
+ #---------------------------------------------------------------------------
39
+ #
40
+ # Methods
41
+ #
42
+ #---------------------------------------------------------------------------
43
+
44
+ public
45
+
46
+ #
47
+ # Renders a document tree.
48
+ #
49
+ def render( tree )
50
+
51
+ case
52
+ when tree.is_a?( ComponentInstance ):
53
+ return render_instance( tree )
54
+
55
+ when tree.is_a?( Array ):
56
+ return render_array( tree )
57
+
58
+ when tree.is_a?( Hash ):
59
+ return render_hash( tree )
60
+
61
+ when tree.nil?:
62
+ return ''
63
+
64
+ else
65
+ return render_scalar( tree )
66
+ end
67
+
68
+ end
69
+
70
+ private
71
+
72
+ #
73
+ # Renders a hash.
74
+ #
75
+ def render_hash( hash )
76
+
77
+ for pair in hash
78
+ hash[ pair[0] ] = render( pair[1] )
79
+ end
80
+
81
+ return hash.to_s
82
+
83
+ end
84
+
85
+ #
86
+ # Renders an array.
87
+ #
88
+ def render_array( array )
89
+
90
+ result = ''
91
+
92
+ array.each do |elem|
93
+ result += render( elem )
94
+ end
95
+
96
+ return result
97
+
98
+ end
99
+
100
+ #
101
+ # Renders a scalar.
102
+ #
103
+ def render_scalar( scalar )
104
+ return scalar.to_s
105
+ end
106
+
107
+ #
108
+ # Renders an instance.
109
+ #
110
+ def render_instance( instance )
111
+
112
+ result = ''
113
+ template = instance.final_properties[ TEMPLATE_PROPERTY ]
114
+
115
+ if template != nil
116
+ proxy = InstanceProxy.new( self, instance )
117
+
118
+ e = ERB.new( template )
119
+ result = e.result( proxy.instance_env() )
120
+ end
121
+
122
+ return result
123
+
124
+ end
125
+
126
+ end
127
+
128
+ end
@@ -0,0 +1,50 @@
1
+ ################################################################################
2
+ # Exceptions.rb
3
+ #
4
+ # Provides exception definitions.
5
+ # -----------------------------------------------------------------------------
6
+ # (C) Copyright 2009 William Madden
7
+ #
8
+ # This file is part of Proteus.
9
+ #
10
+ # Proteus is free software: you can redistribute it and/or modify it under the
11
+ # terms of the GNU General Public License as published by the Free Software
12
+ # Foundation, either version 3 of the License, or (at your option) any later
13
+ # version.
14
+ #
15
+ # Proteus is distributed in the hope that it will be useful, but WITHOUT ANY
16
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License along with
20
+ # Proteus. If not, see <http://www.gnu.org/licenses/>.
21
+ ################################################################################
22
+
23
+ module Proteus
24
+
25
+ module Exceptions
26
+
27
+ class DefinitionMalformed < Exception
28
+ end
29
+
30
+ class RenderError < Exception
31
+ end
32
+
33
+ class RecursiveDefinition < Exception
34
+ end
35
+
36
+ #
37
+ # Raised when a component identifier can't be properly parsed.
38
+ #
39
+ class InvalidComponentIdentifier < Exception
40
+ end
41
+
42
+ #
43
+ # Raised when the definition of a component can't be found.
44
+ #
45
+ class DefinitionUnavailable < Exception
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,314 @@
1
+ ################################################################################
2
+ # (C) Copyright 2009 William Madden
3
+ #
4
+ # This file is part of Proteus.
5
+ #
6
+ # Proteus is free software: you can redistribute it and/or modify it under the
7
+ # terms of the GNU General Public License as published by the Free Software
8
+ # Foundation, either version 3 of the License, or (at your option) any later
9
+ # version.
10
+ #
11
+ # Proteus is distributed in the hope that it will be useful, but WITHOUT ANY
12
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along with
16
+ # Proteus. If not, see <http://www.gnu.org/licenses/>.
17
+ ################################################################################
18
+
19
+ require File.expand_path( 'lib/ClassParser.rb' )
20
+
21
+ include Proteus
22
+
23
+
24
+ describe ClassParser do
25
+
26
+ #-----------------------------------------------------------------------------
27
+ #
28
+ # Input Constants
29
+ #
30
+ #-----------------------------------------------------------------------------
31
+
32
+ @@NIL = nil
33
+
34
+ @@SCALAR_1 = "some scalar"
35
+
36
+ @@LIST_1 = [ "a", "b", "c" ]
37
+
38
+ @@VALID_NAME = "SomeComponent"
39
+
40
+ @@VALID_PARENT = "ParentComponent"
41
+
42
+ @@LONG_HASH = {
43
+ "key1" => "value1",
44
+ "key2" => "value2"
45
+ }
46
+
47
+ @@HASH_MISSING_NAME = {
48
+ "" => {}
49
+ }
50
+
51
+ @@HASH_BAD_NAME = {
52
+ "this name is invalid" => {}
53
+ }
54
+
55
+ @@HASH_MISSING_PARENT = {
56
+ @@VALID_NAME + " < " => {}
57
+ }
58
+
59
+ @@HASH_BAD_PARENT = {
60
+ @@VALID_NAME + " < bad parent" => {}
61
+ }
62
+
63
+ @@HASH_OF_NIL = {
64
+ @@VALID_NAME => @@NIL
65
+ }
66
+
67
+ @@HASH_OF_SCALAR = {
68
+ @@VALID_NAME => @@SCALAR_1
69
+ }
70
+
71
+ @@HASH_OF_LIST = {
72
+ @@VALID_NAME => @@LIST_1
73
+ }
74
+
75
+ @@HASH_OF_HASH = {
76
+ @@VALID_NAME => {}
77
+ }
78
+
79
+ @@PROPERTIES = {
80
+ "property1" => "value1",
81
+ "property2" => "value2",
82
+ "property3" => "value3",
83
+ }
84
+
85
+ @@CHILDREN = [
86
+ "child1",
87
+ "child2",
88
+ "child3"
89
+ ]
90
+
91
+ @@PROPERTIES_WITH_CHILDREN = {
92
+ "property1" => "value1",
93
+ "property2" => "value2",
94
+ "property3" => "value3",
95
+ "children" => @@CHILDREN
96
+ }
97
+
98
+ @@HASH_OF_PROPS = {
99
+ @@VALID_NAME => @@PROPERTIES
100
+ }
101
+
102
+ @@HASH_WITH_PARENT = {
103
+ @@VALID_NAME + " < " + @@VALID_PARENT => {}
104
+ }
105
+
106
+ @@HASH_WITH_CHILDREN = {
107
+ @@VALID_NAME => @@PROPERTIES_WITH_CHILDREN
108
+ }
109
+
110
+ #-----------------------------------------------------------------------------
111
+ #
112
+ # Set up, tear down
113
+ #
114
+ #-----------------------------------------------------------------------------
115
+
116
+ #------------------------------
117
+ # before(:all)
118
+ #------------------------------
119
+
120
+ before(:all) do
121
+ @class_parser = ClassParser.new()
122
+ end
123
+
124
+ #------------------------------
125
+ # after(:all)
126
+ #------------------------------
127
+
128
+ after(:all) do
129
+ end
130
+
131
+ #-----------------------------------------------------------------------------
132
+ #
133
+ # Tests
134
+ #
135
+ #-----------------------------------------------------------------------------
136
+
137
+ # Only accept correctly formed definitions.
138
+ #
139
+ # Do not accept:
140
+ # nil
141
+ # scalar
142
+ # list
143
+ # empty name
144
+ # malformed name
145
+ # empty parent name
146
+ # malformed parent name
147
+ # hash of scalar
148
+ # hash of list
149
+ # hash longer than one element
150
+ #
151
+ # Accept:
152
+ # hash of nothing
153
+ # hash of hash
154
+ #
155
+
156
+ it "should reject nil" do
157
+ begin
158
+ @class_parser.parse_yaml( @@NIL )
159
+ rescue Exceptions::DefinitionMalformed
160
+ success = true
161
+ end
162
+
163
+ success.should == true
164
+ end
165
+
166
+
167
+ it "should reject scalar" do
168
+ begin
169
+ @class_parser.parse_yaml( @@SCALAR_1 )
170
+ rescue Exceptions::DefinitionMalformed
171
+ success = true
172
+ end
173
+
174
+ success.should == true
175
+ end
176
+
177
+
178
+ it "should reject list" do
179
+ begin
180
+ @class_parser.parse_yaml( @@LIST_1 )
181
+ rescue Exceptions::DefinitionMalformed
182
+ success = true
183
+ end
184
+
185
+ success.should == true
186
+ end
187
+
188
+
189
+ it "should reject hash longer than one element" do
190
+ begin
191
+ @class_parser.parse_yaml( @@LONG_HASH )
192
+ rescue Exceptions::DefinitionMalformed
193
+ success = true
194
+ end
195
+
196
+ success.should == true
197
+ end
198
+
199
+
200
+ it "should reject missing name" do
201
+ begin
202
+ @class_parser.parse_yaml( @@HASH_MISSING_NAME )
203
+ rescue Exceptions::DefinitionMalformed
204
+ success = true
205
+ end
206
+
207
+ success.should == true
208
+ end
209
+
210
+
211
+ it "should reject malformed name" do
212
+ begin
213
+ @class_parser.parse_yaml( @@HASH_BAD_NAME )
214
+ rescue Exceptions::DefinitionMalformed
215
+ success = true
216
+ end
217
+
218
+ success.should == true
219
+ end
220
+
221
+
222
+ it "should reject empty parent name" do
223
+ begin
224
+ @class_parser.parse_yaml( @@HASH_MISSING_PARENT )
225
+ rescue Exceptions::DefinitionMalformed
226
+ success = true
227
+ end
228
+
229
+ success.should == true
230
+ end
231
+
232
+
233
+ it "should reject malformed parent name" do
234
+ begin
235
+ @class_parser.parse_yaml( @@HASH_BAD_PARENT )
236
+ rescue Exceptions::DefinitionMalformed
237
+ success = true
238
+ end
239
+
240
+ success.should == true
241
+ end
242
+
243
+
244
+ it "should reject hash of scalar" do
245
+ begin
246
+ @class_parser.parse_yaml( @@HASH_OF_SCALAR )
247
+ rescue Exceptions::DefinitionMalformed
248
+ success = true
249
+ end
250
+
251
+ success.should == true
252
+ end
253
+
254
+
255
+ it "should reject hash of list" do
256
+ begin
257
+ @class_parser.parse_yaml( @@HASH_OF_LIST )
258
+ rescue Exceptions::DefinitionMalformed
259
+ success = true
260
+ end
261
+
262
+ success.should == true
263
+ end
264
+
265
+
266
+
267
+ it "should accept valid empty hash" do
268
+
269
+ result = @class_parser.parse_yaml( @@HASH_OF_NIL )
270
+
271
+ end
272
+
273
+
274
+ it "should accept a hash of a hash" do
275
+
276
+ result = @class_parser.parse_yaml( @@HASH_OF_HASH )
277
+
278
+ end
279
+
280
+
281
+ it "should parse names in the form 'Name < Parent'" do
282
+
283
+ result = @class_parser.parse_yaml( @@HASH_WITH_PARENT )
284
+
285
+ result.name.should == @@VALID_NAME
286
+ result.parent.should == @@VALID_PARENT
287
+
288
+ end
289
+
290
+
291
+ it "should interpret the inner hash as properties" do
292
+
293
+ result = @class_parser.parse_yaml( @@HASH_OF_PROPS )
294
+
295
+ result.properties.should == @@PROPERTIES
296
+
297
+ end
298
+
299
+ it "should interpret the 'children' property as children" do
300
+
301
+ result = @class_parser.parse_yaml( @@HASH_WITH_CHILDREN )
302
+
303
+ result.children.should == [
304
+ "child1",
305
+ "child2",
306
+ "child3"
307
+ ]
308
+ result.properties.should == @@PROPERTIES
309
+
310
+ end
311
+
312
+
313
+ end
314
+