def_dsl 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Guardfile +37 -0
- data/def_dsl.gemspec +2 -0
- data/lib/def_dsl.rb +211 -34
- data/lib/def_dsl/version.rb +1 -1
- data/spec/exmaple_spec.rb +45 -9
- data/spec/support/remove_const.rb +3 -3
- data/spec/unit/def_dsl/all_modules_spec.rb +255 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0bf88a700504a38b4fc76da05744ba255305098
|
4
|
+
data.tar.gz: 76cccfdc5bdb63cc32797ede9e91907e631b9688
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54a1517902548b0ea57202cf384638bffda51646a5cb10aeaf2fa83e1f751471ca34cf2696085fb6201119a377172a592e48223d76955e9f73e33d731b97b9bd
|
7
|
+
data.tar.gz: 3d86dd7b95305dcd8070b56454552804701385a16912a7575e044e41928538184e538d8a87401509187ec40d59078f18729b239c18f303c152cdecc3e934e806
|
data/.gitignore
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
notification :tmux, display_message: false
|
5
|
+
#notification :tmux,
|
6
|
+
# :display_message => true,
|
7
|
+
# :timeout => 5, # in seconds
|
8
|
+
# :default_message_format => '%s >> %s',
|
9
|
+
# # the first %s will show the title, the second the message
|
10
|
+
# # Alternately you can also configure *success_message_format*,
|
11
|
+
# # *pending_message_format*, *failed_message_format*
|
12
|
+
# :line_separator => ' > ', # since we are single line we need a separator
|
13
|
+
# :color_location => 'status-left-bg' # to customize which tmux element will change color
|
14
|
+
|
15
|
+
|
16
|
+
guard 'rspec', all_on_start: true do
|
17
|
+
watch(%r{^spec/.+_spec\.rb$})
|
18
|
+
watch(/\.rb$/) { 'spec' }
|
19
|
+
# some discipline to map lib => spec
|
20
|
+
end
|
21
|
+
__END__
|
22
|
+
# Rails example
|
23
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
24
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
25
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
26
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
27
|
+
watch('config/routes.rb') { "spec/routing" }
|
28
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
29
|
+
|
30
|
+
# Capybara features specs
|
31
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
32
|
+
|
33
|
+
# Turnip features and steps
|
34
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
35
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
36
|
+
end
|
37
|
+
|
data/def_dsl.gemspec
CHANGED
data/lib/def_dsl.rb
CHANGED
@@ -3,55 +3,179 @@
|
|
3
3
|
#
|
4
4
|
# extended at the end of context class
|
5
5
|
# rspec!!!!!!!!!!!!!
|
6
|
+
# mutant?
|
7
|
+
# So is'nt tested
|
8
|
+
# more comments inside method - more dumb decisions it has!
|
6
9
|
|
10
|
+
require "def_dsl/version"
|
11
|
+
require 'meta_module'
|
7
12
|
|
8
|
-
#
|
9
|
-
#
|
13
|
+
#def DefDsl *classes
|
14
|
+
# DefDsl::Dsl.new *classes
|
15
|
+
#end
|
16
|
+
#alias DefDSL DefDsl
|
10
17
|
|
11
|
-
|
18
|
+
# shortcut to extend and define
|
19
|
+
def DefDsl! *black_list
|
20
|
+
Module.new do
|
21
|
+
define_singleton_method :extended do |target|
|
22
|
+
target.send :extend, DefDsl
|
23
|
+
target.def_dsl *black_list
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
alias DefDSL! DefDsl!
|
12
28
|
|
13
29
|
module DefDsl
|
14
30
|
|
31
|
+
module Lazy
|
32
|
+
def feed_block &b; @block_ = b end
|
33
|
+
def block!; @block_ end
|
34
|
+
def call! ctx; ctx.instance_eval &block! end
|
35
|
+
end
|
36
|
+
|
37
|
+
# todo: test so, trash(?)
|
38
|
+
def def_dsl trash = []
|
39
|
+
DefDsl.traverse self, trash do |who|
|
40
|
+
who.send :include, So
|
41
|
+
who.send :include, Lazy if who.instance_eval { @lazy }
|
42
|
+
|
43
|
+
DefDsl.shallow(who, trash).each do |mod|
|
44
|
+
mini = mod.name.underscore # .....
|
45
|
+
method = mod.instance_eval { @dsl } || mod.name.underscore
|
15
46
|
|
16
|
-
|
17
|
-
|
18
|
-
|
47
|
+
who.module_eval do
|
48
|
+
define_method method do |*a,&b|
|
49
|
+
so [mini,method],*a,&b # artifact...
|
50
|
+
end
|
51
|
+
end
|
52
|
+
# or check superclass if respond for meta_modules + test
|
53
|
+
if who.class == Module
|
54
|
+
who.send :module_function, method
|
55
|
+
end
|
56
|
+
end
|
19
57
|
end
|
20
58
|
end
|
21
|
-
alias define_dsl def_dsl
|
22
59
|
|
60
|
+
# todo: to test optional black list or run mutant :)
|
61
|
+
#
|
62
|
+
# @param given [Class, Module]
|
63
|
+
# @return [Array<Class, Module>] that explicitly defined in given
|
64
|
+
def shallow given, trash = []
|
65
|
+
if given.class == Module; given.constants.map { |x| given.const_get x }
|
66
|
+
elsif given.class == Class
|
67
|
+
here = given.constants.map { |x| given.const_get x }
|
68
|
+
sup = given.superclass
|
69
|
+
other = sup.constants.map { |x| sup.const_get x }
|
70
|
+
here - other
|
71
|
+
else []
|
72
|
+
end - trash
|
73
|
+
end
|
74
|
+
module_function :shallow # explicit_const or other name?
|
23
75
|
|
24
|
-
|
25
|
-
|
76
|
+
# @param klass
|
77
|
+
# @param trash [Class, Module, Array<Class, Module>]
|
78
|
+
# optional black list of entities to visit and return
|
79
|
+
# @return [Array<Class, Module>]
|
80
|
+
def all_modules klass, trash = []
|
81
|
+
trash = [*trash]
|
82
|
+
trash += [klass]
|
83
|
+
children = shallow(klass, trash)
|
84
|
+
all = [klass, children.
|
85
|
+
map { |x| all_modules x, trash + children }].
|
86
|
+
flatten.select { |x| Module === x }
|
87
|
+
all
|
26
88
|
end
|
89
|
+
module_function :all_modules
|
27
90
|
|
91
|
+
# implicit way to use instance_eval, by passing block with zero arity
|
92
|
+
# @param block [Proc]
|
93
|
+
# @return [Proc]
|
94
|
+
def arity_based &block
|
95
|
+
block.arity == 0 ? proc { |obj| obj.instance_eval &block }
|
96
|
+
: block
|
97
|
+
end
|
98
|
+
module_function :arity_based
|
28
99
|
|
29
|
-
|
30
|
-
|
31
|
-
|
100
|
+
# traverse tree of classes and modules, acts {arity_based}
|
101
|
+
#
|
102
|
+
# @param target [Class, Module] root of search tree
|
103
|
+
# @param trash [Array<Class, Module>] black list of entities to visit and yield
|
104
|
+
# @yield [Class, Module] once per entity
|
105
|
+
def traverse target, trash = [], &block
|
106
|
+
all_modules(target, trash).each &DefDsl.arity_based(&block)
|
107
|
+
end
|
108
|
+
module_function :traverse
|
32
109
|
|
33
|
-
|
34
|
-
|
35
|
-
|
110
|
+
#include MetaModule
|
111
|
+
#class DSL < MModule
|
112
|
+
# def initialize(*classes) @classes = classes end
|
113
|
+
# used do |x|
|
114
|
+
# x.extend DefDsl
|
115
|
+
# @classes.each { |c| x.def_dsl c }
|
116
|
+
# end
|
117
|
+
#end
|
118
|
+
#Dsl = DSL
|
36
119
|
|
37
|
-
meth = const.instance_eval { @dsl } || mini
|
38
120
|
|
39
|
-
who.class_eval do
|
40
|
-
define_method(meth) do |*a,&b|
|
41
|
-
so [mini,meth],*a,&b
|
42
|
-
end
|
43
|
-
end
|
44
121
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
122
|
+
#
|
123
|
+
#
|
124
|
+
#
|
125
|
+
#
|
126
|
+
#######################################################
|
127
|
+
#
|
128
|
+
#
|
129
|
+
#
|
130
|
+
#
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
#def def_dsl *const
|
135
|
+
# const.each do |const|
|
136
|
+
# define_dsl! self, [[const.name.to_s.underscore(self), const]]
|
137
|
+
# end
|
138
|
+
#end
|
139
|
+
#alias define_dsl def_dsl
|
140
|
+
|
141
|
+
|
142
|
+
# def shallow_constants who
|
143
|
+
# (who.constants - who.superclass.constants).map { |name| * = name.to_s.underscore, who.const_get(name) }
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
#
|
147
|
+
# def define_dsl! who, constants=shallow_constants(who) # ...
|
148
|
+
# # constants = constants.nil?? shallow_constants(who) : constants_info(constants)
|
149
|
+
# return if who.included_modules.include? So
|
150
|
+
# who.send :include, So
|
151
|
+
# constants.each do |mini, const|
|
152
|
+
#
|
153
|
+
# #next if who.included_modules.include? So
|
154
|
+
# #who.send :include, So
|
155
|
+
# next if const.included_modules.include? So
|
156
|
+
# const.send :include, So
|
157
|
+
# #who.send :include, So
|
158
|
+
#
|
159
|
+
# define_dsl! const if const.is_a? Class
|
160
|
+
#
|
161
|
+
# meth = const.instance_eval { @dsl } || mini
|
162
|
+
#
|
163
|
+
# who.class_eval do
|
164
|
+
# define_method(meth) do |*a,&b|
|
165
|
+
# so [mini,meth],*a,&b
|
166
|
+
# end
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# # const.send :include, So if const.is_a? Module # or even class
|
170
|
+
# # who.send :include, So if who.is_a? Module # or even class
|
171
|
+
# if who.class == Module
|
172
|
+
# who.send :module_function, meth
|
173
|
+
# who.send :module_function, :so
|
174
|
+
# who.send :module_function, :so1
|
175
|
+
# who.send :module_function, :so2
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
# end
|
55
179
|
|
56
180
|
module So
|
57
181
|
def feed_block &block
|
@@ -87,8 +211,17 @@ module DefDsl
|
|
87
211
|
value = @so[name]
|
88
212
|
value.is_a?(Array) ? value : [value]
|
89
213
|
end
|
214
|
+
|
215
|
+
def self.included target
|
216
|
+
if target.class == Module # class.superclass for meta_module...
|
217
|
+
target.send :module_function, :so
|
218
|
+
target.send :module_function, :so1
|
219
|
+
target.send :module_function, :so2
|
220
|
+
end
|
221
|
+
end
|
90
222
|
end
|
91
223
|
|
224
|
+
|
92
225
|
end
|
93
226
|
DefDSL = DefDsl
|
94
227
|
|
@@ -98,12 +231,56 @@ class String
|
|
98
231
|
self.split(/[^a-z0-9]/i).map{|w| w.capitalize}.join
|
99
232
|
end
|
100
233
|
|
101
|
-
|
102
|
-
|
234
|
+
# just last name
|
235
|
+
def underscore #(relative_to=nil)
|
236
|
+
#name = relative_to.nil?? self : self.sub(/^#{ relative_to.name.to_s }::/,'')
|
237
|
+
name = self
|
103
238
|
name.gsub(/::/, '/').
|
104
239
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
105
240
|
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
106
241
|
tr("-", "_").
|
107
|
-
downcase
|
242
|
+
downcase.
|
243
|
+
split('/').last
|
108
244
|
end
|
109
245
|
end
|
246
|
+
__END__
|
247
|
+
#def def_dsl *classes
|
248
|
+
# classes.any?? def_dsl!(classes) : def_dsl!
|
249
|
+
#end
|
250
|
+
#def def_dsl #*classes #=shallow(self)
|
251
|
+
# classes
|
252
|
+
# classes.each do |klass|
|
253
|
+
# klass.def_dsl_shallow # WTF? #klass
|
254
|
+
# end
|
255
|
+
# #magic = So
|
256
|
+
# #self.send :include, magic #unless self.included_modules.include? magic
|
257
|
+
# #p self
|
258
|
+
# #classes.each do |klass|
|
259
|
+
# # DefDsl.include_recursively klass, magic
|
260
|
+
# #end
|
261
|
+
#end
|
262
|
+
#def def_dsl_shallow targets = shallow(self); root = self
|
263
|
+
# [*targets].each do |x|
|
264
|
+
# meth = x.instance_eval { @dsl } || x.name.to_s.underscore(root)
|
265
|
+
# root.class_eval do
|
266
|
+
# define_method(meth) do |*a,&b|
|
267
|
+
# #so [mini,meth],*a,&b
|
268
|
+
# end
|
269
|
+
# end
|
270
|
+
# if root.class == Module
|
271
|
+
# root.send :module_function, meth
|
272
|
+
# #who.send :module_function, :so
|
273
|
+
# #who.send :module_function, :so1
|
274
|
+
# #who.send :module_function, :so2
|
275
|
+
# end
|
276
|
+
# end
|
277
|
+
#end
|
278
|
+
|
279
|
+
####def include_recursively target, mod, &block
|
280
|
+
#### all_modules(target).each do |x|
|
281
|
+
#### x.send :include, mod
|
282
|
+
#### x.instance_eval &block if block
|
283
|
+
#### end
|
284
|
+
####end
|
285
|
+
####module_function :include_recursively
|
286
|
+
####module_function :all_modules, :shallow
|
data/lib/def_dsl/version.rb
CHANGED
data/spec/exmaple_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
describe
|
1
|
+
describe 'DefDsl or DefDSL' do
|
2
2
|
after { remove_const :My if defined? My }
|
3
3
|
|
4
4
|
example 'usage inside module' do
|
@@ -10,8 +10,7 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
10
10
|
File = File
|
11
11
|
end
|
12
12
|
|
13
|
-
extend DefDSL
|
14
|
-
def_dsl Dir, File
|
13
|
+
extend DefDSL! # accepts optional black list of classes
|
15
14
|
|
16
15
|
file 'root.txt'
|
17
16
|
dir 'dir' do
|
@@ -42,7 +41,7 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
42
41
|
end
|
43
42
|
|
44
43
|
extend DefDSL
|
45
|
-
def_dsl
|
44
|
+
def_dsl # accepts optional black list of classes
|
46
45
|
|
47
46
|
def initialize
|
48
47
|
file 'root.txt'
|
@@ -77,7 +76,7 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
77
76
|
end
|
78
77
|
|
79
78
|
extend DefDSL
|
80
|
-
def_dsl ADir, AFile
|
79
|
+
def_dsl #ADir, AFile
|
81
80
|
|
82
81
|
file 'root.txt'
|
83
82
|
dir 'dir' do
|
@@ -112,7 +111,7 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
112
111
|
end
|
113
112
|
|
114
113
|
extend DefDSL
|
115
|
-
def_dsl Dir, File
|
114
|
+
def_dsl #Dir, File
|
116
115
|
|
117
116
|
file 'root.txt' do
|
118
117
|
this.block.should_be just stored.in_ivar
|
@@ -137,7 +136,7 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
137
136
|
end
|
138
137
|
|
139
138
|
|
140
|
-
example 'lazy evaluation' do
|
139
|
+
example 'lazy evaluation' do # useless
|
141
140
|
pending
|
142
141
|
class My
|
143
142
|
class File < Struct.new :name; end
|
@@ -147,7 +146,7 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
147
146
|
end
|
148
147
|
|
149
148
|
extend DefDSL
|
150
|
-
def_dsl Dir, File
|
149
|
+
def_dsl #Dir, File
|
151
150
|
|
152
151
|
def initialize &block
|
153
152
|
@block = block
|
@@ -195,4 +194,41 @@ describe [DefDsl,DefDSL].join' or ' do
|
|
195
194
|
pending
|
196
195
|
end
|
197
196
|
|
198
|
-
|
197
|
+
|
198
|
+
example 'easy dsl' do
|
199
|
+
module My
|
200
|
+
class Use123; end
|
201
|
+
|
202
|
+
extend DefDsl!
|
203
|
+
use123
|
204
|
+
so.should == {use123: so1(:use123)}
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
example 'declarative way to remember block' do
|
209
|
+
module My
|
210
|
+
class Blocky
|
211
|
+
@lazy = true # should remember block to be used in other context
|
212
|
+
end # lazy is too short to ignore
|
213
|
+
extend DefDSL!
|
214
|
+
|
215
|
+
blocky do |x|
|
216
|
+
@a = (@a || 0) + 1
|
217
|
+
end
|
218
|
+
|
219
|
+
context = Object.new
|
220
|
+
so1(:blocky).call!(context)
|
221
|
+
context.instance_eval { @a }.should == 1
|
222
|
+
|
223
|
+
#so.should == {file: so1(:file), dir: so1(:dir)}
|
224
|
+
#class Blocky < Struct.new :shit
|
225
|
+
#end
|
226
|
+
#extend DefDsl #(Block)
|
227
|
+
#def_dsl Blocky
|
228
|
+
#blocky do
|
229
|
+
# @a = 123
|
230
|
+
#end
|
231
|
+
#expect { my.so1(:block).call! }.to change { my.so1(:block).instance_eval{@a} }.from(nil).to(123)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
def remove_const
|
2
|
-
Object.send :remove_const, name
|
3
|
-
end
|
1
|
+
def remove_const *names
|
2
|
+
names.each { |name| Object.send :remove_const, name }
|
3
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
describe DefDsl do
|
2
|
+
#subject { DefDsl }
|
3
|
+
after { remove_const :My if defined? My }
|
4
|
+
|
5
|
+
describe '.shallow' do
|
6
|
+
it '<:*works*:>' do
|
7
|
+
module My
|
8
|
+
X = Class.new
|
9
|
+
class ASuper
|
10
|
+
B = Class.new
|
11
|
+
C = Class.new
|
12
|
+
end
|
13
|
+
class Super < ASuper
|
14
|
+
A = Class.new
|
15
|
+
Y = Class.new
|
16
|
+
end
|
17
|
+
class B < Super
|
18
|
+
A = Class.new
|
19
|
+
B = Class.new
|
20
|
+
C = Class.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
DefDsl.shallow(My::B).should == [My::B::A, My::B::B, My::B::C]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# todo find a better place for helpers
|
29
|
+
describe '.arity_based' do
|
30
|
+
it 'wraps block with instance_eval if block.arity == 0' do
|
31
|
+
a = [1,2,3].map &DefDsl.arity_based { to_s }
|
32
|
+
a.should == %w[1 2 3]
|
33
|
+
end
|
34
|
+
it 'just returns given block otherwise' do
|
35
|
+
a = proc { |x| }
|
36
|
+
DefDsl.arity_based(&a).should == a
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
describe '#def_dsl' do
|
42
|
+
#it 'traverse self, includes So; So.included does other work?'
|
43
|
+
#it 'define dsl for each AMBIGUOUS?
|
44
|
+
#it 'takes optional black list'
|
45
|
+
it 'includes So... in self and each who is_a module' do
|
46
|
+
module My
|
47
|
+
@magic = DefDsl::So # name...
|
48
|
+
|
49
|
+
class A; end; class B; end
|
50
|
+
class C
|
51
|
+
module E
|
52
|
+
class D; end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
extend DefDsl
|
57
|
+
|
58
|
+
[My,A,B,C,C::E,C::E::D].map { |x| x.include? @magic }.should == [false]*6
|
59
|
+
def_dsl
|
60
|
+
[My,A,B,C,C::E,C::E::D].map { |x| x.include? @magic }.should == [true]*6
|
61
|
+
|
62
|
+
#extend RSpec::Matchers ### redefines method `include`...
|
63
|
+
#RSpec::Matchers.expect { def_dsl }.to RSpec::Matchers.change {
|
64
|
+
# [My, A, B, C, C::E, C::E::D].map { |x| x.include? @magic }
|
65
|
+
#}.from([false]*6).to([true]*6)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
it 'defines dsl methods for classes inside module' do
|
69
|
+
module My
|
70
|
+
class A; end
|
71
|
+
class B
|
72
|
+
class C; end
|
73
|
+
end
|
74
|
+
|
75
|
+
extend DefDsl
|
76
|
+
def_dsl
|
77
|
+
extend RSpec::Matchers
|
78
|
+
expect { a;b;B.new.c }.not_to raise_error
|
79
|
+
end
|
80
|
+
end
|
81
|
+
it 'defines dsl methods for classes inside class' do
|
82
|
+
class My
|
83
|
+
class A < Struct.new :any; end
|
84
|
+
class B
|
85
|
+
class C; end
|
86
|
+
end
|
87
|
+
|
88
|
+
extend DefDsl
|
89
|
+
def_dsl
|
90
|
+
self
|
91
|
+
end.new.instance_eval do
|
92
|
+
extend RSpec::Matchers
|
93
|
+
expect { a;b;My::B.new.c }.not_to raise_error
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '.traverse' do
|
99
|
+
it 'acts arity based' do
|
100
|
+
module My
|
101
|
+
class A; end; class B; end
|
102
|
+
|
103
|
+
DefDsl.should_receive(:arity_based).once
|
104
|
+
DefDsl.traverse(My) { }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
context 'one argument' do
|
108
|
+
it 'runs block in context of each found module once per entity' do
|
109
|
+
module My
|
110
|
+
class A
|
111
|
+
end
|
112
|
+
class B
|
113
|
+
module C
|
114
|
+
A = A
|
115
|
+
X = A
|
116
|
+
Y = B
|
117
|
+
end
|
118
|
+
end
|
119
|
+
DefDsl.traverse My do
|
120
|
+
@count = (@count || 0) + 1
|
121
|
+
end
|
122
|
+
[A, B, B::C, B::C::A, B::C::X, B::C::Y].each do |x|
|
123
|
+
x.instance_eval { @count }.should == 1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
context 'two arguments' do # not very useful but emergent anyway!
|
129
|
+
it 'takes optional black list of entities to visit and yield' do
|
130
|
+
module My
|
131
|
+
class A
|
132
|
+
end
|
133
|
+
class B
|
134
|
+
module C
|
135
|
+
A = A
|
136
|
+
X = A
|
137
|
+
Y = B
|
138
|
+
end
|
139
|
+
end
|
140
|
+
DefDsl.traverse My, [A] do
|
141
|
+
@count = (@count || 0) + 1
|
142
|
+
end
|
143
|
+
[A, B::C::A, B::C::X].each do |x|
|
144
|
+
x.instance_eval { @count }.should == nil
|
145
|
+
end
|
146
|
+
[B, B::C, B::C::Y].each do |x|
|
147
|
+
x.instance_eval { @count }.should == 1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe '.all_modules' do
|
155
|
+
# todo: returns '' do instead of it '' do
|
156
|
+
it 'returns all unique nested modules and classes' do
|
157
|
+
module My
|
158
|
+
ODDMy = My
|
159
|
+
ODD = 1
|
160
|
+
A = Class.new
|
161
|
+
class B
|
162
|
+
ODDB = B
|
163
|
+
ODDA = A
|
164
|
+
C = Module.new
|
165
|
+
ODD = 1
|
166
|
+
module D
|
167
|
+
ODDB = B
|
168
|
+
E = Module.new
|
169
|
+
ODD = 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
module F
|
173
|
+
ODD = 1
|
174
|
+
G = Module.new
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
DefDsl.all_modules(My).map(&:name).map{|x|x.split('::').last}.should == ['My',*'A'..'G']
|
179
|
+
end
|
180
|
+
it 'takes optional black list of entities to visit and return' do
|
181
|
+
module My
|
182
|
+
A = Class.new
|
183
|
+
class B
|
184
|
+
C = Class.new
|
185
|
+
end
|
186
|
+
|
187
|
+
DefDsl.all_modules(My, My::B).should == [My,My::A]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
__END__
|
193
|
+
describe '#def_dsl_shallow' do
|
194
|
+
it 'defines dsl methods for each shallow nested module if no argument given' do
|
195
|
+
module My
|
196
|
+
A = Class.new
|
197
|
+
B = Module.new
|
198
|
+
extend DefDsl
|
199
|
+
extend RSpec::Matchers
|
200
|
+
expect { def_dsl_shallow }.to change { (a && b) rescue :err }.from(:err)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
it 'defines dsl methods only for given classes/modules' do
|
204
|
+
module My
|
205
|
+
A = Class.new
|
206
|
+
B = Module.new
|
207
|
+
extend DefDsl
|
208
|
+
extend RSpec::Matchers
|
209
|
+
expect { def_dsl_shallow A }.to change {
|
210
|
+
[:a,:b].select { |x| respond_to? x } }.from([]).to([:a])
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
#describe 'def_dsl' do
|
216
|
+
# it 'calls def_dsl_shallow for self and each nested module recursively' do
|
217
|
+
# module My
|
218
|
+
# A = Module.new
|
219
|
+
# class B
|
220
|
+
# C = Class.new
|
221
|
+
# end
|
222
|
+
# extend DefDsl
|
223
|
+
# extend RSpec::Matchers
|
224
|
+
# ########## DefDsl.should_receive(:def_shallow_dsl) ###
|
225
|
+
# def_dsl
|
226
|
+
# expect { def_dsl }.to change {
|
227
|
+
# respond_to?(:a) # && respond_to?(:b) && B.new.respond_to?(:c)
|
228
|
+
# }.from(false).to(true)
|
229
|
+
# end
|
230
|
+
# end
|
231
|
+
# it 'include ***crap*** in self' do#.include_recursively for given module' do
|
232
|
+
# module My
|
233
|
+
# class A; end
|
234
|
+
# #DefDsl.should_receive(:include_recursively).with(My, DefDsl::So)
|
235
|
+
# extend DefDsl
|
236
|
+
# extend RSpec::Matchers
|
237
|
+
# expect { My.def_dsl A }.to change { My.included_modules }
|
238
|
+
# end
|
239
|
+
# end
|
240
|
+
#end
|
241
|
+
#it 'includes second module into first and all its children' do
|
242
|
+
# module My
|
243
|
+
# @rec = Module.new
|
244
|
+
# class A
|
245
|
+
# end
|
246
|
+
# class B
|
247
|
+
# module C
|
248
|
+
# end
|
249
|
+
# end
|
250
|
+
# DefDsl.include_recursively My, @rec
|
251
|
+
# [A, B, B::C].each do |x|
|
252
|
+
# x.included_modules.include?(@rec).should == true
|
253
|
+
# end
|
254
|
+
# end
|
255
|
+
#end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: def_dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander K
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: meta_module
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: easy way to build dsl without use of dsl...
|
56
84
|
email:
|
57
85
|
- xpyro@ya.ru
|
@@ -62,6 +90,7 @@ files:
|
|
62
90
|
- .gitignore
|
63
91
|
- .rspec
|
64
92
|
- Gemfile
|
93
|
+
- Guardfile
|
65
94
|
- LICENSE.txt
|
66
95
|
- README.md
|
67
96
|
- Rakefile
|
@@ -72,6 +101,7 @@ files:
|
|
72
101
|
- spec/support/remove_const.rb
|
73
102
|
- spec/support/require_self.rb
|
74
103
|
- spec/support/spec_helper.rb
|
104
|
+
- spec/unit/def_dsl/all_modules_spec.rb
|
75
105
|
homepage: https://github.com/sowcow/def_dsl
|
76
106
|
licenses:
|
77
107
|
- MIT
|
@@ -101,3 +131,4 @@ test_files:
|
|
101
131
|
- spec/support/remove_const.rb
|
102
132
|
- spec/support/require_self.rb
|
103
133
|
- spec/support/spec_helper.rb
|
134
|
+
- spec/unit/def_dsl/all_modules_spec.rb
|