dockly-util 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/dockly/util/dsl.rb +58 -12
- data/lib/dockly/util/version.rb +1 -1
- data/spec/dockly/util/dsl_spec.rb +224 -0
- data/spec/{dockl → dockly}/util/logger_spec.rb +0 -0
- data/spec/spec_helper.rb +1 -0
- metadata +6 -6
- data/spec/dockl/util/dsl_spec.rb +0 -171
data/lib/dockly/util/dsl.rb
CHANGED
@@ -22,29 +22,64 @@ module Dockly::Util::DSL
|
|
22
22
|
end
|
23
23
|
private :dsl_attribute
|
24
24
|
|
25
|
-
def dsl_class_attribute(name, klass)
|
25
|
+
def dsl_class_attribute(name, klass, options={})
|
26
26
|
unless klass.ancestors.include?(Dockly::Util::DSL)
|
27
|
-
raise "#{self
|
28
|
-
end
|
29
|
-
define_method(name) do |sym = nil, &block|
|
30
|
-
new_value = case
|
31
|
-
when !block.nil? && !sym.nil? then klass.new!(:name => sym, &block)
|
32
|
-
when block.nil? then klass.instances[sym]
|
33
|
-
when sym.nil? then klass.new!(:name => :"#{self.name}_#{klass}", &block)
|
34
|
-
end
|
35
|
-
instance_variable_set(:"@#{name}", new_value) unless new_value.nil?
|
36
|
-
instance_variable_get(:"@#{name}")
|
27
|
+
raise "#{self}.dsl_class_attribute requires a class that includes DSL"
|
37
28
|
end
|
29
|
+
type = options.delete(:type) || Object
|
30
|
+
generated_related_name = :"#{self.underscore(self.demodulize(self.to_s))}"
|
31
|
+
related_name = options.delete(:related_name) || generated_related_name
|
32
|
+
define_forward_relation(name, related_name, self, klass, type)
|
33
|
+
define_reverse_relation(related_name, name, klass, self)
|
38
34
|
end
|
39
35
|
private :dsl_class_attribute
|
40
36
|
|
37
|
+
def define_forward_relation(name, related_name, current_class, klass, type)
|
38
|
+
current_class.instance_eval do
|
39
|
+
define_method(name) do |sym = nil, &block|
|
40
|
+
new_value = case
|
41
|
+
when !block.nil? && !sym.nil? then klass.new!(:name => sym, &block)
|
42
|
+
when block.nil? then klass.instances[sym]
|
43
|
+
when sym.nil? then klass.new!(:name => :"#{self.name}_#{klass}", &block)
|
44
|
+
end
|
45
|
+
unless new_value.nil?
|
46
|
+
if type.ancestors.include? Array
|
47
|
+
val = instance_variable_get(:"@#{name}") || []
|
48
|
+
instance_variable_set(:"@#{name}", val + [new_value])
|
49
|
+
else
|
50
|
+
instance_variable_set(:"@#{name}", new_value)
|
51
|
+
end
|
52
|
+
new_value.instance_variable_set(
|
53
|
+
:"@#{related_name}",
|
54
|
+
self
|
55
|
+
)
|
56
|
+
end
|
57
|
+
instance_variable_get(:"@#{name}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
private :define_forward_relation
|
62
|
+
|
63
|
+
def define_reverse_relation(name, related_name, current_class, klass)
|
64
|
+
current_class.instance_eval do
|
65
|
+
define_method(name) do
|
66
|
+
instance_variable_get(:"@#{name}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
private :define_reverse_relation
|
71
|
+
|
41
72
|
def default_value(name, val = nil)
|
42
73
|
default_values[name] = block_given? ? yield : val
|
43
74
|
end
|
44
75
|
private :default_value
|
45
76
|
|
46
77
|
def default_values
|
47
|
-
@default_values ||=
|
78
|
+
@default_values ||= if self.superclass.respond_to?(:default_values)
|
79
|
+
self.superclass.default_values
|
80
|
+
else
|
81
|
+
{}
|
82
|
+
end
|
48
83
|
end
|
49
84
|
|
50
85
|
def instances
|
@@ -59,6 +94,17 @@ module Dockly::Util::DSL
|
|
59
94
|
end
|
60
95
|
end
|
61
96
|
|
97
|
+
def underscore(camel_cased_word)
|
98
|
+
word = camel_cased_word.to_s.dup
|
99
|
+
word.gsub!('::', '/')
|
100
|
+
word.gsub!(/(?:([A-Za-z\d])|^)(#{/(?=a)b/})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
101
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
102
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
103
|
+
word.tr!("-", "_")
|
104
|
+
word.downcase!
|
105
|
+
word
|
106
|
+
end
|
107
|
+
|
62
108
|
def generate_unique_name
|
63
109
|
name = nil
|
64
110
|
(0..(1.0 / 0.0)).each do |n|
|
data/lib/dockly/util/version.rb
CHANGED
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class IncludedClass
|
4
|
+
include Dockly::Util::DSL
|
5
|
+
|
6
|
+
dsl_attribute :ocean
|
7
|
+
end
|
8
|
+
|
9
|
+
class TestClass
|
10
|
+
include Dockly::Util::DSL
|
11
|
+
|
12
|
+
dsl_attribute :chips
|
13
|
+
dsl_class_attribute :meta, IncludedClass
|
14
|
+
end
|
15
|
+
|
16
|
+
class ArrayClass
|
17
|
+
include Dockly::Util::DSL
|
18
|
+
|
19
|
+
dsl_class_attribute :attr, IncludedClass, type: Array
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Dockly::Util::DSL do
|
23
|
+
let(:included_class) { IncludedClass }
|
24
|
+
let(:test_class) { TestClass }
|
25
|
+
let(:array_class) { ArrayClass }
|
26
|
+
|
27
|
+
let(:test_instance) { test_class.new!(:name => 'Tony') }
|
28
|
+
let(:array_instance) { array_class.new! }
|
29
|
+
|
30
|
+
describe '.dsl_attribute' do
|
31
|
+
it 'defines a method for each name given' do
|
32
|
+
test_instance.should respond_to :chips
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'the defined method(s)' do
|
36
|
+
context 'with 0 arguments' do
|
37
|
+
let(:test_val) { 'lays' }
|
38
|
+
before { test_instance.instance_variable_set(:@chips, test_val) }
|
39
|
+
|
40
|
+
it 'returns the value of the instance variable with a matching name' do
|
41
|
+
test_instance.chips.should == test_val
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with one argument' do
|
46
|
+
it 'sets the corresponding instance variable to the passed-in value' do
|
47
|
+
expect { test_instance.chips('bbq') }
|
48
|
+
.to change { test_instance.instance_variable_get(:@chips) }
|
49
|
+
.to 'bbq'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '.dsl_class_attribute' do
|
56
|
+
context 'when the sceond argument is not a DSL' do
|
57
|
+
it 'raises an error' do
|
58
|
+
expect do
|
59
|
+
Class.new do
|
60
|
+
include Dockly::Util::DSL
|
61
|
+
|
62
|
+
dsl_class_attribute :test, Array
|
63
|
+
end
|
64
|
+
end.to raise_error
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when the second argument is a DSL' do
|
69
|
+
it 'defines a new method with the name of the first argument' do
|
70
|
+
test_instance.should respond_to :meta
|
71
|
+
array_instance.should respond_to :attr
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'defines a new method on the DSL class with the name of the current class' do
|
75
|
+
included_class.new.should respond_to :test_class
|
76
|
+
included_class.new.should respond_to :array_class
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'the method' do
|
80
|
+
context 'for a regular class attribute' do
|
81
|
+
let(:meta) { test_instance.instance_variable_get(:@meta) }
|
82
|
+
|
83
|
+
context 'when a symbol is given' do
|
84
|
+
context 'and a block is given' do
|
85
|
+
before { test_instance.meta(:yolo) { ocean 'Indian' } }
|
86
|
+
|
87
|
+
it 'creates a new instance of the specified Class with the name set' do
|
88
|
+
meta.name.should == :yolo
|
89
|
+
meta.ocean.should == 'Indian'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'and a block is not given' do
|
94
|
+
before { included_class.new!(:name => :test_name) { ocean 'Pacific' } }
|
95
|
+
|
96
|
+
it 'looks up the instance in its Class\'s .instances hash' do
|
97
|
+
test_instance.meta(:test_name).ocean.should == 'Pacific'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when a symbol is not given' do
|
103
|
+
context 'and a block is given' do
|
104
|
+
before { test_instance.meta { ocean 'Atlantic' } }
|
105
|
+
|
106
|
+
it 'creates a new instance of the specified Class' do
|
107
|
+
meta.ocean.should == 'Atlantic'
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'generates a name' do
|
111
|
+
meta.name.should == :"#{test_instance.name}_#{meta.class}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'and a block is not given' do
|
116
|
+
before { test_instance.meta(:test) { ocean 'Artic' } }
|
117
|
+
|
118
|
+
it 'returns the corresponding instance variable' do
|
119
|
+
test_instance.meta.should == meta
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'for an array class attribute' do
|
126
|
+
let(:attr) { array_instance.instance_variable_get(:@attr) }
|
127
|
+
|
128
|
+
context 'when a symbol is given' do
|
129
|
+
context 'and a block is given' do
|
130
|
+
before { array_instance.attr(:yolo) { ocean 'Indian' } }
|
131
|
+
|
132
|
+
it 'creates a new instance of the specified Class with the name set' do
|
133
|
+
expect(attr.length).to be == 1
|
134
|
+
expect(attr.first.ocean).to be == 'Indian'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'and a block is not given' do
|
139
|
+
before { included_class.new!(:name => :test_name) { ocean 'Pacific' } }
|
140
|
+
|
141
|
+
it 'looks up the instance in its Class\'s .instances hash' do
|
142
|
+
expect(array_instance.attr(:test_name).first.ocean).to be == 'Pacific'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when a symbol is not given' do
|
148
|
+
context 'and a block is given' do
|
149
|
+
before { array_instance.attr { ocean 'Atlantic' } }
|
150
|
+
|
151
|
+
it 'creates a new instance of the specified Class' do
|
152
|
+
attr.first.ocean.should == 'Atlantic'
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'generates a name' do
|
156
|
+
attr.first.name.should == :"#{array_instance.name}_#{IncludedClass.to_s}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'and a block is not given' do
|
161
|
+
before { array_instance.attr(:test) { ocean 'Artic' } }
|
162
|
+
|
163
|
+
it 'returns the corresponding instance variable' do
|
164
|
+
array_instance.attr.should == attr
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#ensure_present!' do
|
174
|
+
context 'when at least one of the symbols is nil' do
|
175
|
+
it 'raises an error' do
|
176
|
+
expect { test_instance.send(:ensure_present!, :meta) }.to raise_error
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'when each symbol is present' do
|
181
|
+
it 'does nothing' do
|
182
|
+
expect { test_instance.send(:ensure_present!, :name) }.to_not raise_error
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe '.default_value' do
|
188
|
+
context 'when a block is given' do
|
189
|
+
it 'calls the block and adds it to he default_values hash' do
|
190
|
+
test_class.send(:default_value, :meta) { included_class.new!(:name => :joey) }
|
191
|
+
test_class.default_values[:meta].name.should == :joey
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when a value is given' do
|
196
|
+
it 'adds the pair to the default_values hash' do
|
197
|
+
test_class.send(:default_value, :chips, 'Cool Ranch')
|
198
|
+
test_class.default_values[:chips].should == 'Cool Ranch'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#initialize' do
|
204
|
+
context 'when a block is given' do
|
205
|
+
it 'is instance evaluated' do
|
206
|
+
test_class.new! { name :timmy }.name.should == :timmy
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'when a hash is given' do
|
211
|
+
it 'sends each key value pair to the object as a message' do
|
212
|
+
test_class.new!(:name => :tommy).name.should == :tommy
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'when there is a name' do
|
217
|
+
it 'adds the current instance to the class\'s instances hash' do
|
218
|
+
test_class.instances[:jillian].should be_nil
|
219
|
+
test_class.new! { name :jillian }
|
220
|
+
test_class.instances[:jillian].name.should == :jillian
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dockly-util
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -98,8 +98,8 @@ files:
|
|
98
98
|
- lib/dockly/util/dsl.rb
|
99
99
|
- lib/dockly/util/logger.rb
|
100
100
|
- lib/dockly/util/version.rb
|
101
|
-
- spec/
|
102
|
-
- spec/
|
101
|
+
- spec/dockly/util/dsl_spec.rb
|
102
|
+
- spec/dockly/util/logger_spec.rb
|
103
103
|
- spec/spec_helper.rb
|
104
104
|
homepage: https://github.com/swipely/dockly-util
|
105
105
|
licenses:
|
@@ -127,7 +127,7 @@ signing_key:
|
|
127
127
|
specification_version: 3
|
128
128
|
summary: DSL made easy
|
129
129
|
test_files:
|
130
|
-
- spec/
|
131
|
-
- spec/
|
130
|
+
- spec/dockly/util/dsl_spec.rb
|
131
|
+
- spec/dockly/util/logger_spec.rb
|
132
132
|
- spec/spec_helper.rb
|
133
133
|
has_rdoc:
|
data/spec/dockl/util/dsl_spec.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Dockly::Util::DSL do
|
4
|
-
let(:included_class) do
|
5
|
-
Class.new do
|
6
|
-
include Dockly::Util::DSL
|
7
|
-
|
8
|
-
dsl_attribute :ocean
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:test_class) do
|
13
|
-
klass = included_class
|
14
|
-
Class.new do
|
15
|
-
include Dockly::Util::DSL
|
16
|
-
|
17
|
-
dsl_attribute :chips
|
18
|
-
dsl_class_attribute :meta, klass
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
subject { test_class.new!(:name => 'Tony') }
|
23
|
-
|
24
|
-
describe '.dsl_attribute' do
|
25
|
-
it 'defines a method for each name given' do
|
26
|
-
subject.should respond_to :chips
|
27
|
-
end
|
28
|
-
|
29
|
-
context 'the defined method(s)' do
|
30
|
-
context 'with 0 arguments' do
|
31
|
-
let(:test_val) { 'lays' }
|
32
|
-
before { subject.instance_variable_set(:@chips, test_val) }
|
33
|
-
|
34
|
-
it 'returns the value of the instance variable with a matching name' do
|
35
|
-
subject.chips.should == test_val
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'with one argument' do
|
40
|
-
it 'sets the corresponding instance variable to the passed-in value' do
|
41
|
-
expect { subject.chips('bbq') }
|
42
|
-
.to change { subject.instance_variable_get(:@chips) }
|
43
|
-
.to 'bbq'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '.dsl_class_attribute' do
|
50
|
-
context 'when the sceond argument is not a DSL' do
|
51
|
-
it 'raises an error' do
|
52
|
-
expect do
|
53
|
-
Class.new do
|
54
|
-
include Dockly::Util::DSL
|
55
|
-
|
56
|
-
dsl_class_attribute :test, Array
|
57
|
-
end
|
58
|
-
end.to raise_error
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context 'when the second argument is a DSL' do
|
63
|
-
it 'defines a new method with the name of the first argument' do
|
64
|
-
subject.should respond_to :meta
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'the method' do
|
68
|
-
let(:meta) { subject.instance_variable_get(:@meta) }
|
69
|
-
|
70
|
-
context 'when a symbol is given' do
|
71
|
-
context 'and a block is given' do
|
72
|
-
before { subject.meta(:yolo) { ocean 'Indian' } }
|
73
|
-
|
74
|
-
it 'creates a new instance of the specified Class with the name set' do
|
75
|
-
meta.name.should == :yolo
|
76
|
-
meta.ocean.should == 'Indian'
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'and a block is not given' do
|
81
|
-
before { included_class.new!(:name => :test_name) { ocean 'Pacific' } }
|
82
|
-
|
83
|
-
it 'looks up the instance in its Class\'s .instances hash' do
|
84
|
-
subject.meta(:test_name).ocean.should == 'Pacific'
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
context 'when a symbol is not given' do
|
90
|
-
context 'and a block is given' do
|
91
|
-
before { subject.meta { ocean 'Atlantic' } }
|
92
|
-
|
93
|
-
it 'creates a new instance of the specified Class' do
|
94
|
-
meta.ocean.should == 'Atlantic'
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'generates a name' do
|
98
|
-
meta.name.should == :"#{subject.name}_#{meta.class}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context 'and a block is not given' do
|
103
|
-
before { subject.meta(:test) { ocean 'Artic' } }
|
104
|
-
|
105
|
-
it 'returns the corresponding instance variable' do
|
106
|
-
subject.meta.should == meta
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe '#ensure_present!' do
|
115
|
-
context 'when at least one of the symbols is nil' do
|
116
|
-
it 'raises an error' do
|
117
|
-
expect { subject.send(:ensure_present!, :meta) }.to raise_error
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'when each symbol is present' do
|
122
|
-
it 'does nothing' do
|
123
|
-
expect { subject.send(:ensure_present!, :name) }.to_not raise_error
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
describe '.default_value' do
|
129
|
-
context 'when a block is given' do
|
130
|
-
it 'calls the block and adds it to he default_values hash' do
|
131
|
-
test_class.send(:default_value, :meta) { included_class.new!(:name => :joey) }
|
132
|
-
test_class.default_values[:meta].name.should == :joey
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
context 'when a value is given' do
|
137
|
-
it 'adds the pair to the default_values hash' do
|
138
|
-
test_class.send(:default_value, :chips, 'Cool Ranch')
|
139
|
-
test_class.default_values[:chips].should == 'Cool Ranch'
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe '#initialize' do
|
145
|
-
context 'when a block is given' do
|
146
|
-
it 'is instance evaluated' do
|
147
|
-
test_class.new! { name :timmy }.name.should == :timmy
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
context 'when a hash is given' do
|
152
|
-
it 'sends each key value pair to the object as a message' do
|
153
|
-
test_class.new!(:name => :tommy).name.should == :tommy
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
context 'when there is no name' do
|
158
|
-
it 'raises an error' do
|
159
|
-
expect { test_class.new! { chips 'Tortilla' } }.to raise_error
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
context 'when there is a name' do
|
164
|
-
it 'adds the current instance to the class\'s instances hash' do
|
165
|
-
test_class.instances[:jillian].should be_nil
|
166
|
-
test_class.new! { name :jillian }
|
167
|
-
test_class.instances[:jillian].name.should == :jillian
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|