dsl_maker 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a86f0dfab03af6d1b25904ef7c7dd0ef4090b33
4
- data.tar.gz: f63cd7dd2beaa1850851dba11a42d19ac67300a0
3
+ metadata.gz: 4dcf7e27a270d732f50700ad02cc0e2df6410d31
4
+ data.tar.gz: 67af6f9d5095417301601997d3f4244d6887a329
5
5
  SHA512:
6
- metadata.gz: bb2d7b7e998e65c35b595904fe49fb0b42c549d8796d303a5ac9b5faa366f7b6fb12e4ba3a74fef8517c961eb5a9086b44fde8a1080481a4028e2eb6a9deeffb
7
- data.tar.gz: 8a9aafadbc5c3c4a99e071609e49abf2b95f115b8106431e272500b96fad7afa26e913bd465fc762ff5525b1718dec33edcf1c8e83283c89cdf84a3cca43429a
6
+ metadata.gz: c3c69f7f5890b5266ec5a00a6e2c7d3238f50839ee5f527887024d63b90d146c4959b11f69575753d77ba1f6f3add5f8bbb6957533d8960428c0cdcd0c7c92c5
7
+ data.tar.gz: 3a78ff0dfce77a4c3e358400864110c068f102698a7aace6741315369f0956f80b55fb92431302ad8d262eb877fe48c955d08960c70dce0a6dac50c2b5d6a8c5
data/Changes CHANGED
@@ -1,9 +1,15 @@
1
1
  Revision history for DSL::Maker (ordered by revision number).
2
2
 
3
+ 0.0.3 Jul 28 2015
4
+ - Added entrypoint() that returns the DSL implementing an entrypoint
5
+ - Several refactorings to improve maintainability:
6
+ - DSL::Maker::Boolean is now a mixin, not a base class
7
+ - DSL::Maker::Base is now the base class for all the DSL classes
8
+
3
9
  0.0.2 Jul 22 2015
4
10
  - Allow add_entrypoint() to take a DSL class instead of args
5
11
  - Added execute_dsl() that takes a block
6
- - Several refactorings to improve maintainability
12
+ - Several refactorings to improve maintainability:
7
13
  - Recursive DSLs are now simpler to define and maintain
8
14
 
9
15
  0.0.1 Jul 21 2015
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ task :default => [:spec]
12
12
  RSpec::Core::RakeTask.new
13
13
 
14
14
  # Configure `rake clobber` to delete all generated files
15
- CLOBBER.include('pkg', 'doc', 'coverage')
15
+ CLOBBER.include('pkg', 'doc', 'coverage', '*.gem')
16
16
 
17
17
  if !on_travis? && !on_jruby? && !on_1_8?
18
18
  require 'github/markup'
@@ -1,6 +1,6 @@
1
1
  module DSL
2
2
  class Maker
3
3
  # The current version of this library
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
6
6
  end
data/lib/dsl/maker.rb CHANGED
@@ -4,15 +4,8 @@ require 'docile'
4
4
 
5
5
  # This is the base class we provide.
6
6
  class DSL::Maker
7
- # This is a useful class that contains all the Boolean handling we have.
8
- class Boolean
9
- {
10
- :yes => true, :no => false,
11
- :on => true, :off => false,
12
- }.each do |name, result|
13
- define_method(name) { result }
14
- end
15
-
7
+ # This is the base class for all DSL-parsing classes.
8
+ class Base
16
9
  # 21 character method names are obscene. Make it easier to read.
17
10
  alias :___set :instance_variable_set
18
11
 
@@ -34,18 +27,26 @@ class DSL::Maker
34
27
  return
35
28
  end
36
29
  end
37
- Yes = On = True = true
38
- No = Off = False = false
39
- $to_bool = lambda do |value|
40
- if value
41
- return false if %w(no off false nil).include? value.to_s.downcase
30
+
31
+ # This is a useful module that contains all the Boolean handling we need.
32
+ module Boolean
33
+ {
34
+ :yes => true, :no => false,
35
+ :on => true, :off => false,
36
+ }.each do |name, result|
37
+ define_method(name) { result }
42
38
  end
43
- # The bang-bang boolean-izes the value. We want this to be lossy.
44
- !!value
45
- end
46
39
 
47
- # TODO: Is this safe if the invoker doesn't use parse_dsl()?
48
- @@accumulator = []
40
+ def self.coerce(value)
41
+ if value
42
+ return false if %w(no off false nil).include? value.to_s.downcase
43
+ end
44
+ # The bang-bang boolean-izes the value. We want this to be lossy.
45
+ !!value
46
+ end
47
+ end
48
+ Yes = On = True = true
49
+ No = Off = False = false
49
50
 
50
51
  # Parse the DSL provided in the parameter.
51
52
  #
@@ -56,14 +57,14 @@ class DSL::Maker
56
57
  #
57
58
  # @return [Object] Whatever is returned by the block defined in this class.
58
59
  def self.parse_dsl(dsl)
59
- # add_entrypoint() will use @@accumulator to handle multiple entrypoints.
60
+ # add_entrypoint() will use @accumulator to handle multiple entrypoints.
60
61
  # Reset it here so that we're only handling the values from this run.
61
- @@accumulator = []
62
+ @accumulator = []
62
63
  eval dsl, self.get_binding
63
- if @@accumulator.length <= 1
64
- return @@accumulator[0]
64
+ if @accumulator.length <= 1
65
+ return @accumulator[0]
65
66
  end
66
- return @@accumulator
67
+ return @accumulator
67
68
  end
68
69
 
69
70
  # Execute the DSL provided in the block.
@@ -75,14 +76,23 @@ class DSL::Maker
75
76
  #
76
77
  # @return [Object] Whatever is returned by &block
77
78
  def self.execute_dsl(&block)
78
- @@accumulator = []
79
+ @accumulator = []
79
80
  instance_eval(&block)
80
- if @@accumulator.length <= 1
81
- return @@accumulator[0]
81
+ if @accumulator.length <= 1
82
+ return @accumulator[0]
82
83
  end
83
- return @@accumulator
84
+ return @accumulator
84
85
  end
85
86
 
87
+ # Returns the binding as needed by parse_dsl() and execute_dsl()
88
+ #
89
+ # @return [Binding] The binding of the invoking class.
90
+ def self.get_binding
91
+ binding
92
+ end
93
+
94
+ # FIXME: This may have to be changed when the elements can be altered because
95
+ # it is global to the hierarchy. But, that may be desirable.
86
96
  @@dsl_elements = {
87
97
  String => ->(klass, name, type) {
88
98
  as_attr = '@' + name.to_s
@@ -93,11 +103,11 @@ class DSL::Maker
93
103
  end
94
104
  end
95
105
  },
96
- Boolean => ->(klass, name, type) {
106
+ DSL::Maker::Boolean => ->(klass, name, type) {
97
107
  as_attr = '@' + name.to_s
98
108
  klass.class_eval do
99
109
  define_method(name.to_sym) do |*args|
100
- ___set(as_attr, $to_bool.call(args[0])) unless args.empty?
110
+ ___set(as_attr, Boolean.coerce(args[0])) unless args.empty?
101
111
  # Ensure that the default nil returns as false.
102
112
  !!___get(as_attr)
103
113
  end
@@ -105,6 +115,10 @@ class DSL::Maker
105
115
  },
106
116
  }
107
117
 
118
+ $is_dsl = lambda do |proto|
119
+ proto.is_a?(Class) && proto.ancestors.include?(DSL::Maker::Base)
120
+ end
121
+
108
122
  # Add a single element of a DSL to a class representing a level in a DSL.
109
123
  #
110
124
  # Each of the types represents a coercion - a guarantee and check of the value
@@ -123,7 +137,7 @@ class DSL::Maker
123
137
  def self.build_dsl_element(klass, name, type)
124
138
  if @@dsl_elements.has_key?(type)
125
139
  @@dsl_elements[type].call(klass, name, type)
126
- elsif type.is_a?(Class) && type.ancestors.include?(Boolean)
140
+ elsif $is_dsl.call(type)
127
141
  as_attr = '@' + name.to_s
128
142
  klass.class_eval do
129
143
  define_method(name.to_sym) do |*args, &dsl_block|
@@ -163,7 +177,9 @@ class DSL::Maker
163
177
  # Inherit from the Boolean class to gain access to the useful methods
164
178
  # TODO: Convert DSL::Maker::Boolean into a Role
165
179
  # TODO: Create a DSL::Maker::Base class to inherit from
166
- dsl_class = Class.new(Boolean) do
180
+ dsl_class = Class.new(DSL::Maker::Base) do
181
+ include DSL::Maker::Boolean
182
+
167
183
  # This instance method exists because we cannot seem to inline its work
168
184
  # where we call it. Could it be a problem of incorrect binding?
169
185
  # It has to be defined here because it needs access to &defn_block
@@ -201,16 +217,13 @@ class DSL::Maker
201
217
  # TODO: Provide a default block that returns the datastructure as a HoH.
202
218
  raise "Block required for add_entrypoint" unless block_given?
203
219
 
204
- # Ensure that get_binding() exists in the child class. This is necessary to
205
- # provide parse_dsl() so that eval works as expected. We have to do it here
206
- # because this is the only place we know for certain will be called.
207
- unless self.respond_to? :get_binding
208
- define_singleton_method(:get_binding) { binding }
220
+ if self.respond_to?(name.to_sym)
221
+ raise "'#{name.to_s}' is already an entrypoint"
209
222
  end
210
223
 
211
224
  # FIXME: This is a wart. Really, we should be pulling out name, then
212
225
  # yielding to generate_dsl() in some fashion.
213
- if args.is_a?(Class) && args.ancestors.include?(Boolean)
226
+ if $is_dsl.call(args)
214
227
  dsl_class = args
215
228
  else
216
229
  dsl_class = generate_dsl(args, &defn_block)
@@ -220,10 +233,24 @@ class DSL::Maker
220
233
  obj = dsl_class.new
221
234
  Docile.dsl_eval(obj, &dsl_block) if dsl_block
222
235
  rv = obj.instance_exec(*args, &defn_block)
223
- @@accumulator.push(rv)
236
+ @accumulator.push(rv)
224
237
  return rv
225
238
  end
226
239
 
227
- return dsl_class
240
+ @entrypoints ||= {}
241
+ return @entrypoints[name.to_sym] = dsl_class
242
+ end
243
+
244
+ # This returns the DSL corresponding to the entrypoint's name.
245
+ #
246
+ # @param name [String] the name of the entrypoint
247
+ #
248
+ # @return [Class] The class that implements this name's DSL definition.
249
+ def self.entrypoint(name)
250
+ unless self.respond_to?(name.to_sym)
251
+ raise "'#{name.to_s}' is not an entrypoint"
252
+ end
253
+
254
+ return @entrypoints[name.to_sym]
228
255
  end
229
256
  end
data/spec/args_spec.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # This will use a DSL that defines fruit
2
2
 
3
3
  describe "A DSL with argument handling describing fruit" do
4
- Color = Struct.new(:name)
5
- Fruit = Struct.new(:name, :color)
4
+ $Color = Struct.new(:name)
5
+ $Fruit = Struct.new(:name, :color)
6
6
 
7
7
  describe "with one argument in add_entrypoint" do
8
8
  dsl_class = Class.new(DSL::Maker) do
@@ -10,7 +10,7 @@ describe "A DSL with argument handling describing fruit" do
10
10
  :name => String,
11
11
  }) do |*args|
12
12
  default(:name, args, 0)
13
- Fruit.new(name, nil)
13
+ $Fruit.new(name, nil)
14
14
  end
15
15
  end
16
16
 
@@ -18,7 +18,7 @@ describe "A DSL with argument handling describing fruit" do
18
18
  fruit = dsl_class.parse_dsl("
19
19
  fruit
20
20
  ")
21
- expect(fruit).to be_instance_of(Fruit)
21
+ expect(fruit).to be_instance_of($Fruit)
22
22
  expect(fruit.name).to be_nil
23
23
  end
24
24
 
@@ -26,7 +26,7 @@ describe "A DSL with argument handling describing fruit" do
26
26
  fruit = dsl_class.parse_dsl("
27
27
  fruit { name 'banana' }
28
28
  ")
29
- expect(fruit).to be_instance_of(Fruit)
29
+ expect(fruit).to be_instance_of($Fruit)
30
30
  expect(fruit.name).to eq('banana')
31
31
  end
32
32
 
@@ -34,7 +34,7 @@ describe "A DSL with argument handling describing fruit" do
34
34
  fruit = dsl_class.parse_dsl("
35
35
  fruit 'banana'
36
36
  ")
37
- expect(fruit).to be_instance_of(Fruit)
37
+ expect(fruit).to be_instance_of($Fruit)
38
38
  expect(fruit.name).to eq('banana')
39
39
  end
40
40
 
@@ -45,7 +45,7 @@ describe "A DSL with argument handling describing fruit" do
45
45
  name 'banana'
46
46
  end
47
47
  ")
48
- expect(fruit).to be_instance_of(Fruit)
48
+ expect(fruit).to be_instance_of($Fruit)
49
49
  expect(fruit.name).to eq('banana')
50
50
  end
51
51
  end
@@ -59,7 +59,7 @@ describe "A DSL with argument handling describing fruit" do
59
59
  default('name', args)
60
60
  default('color', args, 1)
61
61
 
62
- Fruit.new(name, color)
62
+ $Fruit.new(name, color)
63
63
  end
64
64
  end
65
65
 
@@ -67,7 +67,7 @@ describe "A DSL with argument handling describing fruit" do
67
67
  fruit = dsl_class.parse_dsl("
68
68
  fruit
69
69
  ")
70
- expect(fruit).to be_instance_of(Fruit)
70
+ expect(fruit).to be_instance_of($Fruit)
71
71
  expect(fruit.name).to be_nil
72
72
  expect(fruit.color).to be_nil
73
73
  end
@@ -79,7 +79,7 @@ describe "A DSL with argument handling describing fruit" do
79
79
  color 'yellow'
80
80
  }
81
81
  ")
82
- expect(fruit).to be_instance_of(Fruit)
82
+ expect(fruit).to be_instance_of($Fruit)
83
83
  expect(fruit.name).to eq('banana')
84
84
  expect(fruit.color).to eq('yellow')
85
85
 
@@ -89,7 +89,7 @@ describe "A DSL with argument handling describing fruit" do
89
89
  color 'green'
90
90
  end
91
91
  ")
92
- expect(fruit).to be_instance_of(Fruit)
92
+ expect(fruit).to be_instance_of($Fruit)
93
93
  expect(fruit.name).to eq('plantain')
94
94
  expect(fruit.color).to eq('green')
95
95
  end
@@ -98,7 +98,7 @@ describe "A DSL with argument handling describing fruit" do
98
98
  fruit = dsl_class.parse_dsl("
99
99
  fruit 'banana', 'yellow'
100
100
  ")
101
- expect(fruit).to be_instance_of(Fruit)
101
+ expect(fruit).to be_instance_of($Fruit)
102
102
  expect(fruit.name).to eq('banana')
103
103
  expect(fruit.color).to eq('yellow')
104
104
  end
@@ -112,11 +112,11 @@ describe "A DSL with argument handling describing fruit" do
112
112
  :name => String,
113
113
  }) { |*args|
114
114
  default('name', args, 0)
115
- Color.new(name)
115
+ $Color.new(name)
116
116
  }
117
117
  }) do |*args|
118
118
  default('name', args, 0)
119
- Fruit.new(name, color)
119
+ $Fruit.new(name, color)
120
120
  end
121
121
  end
122
122
 
@@ -128,9 +128,9 @@ describe "A DSL with argument handling describing fruit" do
128
128
  }
129
129
  end
130
130
  ")
131
- expect(fruit).to be_instance_of(Fruit)
131
+ expect(fruit).to be_instance_of($Fruit)
132
132
  expect(fruit.name).to eq('banana')
133
- expect(fruit.color).to be_instance_of(Color)
133
+ expect(fruit.color).to be_instance_of($Color)
134
134
  expect(fruit.color.name).to eq('yellow')
135
135
  end
136
136
 
@@ -140,9 +140,9 @@ describe "A DSL with argument handling describing fruit" do
140
140
  color 'yellow'
141
141
  end
142
142
  ")
143
- expect(fruit).to be_instance_of(Fruit)
143
+ expect(fruit).to be_instance_of($Fruit)
144
144
  expect(fruit.name).to eq('banana')
145
- expect(fruit.color).to be_instance_of(Color)
145
+ expect(fruit.color).to be_instance_of($Color)
146
146
  expect(fruit.color.name).to eq('yellow')
147
147
  end
148
148
 
@@ -154,9 +154,9 @@ describe "A DSL with argument handling describing fruit" do
154
154
  end
155
155
  end
156
156
  ")
157
- expect(fruit).to be_instance_of(Fruit)
157
+ expect(fruit).to be_instance_of($Fruit)
158
158
  expect(fruit.name).to eq('banana')
159
- expect(fruit.color).to be_instance_of(Color)
159
+ expect(fruit.color).to be_instance_of($Color)
160
160
  expect(fruit.color.name).to eq('green')
161
161
  end
162
162
  end
@@ -0,0 +1,83 @@
1
+ # This is testing the ability to pass a class into generate_dsl and it
2
+ # does the right thing.
3
+
4
+ describe "Passing a class into generate_dsl" do
5
+ $Car = Struct.new(:maker, :wheel)
6
+ $Wheel = Struct.new(:maker, :size)
7
+
8
+ it "can do it" do
9
+ wheel_dsl = Class.new(DSL::Maker) do
10
+ add_entrypoint(:wheel, {
11
+ :size => String,
12
+ :maker => String,
13
+ }) do |*args|
14
+ default(:maker, args, 0)
15
+ $Wheel.new(maker, size)
16
+ end
17
+ end
18
+
19
+ dsl_class = Class.new(DSL::Maker) do
20
+ add_entrypoint(:car, {
21
+ :maker => String,
22
+ :wheel => wheel_dsl.entrypoint(:wheel),
23
+ }) do |*args|
24
+ default(:maker, args, 0)
25
+ $Car.new(maker, wheel)
26
+ end
27
+ end
28
+
29
+ car = dsl_class.execute_dsl do
30
+ car 'honda' do
31
+ wheel 'goodyear' do
32
+ size 26
33
+ end
34
+ end
35
+ end
36
+ expect(car).to be_instance_of($Car)
37
+ expect(car.maker).to eq('honda')
38
+ expect(car.wheel).to be_instance_of($Wheel)
39
+ expect(car.wheel.maker).to eq('goodyear')
40
+ expect(car.wheel.size).to eq('26')
41
+ end
42
+
43
+ # This ensures that if we create multiple entrypoints with the same name, they
44
+ # won't tramp on each other.
45
+ it "will not tramp on the entrypoints with the same name" do
46
+ wheel_dsl = Class.new(DSL::Maker) do
47
+ add_entrypoint(:wheel, {
48
+ :size => String,
49
+ :maker => String,
50
+ }) do |*args|
51
+ default(:maker, args, 0)
52
+ $Wheel.new(maker, size)
53
+ end
54
+ end
55
+
56
+ other_wheel_dsl = Class.new(DSL::Maker) do
57
+ add_entrypoint(:wheel, {}) { nil }
58
+ end
59
+
60
+ dsl_class = Class.new(DSL::Maker) do
61
+ add_entrypoint(:car, {
62
+ :maker => String,
63
+ :wheel => wheel_dsl.entrypoint(:wheel),
64
+ }) do |*args|
65
+ default(:maker, args, 0)
66
+ $Car.new(maker, wheel)
67
+ end
68
+ end
69
+
70
+ car = dsl_class.execute_dsl do
71
+ car 'honda' do
72
+ wheel 'goodyear' do
73
+ size 26
74
+ end
75
+ end
76
+ end
77
+ expect(car).to be_instance_of($Car)
78
+ expect(car.maker).to eq('honda')
79
+ expect(car.wheel).to be_instance_of($Wheel)
80
+ expect(car.wheel.maker).to eq('goodyear')
81
+ expect(car.wheel.size).to eq('26')
82
+ end
83
+ end
data/spec/error_spec.rb CHANGED
@@ -44,4 +44,21 @@ describe "DSL::Maker validation" do
44
44
  }.to raise_error("Illegal attribute name '#{name}'")
45
45
  end
46
46
  end
47
+
48
+ it "rejects re-using an entrypoint name in add_entrypoint()" do
49
+ dsl_class = Class.new(DSL::Maker) do
50
+ add_entrypoint(:x, {}) { nil }
51
+ end
52
+ expect {
53
+ dsl_class.add_entrypoint(:x, {}) { nil }
54
+ }.to raise_error("'x' is already an entrypoint")
55
+ end
56
+
57
+ it "rejects an entrypoint name that doesn't exist in entrypoint()" do
58
+ dsl_class = Class.new(DSL::Maker)
59
+
60
+ expect {
61
+ dsl_class.entrypoint(:x)
62
+ }.to raise_error("'x' is not an entrypoint")
63
+ end
47
64
  end
@@ -4,7 +4,7 @@
4
4
  # 1. Because we're creating classes on the fly, we must fully-qualify the Boolean
5
5
  # class name. If we created real classes, the context would be provided for us.
6
6
  describe 'A multi-level DSL making family-trees' do
7
- Person = Struct.new(:name, :child)
7
+ $Person = Struct.new(:name, :child)
8
8
 
9
9
  it "can handle a simple single-level parse of a two-level DSL" do
10
10
  dsl_class = Class.new(DSL::Maker) do
@@ -13,15 +13,15 @@ describe 'A multi-level DSL making family-trees' do
13
13
  :child => generate_dsl({
14
14
  :name => String,
15
15
  }) {
16
- Person.new(name)
16
+ $Person.new(name)
17
17
  },
18
18
  }) do
19
- Person.new(name, child)
19
+ $Person.new(name, child)
20
20
  end
21
21
  end
22
22
 
23
23
  person = dsl_class.parse_dsl('person { name "Tom" }')
24
- expect(person).to be_instance_of(Person)
24
+ expect(person).to be_instance_of($Person)
25
25
  expect(person.name).to eq('Tom')
26
26
  expect(person.child).to be_nil
27
27
  end
@@ -33,10 +33,10 @@ describe 'A multi-level DSL making family-trees' do
33
33
  :child => generate_dsl({
34
34
  :name => String,
35
35
  }) {
36
- Person.new(name, nil)
36
+ $Person.new(name, nil)
37
37
  },
38
38
  }) do
39
- Person.new(name, child)
39
+ $Person.new(name, child)
40
40
  end
41
41
  end
42
42
 
@@ -48,9 +48,9 @@ describe 'A multi-level DSL making family-trees' do
48
48
  }
49
49
  }
50
50
  ")
51
- expect(person).to be_instance_of(Person)
51
+ expect(person).to be_instance_of($Person)
52
52
  expect(person.name).to eq('Tom')
53
- expect(person.child).to be_instance_of(Person)
53
+ expect(person.child).to be_instance_of($Person)
54
54
  expect(person.child.name).to eq('Bill')
55
55
  end
56
56
 
@@ -63,13 +63,13 @@ describe 'A multi-level DSL making family-trees' do
63
63
  :child => generate_dsl({
64
64
  :name => String,
65
65
  }) {
66
- Person.new(name, nil)
66
+ $Person.new(name, nil)
67
67
  },
68
68
  }) {
69
- Person.new(name, child)
69
+ $Person.new(name, child)
70
70
  },
71
71
  }) do
72
- Person.new(name, child)
72
+ $Person.new(name, child)
73
73
  end
74
74
  end
75
75
 
@@ -84,11 +84,11 @@ describe 'A multi-level DSL making family-trees' do
84
84
  }
85
85
  }
86
86
  ")
87
- expect(person).to be_instance_of(Person)
87
+ expect(person).to be_instance_of($Person)
88
88
  expect(person.name).to eq('Tom')
89
- expect(person.child).to be_instance_of(Person)
89
+ expect(person.child).to be_instance_of($Person)
90
90
  expect(person.child.name).to eq('Bill')
91
- expect(person.child.child).to be_instance_of(Person)
91
+ expect(person.child.child).to be_instance_of($Person)
92
92
  expect(person.child.child.name).to eq('Judith')
93
93
  end
94
94
 
@@ -98,7 +98,7 @@ describe 'A multi-level DSL making family-trees' do
98
98
  person_dsl = add_entrypoint(:person, {
99
99
  :name => String,
100
100
  }) do
101
- Person.new(name, child)
101
+ $Person.new(name, child)
102
102
  end
103
103
  build_dsl_element(person_dsl, :child, person_dsl)
104
104
  end
@@ -145,7 +145,7 @@ describe 'A multi-level DSL making family-trees' do
145
145
  'Adam', 'Seth', 'Enos', 'Cainan', 'Mahalaleel', 'Jared',
146
146
  'Enoch', 'Methuselah', 'Lamech', 'Noah', 'Shem',
147
147
  ].each do |name|
148
- expect(person).to be_instance_of(Person)
148
+ expect(person).to be_instance_of($Person)
149
149
  expect(person.name).to eq(name)
150
150
  person = person.child
151
151
  end
@@ -1,15 +1,15 @@
1
- # This will use a DSL that defines Cars
1
+ # This will use a DSL that defines $Cars
2
2
 
3
3
  describe "A DSL describing cars used with multiple invocations" do
4
- Car = Struct.new(:maker)
5
- Truck = Struct.new(:maker)
4
+ $Car = Struct.new(:maker, :wheel)
5
+ $Truck = Struct.new(:maker, :wheel)
6
6
 
7
7
  it "returns two items in the right order" do
8
8
  dsl_class = Class.new(DSL::Maker) do
9
9
  add_entrypoint(:car, {
10
10
  :maker => String,
11
11
  }) do
12
- Car.new(maker)
12
+ $Car.new(maker)
13
13
  end
14
14
  end
15
15
 
@@ -19,9 +19,9 @@ describe "A DSL describing cars used with multiple invocations" do
19
19
  ")
20
20
  expect(cars).to be_instance_of(Array)
21
21
  expect(cars.length).to eq(2)
22
- expect(cars[0]).to be_instance_of(Car)
22
+ expect(cars[0]).to be_instance_of($Car)
23
23
  expect(cars[0].maker).to eq('Honda')
24
- expect(cars[1]).to be_instance_of(Car)
24
+ expect(cars[1]).to be_instance_of($Car)
25
25
  expect(cars[1].maker).to eq('Acura')
26
26
  end
27
27
 
@@ -30,12 +30,12 @@ describe "A DSL describing cars used with multiple invocations" do
30
30
  add_entrypoint(:car, {
31
31
  :maker => String,
32
32
  }) do
33
- Car.new(maker)
33
+ $Car.new(maker)
34
34
  end
35
35
  add_entrypoint(:truck, {
36
36
  :maker => String,
37
37
  }) do
38
- Truck.new(maker)
38
+ $Truck.new(maker)
39
39
  end
40
40
  end
41
41
 
@@ -46,11 +46,11 @@ describe "A DSL describing cars used with multiple invocations" do
46
46
  ")
47
47
  expect(vehicles).to be_instance_of(Array)
48
48
  expect(vehicles.length).to eq(3)
49
- expect(vehicles[0]).to be_instance_of(Truck)
49
+ expect(vehicles[0]).to be_instance_of($Truck)
50
50
  expect(vehicles[0].maker).to eq('Ford')
51
- expect(vehicles[1]).to be_instance_of(Car)
51
+ expect(vehicles[1]).to be_instance_of($Car)
52
52
  expect(vehicles[1].maker).to eq('Honda')
53
- expect(vehicles[2]).to be_instance_of(Truck)
53
+ expect(vehicles[2]).to be_instance_of($Truck)
54
54
  expect(vehicles[2].maker).to eq('Toyota')
55
55
  end
56
56
 
@@ -59,12 +59,12 @@ describe "A DSL describing cars used with multiple invocations" do
59
59
  add_entrypoint(:car, {
60
60
  :maker => String,
61
61
  }) do
62
- Car.new(maker)
62
+ $Car.new(maker)
63
63
  end
64
64
  add_entrypoint(:truck, {
65
65
  :maker => String,
66
66
  }) do
67
- Truck.new(maker)
67
+ $Truck.new(maker)
68
68
  end
69
69
  end
70
70
 
@@ -75,11 +75,11 @@ describe "A DSL describing cars used with multiple invocations" do
75
75
  end
76
76
  expect(vehicles).to be_instance_of(Array)
77
77
  expect(vehicles.length).to eq(3)
78
- expect(vehicles[0]).to be_instance_of(Truck)
78
+ expect(vehicles[0]).to be_instance_of($Truck)
79
79
  expect(vehicles[0].maker).to eq('Ford')
80
- expect(vehicles[1]).to be_instance_of(Car)
80
+ expect(vehicles[1]).to be_instance_of($Car)
81
81
  expect(vehicles[1].maker).to eq('Honda')
82
- expect(vehicles[2]).to be_instance_of(Truck)
82
+ expect(vehicles[2]).to be_instance_of($Truck)
83
83
  expect(vehicles[2].maker).to eq('Toyota')
84
84
  end
85
85
  end
@@ -12,10 +12,10 @@
12
12
  # class name. If we created real classes, the context would be provided for us.
13
13
  describe 'A single-level DSL for pizza' do
14
14
  $toppings = [:cheese, :pepperoni, :bacon, :sauce]
15
- Pizza = Struct.new(*$toppings)
15
+ $Pizza = Struct.new(*$toppings)
16
16
 
17
17
  def verify_pizza(pizza, values={})
18
- expect(pizza).to be_instance_of(Pizza)
18
+ expect(pizza).to be_instance_of($Pizza)
19
19
  $toppings.each do |topping|
20
20
  expect(pizza.send(topping)).to eq(values[topping])
21
21
  end
@@ -23,7 +23,7 @@ describe 'A single-level DSL for pizza' do
23
23
 
24
24
  it 'makes a blank pizza' do
25
25
  dsl_class = Class.new(DSL::Maker) do
26
- add_entrypoint(:pizza) { Pizza.new }
26
+ add_entrypoint(:pizza) { $Pizza.new }
27
27
  end
28
28
 
29
29
  pizza = dsl_class.parse_dsl('pizza')
@@ -36,7 +36,7 @@ describe 'A single-level DSL for pizza' do
36
36
  add_entrypoint(:pizza, {
37
37
  :cheese => DSL::Maker::Boolean,
38
38
  }) do
39
- Pizza.new(cheese, nil, nil, nil)
39
+ $Pizza.new(cheese, nil, nil, nil)
40
40
  end
41
41
  end
42
42
 
@@ -84,7 +84,7 @@ describe 'A single-level DSL for pizza' do
84
84
  add_entrypoint(:pizza, {
85
85
  :sauce => String,
86
86
  }) do
87
- Pizza.new(nil, nil, nil, sauce)
87
+ $Pizza.new(nil, nil, nil, sauce)
88
88
  end
89
89
  end
90
90
 
@@ -112,7 +112,7 @@ describe 'A single-level DSL for pizza' do
112
112
 
113
113
  # This is a wart - this block should be against toppings_dsl, not here.
114
114
  add_entrypoint(:pizza, toppings_dsl) do
115
- Pizza.new(cheese, pepperoni, bacon, sauce)
115
+ $Pizza.new(cheese, pepperoni, bacon, sauce)
116
116
  end
117
117
  end
118
118
 
@@ -143,7 +143,7 @@ describe 'A single-level DSL for pizza' do
143
143
 
144
144
  # This is a wart - this block should be against toppings_dsl, not here.
145
145
  add_entrypoint(:pizza, toppings_dsl) do
146
- Pizza.new(cheese, pepperoni, bacon, sauce)
146
+ $Pizza.new(cheese, pepperoni, bacon, sauce)
147
147
  end
148
148
  end
149
149
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dsl_maker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Kinyon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-22 00:00:00.000000000 Z
11
+ date: 2015-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
@@ -141,6 +141,7 @@ files:
141
141
  - lib/dsl/maker/version.rb
142
142
  - on_what.rb
143
143
  - spec/args_spec.rb
144
+ - spec/class_as_subdsl_spec.rb
144
145
  - spec/error_spec.rb
145
146
  - spec/multi_level_spec.rb
146
147
  - spec/multiple_invocation_spec.rb
@@ -171,3 +172,4 @@ signing_key:
171
172
  specification_version: 4
172
173
  summary: Easy multi-level DSLs
173
174
  test_files: []
175
+ has_rdoc: