proteus 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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
+