iron-extensions 1.1.5 → 1.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 25e58b7dab82ea9ffef58c5d04ad58ba2d9777c9
4
+ data.tar.gz: 915e17967decb24e1526328b927f1e562357a01b
5
+ SHA512:
6
+ metadata.gz: 63b0cbb8e2702a7645818e80e26557221b919998152f2dd0a9724672b1fa94f3d8839f64e932b31d1784d162d88e3fa379dcb7648979930339c2d150b035ab6e
7
+ data.tar.gz: 916089267edf2c7735e357f2a9a0535202f6f50f1e4e0a7a2fcc6f1fc2c3f40cf4d1b5128de8e4d0909228ff3facbbe5fb87b7be19a859f1ac5ad3c4d20db004
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 1.2.0 / 2015-01-27
2
+
3
+ * BREAKING CHANGE: removed DslProxy/DslBuilder and the dsl_* accessor helpers and moved them into the iron-dsl gem
4
+ * BREAKING CHANGE: removed deprecated Array#rand and Array#rand! - use #shuffle instead
5
+ * Improved blank? to work on strings containing only whitespace
6
+ * Improved documentation & specs a bit
7
+
1
8
  == 1.1.5 / 2014-03-31
2
9
 
3
10
  * Fix bug in Enumerable#convert_to_hash where default values (eg hashes) weren't being duplicated
data/README.rdoc CHANGED
@@ -4,7 +4,9 @@ Written by Rob Morris @ Irongaze Consulting LLC (http://irongaze.com)
4
4
 
5
5
  == DESCRIPTION
6
6
 
7
- Helpful extensions to core Ruby classes, plus a little sugar for common patterns
7
+ Helpful extensions to core Ruby classes, plus a little sugar for common patterns. For users of
8
+ version 1.1.x and lower, please note that as of version 1.2.0 the DSL-specific extensions
9
+ have been moved to the iron-dsl gem!
8
10
 
9
11
  == ADDED EXTENSIONS
10
12
 
@@ -12,48 +14,23 @@ Helpful extensions to core Ruby classes, plus a little sugar for common patterns
12
14
 
13
15
  [1, 2, nil, '', 'count'].list_join # => '1, 2, count'
14
16
 
15
- * Class#dsl_accessor - helpful method for defining accessors on DSL builder-style classes
17
+ * Enumerable#convert_to_hash - convert an array or other enumerable to a hash using a block or constant
16
18
 
17
- class MyBuilder
18
- dsl_accessor :name
19
- end
20
- builder = MyBuilder.new
21
- builder.name 'ProjectX'
22
- builder.name # => 'ProjectX'
23
- DslProxy.exec(builder) do
24
- name 'Project Omega'
25
- end
26
- builder.name # => 'Project Omega'
27
-
28
- * Class#dsl_flag - same as above, but designed for boolean values
29
-
30
- class AnotherBuilder
31
- dsl_flag :awesome
32
- end
33
-
34
- builder = AnotherBuilder
35
- builder.awesome? # => false on uninitialized value
36
- builder.awesome! # => sets @awesome to true
37
- builder.awesome true # ditto, same style as dsl_accessor above
38
-
39
- * Enumerable#to_hash - convert an array or other enumerable to a hash using a block or constant
40
-
41
- [:frog, :pig].to_hash {|n| n.to_s.capitalize} # => {:frog => 'Frog', :pig => 'Pig'}
42
- [:frog, :pig].to_hash(nil) # => {:frog => nil, :pig => nil}
19
+ [:frog, :pig].convert_to_hash {|n| n.to_s.capitalize} # => {:frog => 'Frog', :pig => 'Pig'}
20
+ [:frog, :pig].convert_to_hash(nil) # => {:frog => nil, :pig => nil}
43
21
 
44
22
  * Enumerable#delete_unless - equivalent to delete_if but with inverted test
45
23
 
46
24
  [1,2,3,4,5].delete_unless(&:odd?) # => [1,3,5]
47
25
 
48
- * File.replace - atomic replacement of a file given a block to generate it
26
+ * File.safe_replace - atomic replacement of a file given a block to generate it
49
27
 
50
28
  # Defers deleting old file until block completes successfully (ie no exceptions), then
51
29
  # moves the new file into the old file's location
52
- File.replace('./config') do |file|
30
+ File.safe_replace('./config') do |file|
53
31
  file.write("PRODUCTION: true")
54
32
  end
55
33
 
56
- * Fixnum#blank? - always false
57
34
  * Fixnum#to_human_size - size to MB/GB/whatever, adapted from Rails
58
35
 
59
36
  123456.to_human_size # => "120.5 KB"
@@ -75,7 +52,7 @@ Helpful extensions to core Ruby classes, plus a little sugar for common patterns
75
52
 
76
53
  * Nil#blank? - always true
77
54
 
78
- * Numeric#to_display - pretty display of numbers with options for number of decimal places and inclusion of thousands separator
55
+ * Numeric#to_display - pretty display of numbers with options for number of decimal places and inclusion of thousands separator (US-only, sorry!)
79
56
 
80
57
  5000.to_display # => 5,000
81
58
  100.to_display(2) # => 100.00
@@ -97,8 +74,8 @@ Helpful extensions to core Ruby classes, plus a little sugar for common patterns
97
74
  * Regexp::IP_ADDRESS, Regexp::EMAIL_ADDRESS, Regexp::DOMAIN - commonly useful regexen
98
75
 
99
76
  * String#blank? - true if empty?
100
- * String#append / String#prepend - this should be in Ruby core
101
- * String#to_date - "better" date parser than Date.parse
77
+ * String#append / String#prepend - these should be in Ruby core
78
+ * String#to_date - "better" date parser than Date.parse (US-centric)
102
79
  * String#to_dashcase - perfect for permalinks!
103
80
  * String#smart_truncate - truncate honoring word boundaries
104
81
  * String#integer? - true when string represents an integer
@@ -110,22 +87,6 @@ Helpful extensions to core Ruby classes, plus a little sugar for common patterns
110
87
  * Symbol#blank? - always false
111
88
  * Symbol#to_dashcase - same as for String
112
89
 
113
- == ADDED CLASSES/MODULES
114
-
115
- * DslProxy - a cool and sexy way to make powerful DSLs (domain-specific languages) look easy - see the docs for details
116
-
117
- # DslProxy makes this code possible:
118
- @items = ['one', 'two']
119
- Console.out do
120
- # No explicit receiver for DSL method calls
121
- p 'Item List'
122
- hr
123
- indent do
124
- # Even nested, local variables are still available
125
- @items.each {|item| p item }
126
- end
127
- end
128
-
129
90
  == SYNOPSIS
130
91
 
131
92
  To use:
data/Version.txt CHANGED
@@ -1 +1 @@
1
- 1.1.5
1
+ 1.2.0
@@ -1,17 +1,5 @@
1
1
  class Array
2
2
 
3
- # DEPRECATED: as of Ruby 1.9, you should use Array#sample instead
4
- def rand(count = 1)
5
- warn("[DEPRECATION] Array#rand is deprecated - use Array#sample instead")
6
- shuffle[0...count]
7
- end
8
-
9
- # DEPRECATED: as of Ruby 1.9, you should use Array#sample instead
10
- def rand!(count = 1)
11
- warn("[DEPRECATION] Array#rand is deprecated - use Array#sample instead")
12
- self.replace rand(count)
13
- end
14
-
15
3
  # Join an array's values ignoring blank entries
16
4
  def list_join(sep = ', ')
17
5
  self.select{|e| !e.blank?}.join(sep)
@@ -16,4 +16,8 @@ module Enumerable
16
16
  delete_if {|*args| !block.call(*args)}
17
17
  end
18
18
 
19
+ def blank?
20
+ empty?
21
+ end
22
+
19
23
  end
@@ -21,8 +21,4 @@ class Fixnum
21
21
  nil
22
22
  end
23
23
 
24
- def blank?
25
- false
26
- end
27
-
28
24
  end
@@ -5,4 +5,8 @@ class Object
5
5
  enum.include?(self)
6
6
  end
7
7
 
8
+ def blank?
9
+ false
10
+ end
11
+
8
12
  end
@@ -4,7 +4,7 @@ class String
4
4
 
5
5
  # Provide helper for nil/"" blankness checker
6
6
  def blank?
7
- empty?
7
+ self.strip.empty?
8
8
  end
9
9
 
10
10
  def prepend(str)
@@ -1,10 +1,5 @@
1
1
  class Symbol
2
2
 
3
- # Provide helper for nil/"" blankness checker
4
- def blank?
5
- false
6
- end
7
-
8
3
  def to_dashcase
9
4
  self.to_s.to_dashcase
10
5
  end
@@ -31,4 +31,11 @@ describe Enumerable do
31
31
  h.should == {:c => 12}
32
32
  end
33
33
 
34
+ it 'should be appropriately empty' do
35
+ [].blank?.should be_true
36
+ {}.blank?.should be_true
37
+ [1].blank?.should be_false
38
+ {:a => 2}.blank?.should be_false
39
+ end
40
+
34
41
  end
@@ -7,4 +7,8 @@ describe Object do
7
7
  :b.in?([:a, :b, :c]).should == true
8
8
  end
9
9
 
10
+ it 'should not be blank' do
11
+ Object.new.should_not be_blank
12
+ end
13
+
10
14
  end
@@ -78,5 +78,11 @@ describe String do
78
78
  it 'should support natural ordering' do
79
79
  ['a0', 'a90', 'a10', 'a9'].sort_by {|a| a.natural_order}.should == ['a0', 'a9', 'a10', 'a90']
80
80
  end
81
+
82
+ it 'should be appropriately blank' do
83
+ [nil, '', ' ', "\t", "\n"].each do |test|
84
+ test.should be_blank
85
+ end
86
+ end
81
87
 
82
88
  end
metadata CHANGED
@@ -1,30 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
5
- prerelease:
4
+ version: 1.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rob Morris
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-03-31 00:00:00.000000000 Z
11
+ date: 2015-01-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rspec
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '2.6'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '2.6'
30
27
  description: Adds common extensions to core Ruby classes
@@ -34,10 +31,13 @@ executables: []
34
31
  extensions: []
35
32
  extra_rdoc_files: []
36
33
  files:
34
+ - ".rspec"
35
+ - History.txt
36
+ - LICENSE
37
+ - README.rdoc
38
+ - Version.txt
39
+ - lib/iron/extensions.rb
37
40
  - lib/iron/extensions/array.rb
38
- - lib/iron/extensions/class.rb
39
- - lib/iron/extensions/dsl_builder.rb
40
- - lib/iron/extensions/dsl_proxy.rb
41
41
  - lib/iron/extensions/enumerable.rb
42
42
  - lib/iron/extensions/file.rb
43
43
  - lib/iron/extensions/fixnum.rb
@@ -50,10 +50,7 @@ files:
50
50
  - lib/iron/extensions/regexp.rb
51
51
  - lib/iron/extensions/string.rb
52
52
  - lib/iron/extensions/symbol.rb
53
- - lib/iron/extensions.rb
54
53
  - spec/extensions/array_spec.rb
55
- - spec/extensions/dsl_builder_spec.rb
56
- - spec/extensions/dsl_proxy_spec.rb
57
54
  - spec/extensions/enumerable_spec.rb
58
55
  - spec/extensions/kernel_spec.rb
59
56
  - spec/extensions/numeric_spec.rb
@@ -61,34 +58,28 @@ files:
61
58
  - spec/extensions/string_spec.rb
62
59
  - spec/extensions/symbol_spec.rb
63
60
  - spec/spec_helper.rb
64
- - LICENSE
65
- - History.txt
66
- - Version.txt
67
- - README.rdoc
68
- - .rspec
69
61
  homepage: https://github.com/irongaze/iron-extensions
70
62
  licenses:
71
63
  - MIT
64
+ metadata: {}
72
65
  post_install_message:
73
66
  rdoc_options: []
74
67
  require_paths:
75
68
  - lib
76
69
  required_ruby_version: !ruby/object:Gem::Requirement
77
- none: false
78
70
  requirements:
79
- - - ! '>='
71
+ - - ">="
80
72
  - !ruby/object:Gem::Version
81
73
  version: 1.9.2
82
74
  required_rubygems_version: !ruby/object:Gem::Requirement
83
- none: false
84
75
  requirements:
85
- - - ! '>='
76
+ - - ">="
86
77
  - !ruby/object:Gem::Version
87
78
  version: '0'
88
79
  requirements: []
89
80
  rubyforge_project:
90
- rubygems_version: 1.8.24
81
+ rubygems_version: 2.4.3
91
82
  signing_key:
92
- specification_version: 3
83
+ specification_version: 4
93
84
  summary: Extensions to core classes
94
85
  test_files: []
@@ -1,46 +0,0 @@
1
- class Class
2
-
3
- # Provides a DSL-friendly way to set values. Similar to attr_accessor, but
4
- # supports setting values like so:
5
- #
6
- # class Widget
7
- # dsl_accessor :size
8
- # end
9
- # @w = Widget.new
10
- # @w.size = 5 # normal setter, same as...
11
- # @w.size 5 # note the lack of explicit = sign
12
- # puts @w.size # still get reader access
13
- #
14
- # Useful in DslProxy blocks:
15
- #
16
- # DslProxy.exec(Widget.new) do
17
- # size 10 # sets size to 10, as expected
18
- # size = 10 # fails, creates local variable 'size' instead of invoking Widget#size
19
- # end
20
- #
21
- def dsl_accessor(*keys)
22
- keys.each do |key|
23
- class_eval "def #{key}(val = :__UNDEFINED); @#{key} = val unless val == :__UNDEFINED; @#{key}; end"
24
- class_eval "def #{key}=(val); @#{key} = val; end"
25
- end
26
- end
27
-
28
- # Like #dsl_accessor, but adds imperative and query versions of the keys as well to set the
29
- # flag to true and to query the true-ness of the flag.
30
- #
31
- # class Widget
32
- # dsl_flag :heavy
33
- # end
34
- # @w = Widget.new
35
- # @w.heavy? # => false
36
- # @w.heavy! # now is true
37
- #
38
- def dsl_flag(*keys)
39
- dsl_accessor(*keys)
40
- keys.each do |key|
41
- class_eval "def #{key}!; @#{key} = true; end"
42
- class_eval "def #{key}?; @#{key} === true; end"
43
- end
44
- end
45
-
46
- end
@@ -1,14 +0,0 @@
1
- # Provides a base class for building DSL (domain specific language) builder
2
- # classes, ie classes that define a minimal subset of methods and act as aggregators
3
- # of settings or functionality. Similar to BasicObject in the standard library, but
4
- # has methods such as respond_to? and send that are required for any real DSL building
5
- # effort.
6
- class DslBuilder < Object
7
-
8
- # Remove all methods not explicitly desired
9
- instance_methods.each do |m|
10
- keepers = [:inspect, :send]
11
- undef_method m if m =~ /^[a-z]+[0-9]?$/ && !keepers.include?(m)
12
- end
13
-
14
- end
@@ -1,176 +0,0 @@
1
- # Specialty helper class for building elegant DSLs (domain-specific languages)
2
- # The purpose of the class is to allow seamless DSL's by allowing execution
3
- # of blocks with the instance variables of the calling context preserved, but
4
- # all method calls proxied to a given receiver. This sounds pretty abstract,
5
- # so here's an example:
6
- #
7
- # class ControlBuilder
8
- # def initialize; @controls = []; end
9
- # def control_list; @controls; end
10
- # def knob; @controls << :knob; end
11
- # def button; @controls << :button; end
12
- # def switch; @controls << :switch; end
13
- # def self.define(&block)
14
- # @builder = self.new
15
- # DslProxy.exec(@builder, &block)
16
- # # Do something here with the builder's list of controls
17
- # @builder.control_list
18
- # end
19
- # end
20
- #
21
- # @knob_count = 5
22
- # new_list = ControlBuilder.define do
23
- # switch
24
- # @knob_count.times { knob }
25
- # button
26
- # end
27
- #
28
- # Notice the lack of explicit builder receiver to the calls to #switch, #knob and #button.
29
- # Those calls are automatically proxied to the receiver we passed to the DslProxy.
30
- #
31
- # In quick and dirty DSLs, like Rails' migrations, you end up with a lot of
32
- # pointless receiver declarations for each method call, like so:
33
- #
34
- # def change
35
- # create_table do |t|
36
- # t.integer :counter
37
- # t.text :title
38
- # t.text :desc
39
- # # ... tired of typing "t." yet? ...
40
- # end
41
- # end
42
- #
43
- # This is not a big deal if you're using a simple DSL, but when you have multiple nested
44
- # builders going on at once, it is ugly, pointless, and can cause bugs when
45
- # the throwaway arg names you choose (eg 't' above) overlap in scope.
46
- #
47
- # In addition, simply using a yield statment loses the instance variables set in the calling
48
- # context. This is a major pain in eg Rails views, where most of the interesting
49
- # data resides in instance variables. You can get around this when #yield-ing by
50
- # explicitly creating a local variable to be picked up by the closure created in the
51
- # block, but it kind of sucks.
52
- #
53
- # In summary, DslProxy allows you to keep all the local and instance variable context
54
- # from your block declarations, while proxying all method calls to a given
55
- # receiver. If you're not building DSLs, this class is not for you, but if you are,
56
- # I hope it helps!
57
- class DslProxy < BasicObject
58
-
59
- # Pass in a builder-style class, or other receiver you want set as "self" within the
60
- # block, and off you go. The passed block will be executed with all
61
- # block-context local and instance variables available, but with all
62
- # method calls sent to the receiver you pass in. The block's result will
63
- # be returned.
64
- #
65
- # If the receiver doesn't respond_to? a method, any missing methods
66
- # will be proxied to the enclosing context.
67
- def self.exec(receiver, *to_yield, &block) # :yields: receiver
68
- # Find the context within which the block was defined
69
- context = ::Kernel.eval('self', block.binding)
70
-
71
- # Create or re-use our proxy object
72
- if context.respond_to?(:_to_dsl_proxy)
73
- # If we're nested, we don't want/need a new dsl proxy, just re-use the existing one
74
- proxy = context._to_dsl_proxy
75
- else
76
- # Not nested, create a new proxy for our use
77
- proxy = DslProxy.new(context)
78
- end
79
-
80
- # Exec the block and return the result
81
- proxy._proxy(receiver, *to_yield, &block)
82
- end
83
-
84
- # Simple state setup
85
- def initialize(context)
86
- @_receivers = []
87
- @_instance_original_values = {}
88
- @_context = context
89
- end
90
-
91
- def _proxy(receiver, *to_yield, &block) # :yields: receiver
92
- # Sanity!
93
- raise 'Cannot proxy with a DslProxy as receiver!' if receiver.respond_to?(:_to_dsl_proxy)
94
-
95
- if @_receivers.empty?
96
- # On first proxy call, run each context instance variable,
97
- # and set it to ourselves so we can proxy it
98
- @_context.instance_variables.each do |var|
99
- unless var.starts_with?('@_')
100
- value = @_context.instance_variable_get(var.to_s)
101
- @_instance_original_values[var] = value
102
- instance_eval "#{var} = value"
103
- end
104
- end
105
- end
106
-
107
- # Save the dsl target as our receiver for proxying
108
- _push_receiver(receiver)
109
-
110
- # Run the block with ourselves as the new "self", passing the given yieldable(s) or
111
- # the receiver in case the code wants to disambiguate for some reason
112
- to_yield = [receiver] if to_yield.empty?
113
- to_yield = to_yield.first(block.arity)
114
- result = instance_exec(*to_yield, &block)
115
-
116
- # Pop the last receiver off the stack
117
- _pop_receiver
118
-
119
- if @_receivers.empty?
120
- # Run each local instance variable and re-set it back to the context if it has changed during execution
121
- #instance_variables.each do |var|
122
- @_context.instance_variables.each do |var|
123
- unless var.starts_with?('@_')
124
- value = instance_eval("#{var}")
125
- if @_instance_original_values[var] != value
126
- @_context.instance_variable_set(var.to_s, value)
127
- end
128
- end
129
- end
130
- end
131
-
132
- return result
133
- end
134
-
135
- # For nesting multiple proxies
136
- def _to_dsl_proxy
137
- self
138
- end
139
-
140
- # Set the currently active receiver
141
- def _push_receiver(receiver)
142
- @_receivers.push receiver
143
- end
144
-
145
- # Remove the currently active receiver, restore old receiver if nested
146
- def _pop_receiver
147
- @_receivers.pop
148
- end
149
-
150
- # Proxies all calls to our receiver, or to the block's context
151
- # if the receiver doesn't respond_to? it.
152
- def method_missing(method, *args, &block)
153
- #$stderr.puts "Method missing: #{method}"
154
- if @_receivers.last.respond_to?(method)
155
- #$stderr.puts "Proxy [#{method}] to receiver"
156
- @_receivers.last.__send__(method, *args, &block)
157
- else
158
- #$stderr.puts "Proxy [#{method}] to context"
159
- @_context.__send__(method, *args, &block)
160
- end
161
- end
162
-
163
- # Let anyone who's interested know what our proxied objects will accept
164
- def respond_to?(method, include_private = false)
165
- return true if method == :_to_dsl_proxy
166
- @_receivers.last.respond_to?(method, include_private) || @_context.respond_to?(method, include_private)
167
- end
168
-
169
- # Proxies searching for constants to the context, so that eg Kernel::foo can actually
170
- # find Kernel - BasicObject does not partake in the global scope!
171
- def self.const_missing(name)
172
- #$stderr.puts "Constant missing: #{name} - proxy to context"
173
- @_context.class.const_get(name)
174
- end
175
-
176
- end
@@ -1,29 +0,0 @@
1
- describe DslBuilder do
2
-
3
- # TODO: break this out a bit...
4
- it 'should allow using DSL-style accessors' do
5
- class MyBuilder < DslBuilder
6
- dsl_accessor :name
7
- dsl_flag :flagged
8
- end
9
- builder = MyBuilder.new
10
-
11
- # Test standalone
12
- builder.name 'ProjectX'
13
- builder.name.should == 'ProjectX'
14
-
15
- builder.flagged?.should be_false
16
- builder.flagged = true
17
- builder.flagged?.should be_true
18
- builder.flagged = false
19
-
20
- # Test as part of DslProxy usage (common case)
21
- DslProxy.exec(builder) do
22
- name 'Project Omega'
23
- flagged!
24
- end
25
- builder.name.should == 'Project Omega'
26
- builder.flagged?.should be_true
27
- end
28
-
29
- end
@@ -1,110 +0,0 @@
1
- describe DslProxy do
2
-
3
- # Sample DSL builder class for use in testing
4
- class ControlBuilder
5
- def initialize; @controls = []; end
6
- def controls; @controls; end
7
- def knob; @controls << :knob; end
8
- def button; @controls << :button; end
9
- def switch; @controls << :switch; end
10
-
11
- def self.define(&block)
12
- @builder = self.new
13
- DslProxy.exec(@builder, &block)
14
- @builder.controls
15
- end
16
- end
17
-
18
- it 'should proxy calls to the receiver' do
19
- receiver = Object.new
20
- DslProxy.exec(receiver) do
21
- self.class.name.should == 'Object'
22
- end
23
- end
24
-
25
- it 'should proxy respond_to? to the receiver' do
26
- receiver = ControlBuilder.new
27
- DslProxy.exec(receiver) do
28
- respond_to?(:garbaz).should == false
29
- respond_to?(:button).should == true
30
- end
31
- end
32
-
33
- it 'should proxy local variables from the binding context' do
34
- @foo = 'bar'
35
- DslProxy.exec(Object.new) do
36
- @foo.should == 'bar'
37
- end
38
- end
39
-
40
- it 'should propagate local variable changes back to the binding context' do
41
- @foo = 'bar'
42
- DslProxy.exec(Object.new) do
43
- @foo = 'no bar!'
44
- end
45
- @foo.should == 'no bar!'
46
- end
47
-
48
- it 'should proxy missing methods on the receiver to the calling context' do
49
- class TestContext
50
- def bar
51
- 'something'
52
- end
53
-
54
- def test
55
- DslProxy.exec(Object.new) do
56
- bar
57
- end
58
- end
59
- end
60
-
61
- TestContext.new.test.should == 'something'
62
- end
63
-
64
- it 'should return the result of the block' do
65
- res = DslProxy.exec(Object.new) do
66
- 'foo'
67
- end
68
- res.should == 'foo'
69
- end
70
-
71
- it 'should allow access to global constants' do
72
- DslProxy.exec(self) do # Use self here, so #be_a is defined. :-)
73
- Object.new.should be_a(Object)
74
- end
75
- end
76
-
77
- it 'should proxy correctly even when nested' do
78
- def outerfunc
79
- 5
80
- end
81
- @instance_var = nil
82
- local_var = nil
83
- DslProxy.exec(self) do
84
- DslProxy.exec(Object.new) do
85
- outerfunc.should == 5
86
- @instance_var.should be_nil
87
- local_var.should be_nil
88
- @instance_var = 10
89
- local_var = 11
90
- end
91
- end
92
- @instance_var.should == 10
93
- local_var.should == 11
94
- end
95
-
96
- it 'should pass additional args to block as argument' do
97
- l = lambda {|arg1, arg2| arg1 + arg2}
98
- DslProxy.exec(Object.new, 5, 1, &l).should == 6
99
- end
100
-
101
- it 'should put it all together' do
102
- @knob_count = 5
103
- controls = ControlBuilder.define do
104
- switch
105
- @knob_count.times { knob }
106
- end
107
- controls.count.should == 6
108
- end
109
-
110
- end