dsl_maker 0.0.3 → 0.0.4

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: 4dcf7e27a270d732f50700ad02cc0e2df6410d31
4
- data.tar.gz: 67af6f9d5095417301601997d3f4244d6887a329
3
+ metadata.gz: ff32adb37883c0c6466af73eac18c78e0315cffd
4
+ data.tar.gz: ebaaa08053e1c7d1a3066c3a3ec18cebf685a10b
5
5
  SHA512:
6
- metadata.gz: c3c69f7f5890b5266ec5a00a6e2c7d3238f50839ee5f527887024d63b90d146c4959b11f69575753d77ba1f6f3add5f8bbb6957533d8960428c0cdcd0c7c92c5
7
- data.tar.gz: 3a78ff0dfce77a4c3e358400864110c068f102698a7aace6741315369f0956f80b55fb92431302ad8d262eb877fe48c955d08960c70dce0a6dac50c2b5d6a8c5
6
+ metadata.gz: 237aef00aa5afa13e8d5cd39a72ee339e43de1988426305f1af0183b15a242d971de0a3398bae3a5817f1a2cc9f96a8c64fb36888b6617571b5f7c656757c8f6
7
+ data.tar.gz: 3274e9f900246bac32bc9dbec107e2120544d8241a4109857b79ae4a2d33ec147dd69a832d00392a351a95af015f4f3756110641a6855e3ebe2f98b5c3d05247
data/Changes CHANGED
@@ -1,5 +1,11 @@
1
1
  Revision history for DSL::Maker (ordered by revision number).
2
2
 
3
+ 0.0.4 Jul 29 2015
4
+ - Added add_helper() to allow the user to define new helper methods for use
5
+ within the DSL.
6
+ - Added missing documentation in README for new features in 0.0.3
7
+ - Added TODO list in documentation
8
+
3
9
  0.0.3 Jul 28 2015
4
10
  - Added entrypoint() that returns the DSL implementing an entrypoint
5
11
  - Several refactorings to improve maintainability:
data/README.md CHANGED
@@ -9,7 +9,6 @@
9
9
  [![Code Coverage](https://img.shields.io/codecov/c/github/robkinyon/ruby-dsl-maker.svg)](https://codecov.io/github/robkinyon/ruby-dsl-maker)
10
10
  [![Inline docs](http://inch-ci.org/github/robkinyon/ruby-dsl-maker.png)](http://inch-ci.org/github/robkinyon/ruby-dsl-maker)
11
11
 
12
-
13
12
  Writing single-level Ruby-like DSLs is really easy. Ruby practically builds them
14
13
  for you with a little meta-programming. [Docile](https://github.com/ms-ati/docile)
15
14
  makes it ridiculously easy and there are nearly a dozen other modules to do so.
@@ -55,9 +54,6 @@ class PizzaBuilder
55
54
  Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
56
55
  end
57
56
  end
58
-
59
- PizzaBuilder.new.cheese.pepperoni.sauce(:extra).build
60
- #=> #<Pizza:0x00001009dc398 @cheese=true, @pepperoni=true, @bacon=false, @sauce=:extra>
61
57
  ```
62
58
 
63
59
  But, this doesn't actually implement the DSL. That is left for another snippet:
@@ -85,7 +81,14 @@ class PizzaBuilder < DSL::Maker
85
81
  end
86
82
  end
87
83
 
88
- pizza = PizzaBuilder.parse_dsl(dsl_block)
84
+ pizza = PizzaBuilder.parse_dsl("
85
+ pizza {
86
+ cheese yes
87
+ pepperoni Yes
88
+ bacon On
89
+ sauce 'extra'
90
+ }
91
+ ")
89
92
  ```
90
93
 
91
94
  Now, you accept the strings (possibly from `IO.read()`) and magically get the
@@ -132,7 +135,7 @@ john_smith = FamilyTree.parse_dsl("
132
135
  ")
133
136
  ```
134
137
 
135
- Refactor that a bit and we end up with:
138
+ Pretty easy. We can even refactor that a bit and end up with:
136
139
 
137
140
  ```ruby
138
141
  class FamilyTree < DSL::Maker
@@ -268,7 +271,7 @@ you get back an `Array` with everything in the right order.
268
271
 
269
272
  ### Class Methods
270
273
 
271
- DSL::Maker provides five class methods - three for constructing your DSL and two
274
+ DSL::Maker provides seven class methods - five for constructing your DSL and two
272
275
  for parsing your DSL.
273
276
 
274
277
  * `add_entrypoint(Symbol, Hash={}, Block)`
@@ -278,6 +281,13 @@ level of your DSL. `add_entrypoint()` will create the right class methods for
278
281
  Docile to use when `parse_dsl()` is called. It will also invoke `generate_dsl()`
279
282
  with the Hash you give it to create the parsing.
280
283
 
284
+ * `entrypoint(Symbol)`
285
+
286
+ This returns the DSL defined by a previous call to `add_entrypoint()`.
287
+
288
+ This is primarily useful if you want to take a DSL class and use it within another
289
+ DSL class.
290
+
281
291
  * `generate_dsl(Hash={}, Block)`
282
292
 
283
293
  This is used in defining your DSL to describe the innards - the guts that actually
@@ -290,14 +300,21 @@ This is normally called by `generate_dsl()` to actually construct the DSL elemen
290
300
  It is provided for you so that you can create recursive DSL definitions. Look at
291
301
  the tests in `spec/multi_level_spec.rb` for an example of this.
292
302
 
303
+ * `add_helper(Symbol, Block)`
304
+
305
+ This is used to create helper methods (similar to `default`, described below) that
306
+ are used within the DSL.
307
+
308
+ This creates global helpers that are available at every level of your DSLs.
309
+
293
310
  * `parse_dsl(String)` / `execute_dsl(&block)`
294
311
 
295
312
  You call this on your DSL class when you're ready to invoke your DSL. It will
296
- return whatever the block provided `add_entrypoint()` returns.
313
+ return whatever the block provided to `add_entrypoint()` returns.
297
314
 
298
315
  In the case of multiple DSL entrypoints (for example, a normal Chef recipe),
299
- these methods will return an array with all the return values in the order of
300
- invocation.
316
+ these methods will return an array with all the return values in the order they
317
+ were encountered.
301
318
 
302
319
  ### Coercions
303
320
 
@@ -313,18 +330,27 @@ You will be able to add your own coercions in a forthcoming version of DSL::Make
313
330
 
314
331
  There is one pre-defined helper.
315
332
 
316
- * `default(String, Array, Integer=0)`
333
+ * `default(String, Array, Integer=0)`
317
334
 
318
335
  This takes a method name and the args provided to the block. It then ensures that
319
336
  the method defaults to the value in the args at the optional third argument.
320
337
 
338
+ You can add additional helpers using `add_helper()` described above.
339
+
321
340
  ## Installation
322
341
 
323
342
  ``` bash
324
343
  $ gem install dsl_maker
325
344
  ```
326
345
 
346
+ ## TODO
347
+
348
+ * Add support for Arrays
349
+ * Add additional coercions (e.g., Number)
350
+ * Allow you to add your own coercions
351
+
327
352
  ## Links
353
+
328
354
  * [Source](https://github.com/robkinyon/ruby-dsl-maker)
329
355
  * [Documentation](http://rubydoc.info/gems/ruby-dsl-maker)
330
356
  * [Bug Tracker](https://github.com/robkinyon/ruby-dsl-maker/issues)
data/Rakefile CHANGED
@@ -1,9 +1,10 @@
1
1
  require 'rake/clean'
2
2
  require 'bundler/gem_tasks'
3
+ require 'rubygems/tasks'
3
4
  require 'rspec/core/rake_task'
4
5
 
5
6
  # This is used by the Yardoc stuff in docile's Rakefile. We're not there yet.
6
- #require File.expand_path('on_what', File.dirname(__FILE__))
7
+ require File.expand_path('on_what', File.dirname(__FILE__))
7
8
 
8
9
  # Default task for `rake` is to run rspec
9
10
  task :default => [:spec]
@@ -14,6 +15,10 @@ RSpec::Core::RakeTask.new
14
15
  # Configure `rake clobber` to delete all generated files
15
16
  CLOBBER.include('pkg', 'doc', 'coverage', '*.gem')
16
17
 
18
+ # Add the gem tasks:
19
+ # :build, :console, :install, :release
20
+ Gem::Tasks.new
21
+
17
22
  if !on_travis? && !on_jruby? && !on_1_8?
18
23
  require 'github/markup'
19
24
  require 'redcarpet'
data/dsl_maker.gemspec CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency 'rake', '~> 10'
26
26
  s.add_development_dependency 'rspec', '~> 3.0.0', '>= 3.0.0'
27
27
  s.add_development_dependency 'simplecov', '~> 0'
28
+ s.add_development_dependency 'rubygems-tasks', '~> 0'
28
29
 
29
30
  # To limit needed compatibility with versions of dependencies, only configure
30
31
  # yard doc generation when *not* on Travis, JRuby, or 1.8
@@ -1,6 +1,6 @@
1
1
  module DSL
2
2
  class Maker
3
3
  # The current version of this library
4
- VERSION = '0.0.3'
4
+ VERSION = '0.0.4'
5
5
  end
6
6
  end
data/lib/dsl/maker.rb CHANGED
@@ -253,4 +253,16 @@ class DSL::Maker
253
253
 
254
254
  return @entrypoints[name.to_sym]
255
255
  end
256
+
257
+ def self.add_helper(name, &block)
258
+ raise "Block required for add_helper" unless block_given?
259
+
260
+ if DSL::Maker::Base.new.respond_to? name.to_sym
261
+ raise "'#{name.to_s}' is already a helper"
262
+ end
263
+
264
+ DSL::Maker::Base.class_eval do
265
+ define_method(name.to_sym, &block)
266
+ end
267
+ end
256
268
  end
data/spec/error_spec.rb CHANGED
@@ -61,4 +61,29 @@ describe "DSL::Maker validation" do
61
61
  dsl_class.entrypoint(:x)
62
62
  }.to raise_error("'x' is not an entrypoint")
63
63
  end
64
+
65
+ it "rejects a helper without a block" do
66
+ dsl_class = Class.new(DSL::Maker)
67
+
68
+ expect {
69
+ dsl_class.add_helper(:x)
70
+ }.to raise_error('Block required for add_helper')
71
+ end
72
+
73
+ it "rejects the helper name default" do
74
+ dsl_class = Class.new(DSL::Maker)
75
+
76
+ expect {
77
+ dsl_class.add_helper(:default) {}
78
+ }.to raise_error("'default' is already a helper")
79
+ end
80
+
81
+ it "rejects a helper name already in use" do
82
+ dsl_class = Class.new(DSL::Maker)
83
+ dsl_class.add_helper(:x) {}
84
+
85
+ expect {
86
+ dsl_class.add_helper(:x) {}
87
+ }.to raise_error("'x' is already a helper")
88
+ end
64
89
  end
@@ -0,0 +1,63 @@
1
+ # This uses a DSL that also provides a set of useful helpers.
2
+ #
3
+ describe "A DSL with helpers" do
4
+ $Car = Struct.new(:maker, :wheel)
5
+ $Wheel = Struct.new(:maker, :size)
6
+
7
+ it "can add a helper that's useful" do
8
+ dsl_class = Class.new(DSL::Maker) do
9
+ add_entrypoint(:car, {
10
+ :maker => String,
11
+ }) do
12
+ $Car.new(maker)
13
+ end
14
+
15
+ add_helper(:transform) do |name|
16
+ name.upcase
17
+ end
18
+ end
19
+
20
+ car = dsl_class.parse_dsl("
21
+ car {
22
+ maker transform('Honda')
23
+ }
24
+ ")
25
+ expect(car).to be_instance_of($Car)
26
+ expect(car.maker).to eq('HONDA')
27
+ end
28
+
29
+ # TODO: There is a wart here. We cannot call add_helper() twice in our tests
30
+ # for the same name even in different specs. The specs should be able to reset
31
+ # the class, but I'm not sure how.
32
+ it "adds the helper to every level" do
33
+ dsl_class = Class.new(DSL::Maker) do
34
+ add_entrypoint(:car, {
35
+ :maker => String,
36
+ :wheel => generate_dsl({
37
+ :maker => String,
38
+ }) do
39
+ $Wheel.new(maker)
40
+ end
41
+ }) do
42
+ $Car.new(maker, wheel)
43
+ end
44
+
45
+ add_helper(:transform2) do |name|
46
+ name.upcase
47
+ end
48
+ end
49
+
50
+ car = dsl_class.parse_dsl("
51
+ car {
52
+ maker 'Honda'
53
+ wheel {
54
+ maker transform2('goodyear')
55
+ }
56
+ }
57
+ ")
58
+ expect(car).to be_instance_of($Car)
59
+ expect(car.maker).to eq('Honda')
60
+ expect(car.wheel).to be_instance_of($Wheel)
61
+ expect(car.wheel.maker).to eq('GOODYEAR')
62
+ end
63
+ end
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.3
4
+ version: 0.0.4
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-29 00:00:00.000000000 Z
11
+ date: 2015-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
@@ -78,6 +78,20 @@ dependencies:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
80
  version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rubygems-tasks
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
81
95
  - !ruby/object:Gem::Dependency
82
96
  name: yard
83
97
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +157,7 @@ files:
143
157
  - spec/args_spec.rb
144
158
  - spec/class_as_subdsl_spec.rb
145
159
  - spec/error_spec.rb
160
+ - spec/helper_spec.rb
146
161
  - spec/multi_level_spec.rb
147
162
  - spec/multiple_invocation_spec.rb
148
163
  - spec/single_level_spec.rb