attributes_dsl 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -4
- data/CHANGELOG.md +23 -0
- data/README.md +29 -55
- data/attributes_dsl.gemspec +6 -7
- data/benchmark/run.rb +4 -4
- data/lib/attributes_dsl.rb +11 -24
- data/lib/attributes_dsl/attribute.rb +49 -34
- data/lib/attributes_dsl/attributes.rb +34 -34
- data/lib/attributes_dsl/transprocs.rb +141 -0
- data/lib/attributes_dsl/version.rb +1 -1
- data/spec/integration/blacklisted_attribute_spec.rb +49 -0
- data/spec/integration/coerced_attribute_spec.rb +27 -0
- data/spec/integration/default_attribute_spec.rb +20 -0
- data/spec/integration/required_attribute_spec.rb +17 -0
- data/spec/integration/simple_attribute_spec.rb +29 -0
- data/spec/integration/unknown_attribute_spec.rb +10 -0
- data/spec/integration/unreadable_attribute_spec.rb +18 -0
- data/spec/integration/whitelisted_attribute_spec.rb +49 -0
- data/spec/spec_helper.rb +3 -0
- metadata +40 -27
- data/spec/integration/attributes_dsl_spec.rb +0 -76
- data/spec/unit/attribute_spec.rb +0 -126
- data/spec/unit/attributes_spec.rb +0 -82
@@ -1,76 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe AttributesDSL do
|
4
|
-
|
5
|
-
let(:coercer) { -> value { value.to_s } }
|
6
|
-
let(:klass) { Class.new { extend AttributesDSL } }
|
7
|
-
|
8
|
-
before do
|
9
|
-
klass.attribute(:foo, &:to_s)
|
10
|
-
klass.attribute("bar")
|
11
|
-
klass.attribute(:baz, &:to_i)
|
12
|
-
end
|
13
|
-
|
14
|
-
subject { klass.new(arguments) }
|
15
|
-
|
16
|
-
describe "instance" do
|
17
|
-
|
18
|
-
context "without arguments" do
|
19
|
-
subject { klass.new }
|
20
|
-
|
21
|
-
it "initializes default attributes" do
|
22
|
-
expect(subject.attributes).to eql(foo: "", bar: nil, baz: 0)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context "when all required attributes are set" do
|
27
|
-
let(:arguments) { { bar: :BAR, baz: "42" } }
|
28
|
-
let(:klass) do
|
29
|
-
Class.new do
|
30
|
-
extend AttributesDSL
|
31
|
-
|
32
|
-
def initialize(attributes = {})
|
33
|
-
super
|
34
|
-
IceNine.deep_freeze(self)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it "initializes attributes" do
|
40
|
-
expect(subject.attributes).to eql(foo: "", bar: :BAR, baz: 42)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "defines methods for every attribute" do
|
44
|
-
expect(subject.foo).to eql ""
|
45
|
-
expect(subject.bar).to eql :BAR
|
46
|
-
expect(subject.baz).to eql 42
|
47
|
-
end
|
48
|
-
|
49
|
-
it "doesn't freeze argument" do
|
50
|
-
expect { subject }.not_to change { arguments.frozen? }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
context "when a required attribute is missed" do
|
55
|
-
let(:arguments) { { foo: :FOO, baz: "42" } }
|
56
|
-
|
57
|
-
before { klass.attribute("bar", required: true) }
|
58
|
-
|
59
|
-
it "fails" do
|
60
|
-
expect { subject }.to raise_error ArgumentError
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
end # describe instance
|
65
|
-
|
66
|
-
describe "subclass" do
|
67
|
-
|
68
|
-
subject { Class.new(klass) }
|
69
|
-
|
70
|
-
it "inherits parent attributes" do
|
71
|
-
expect(subject.new.attributes).to eql(klass.new.attributes)
|
72
|
-
end
|
73
|
-
|
74
|
-
end # describe subclass
|
75
|
-
|
76
|
-
end # describe AttributesDSL
|
data/spec/unit/attribute_spec.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe AttributesDSL::Attribute do
|
4
|
-
|
5
|
-
let(:attribute) do
|
6
|
-
described_class.new(name, default: default, required: required, &coercer)
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:name) { :foo }
|
10
|
-
let(:default) { "FOO" }
|
11
|
-
let(:required) { true }
|
12
|
-
let(:coercer) { -> v { v.to_s } }
|
13
|
-
|
14
|
-
describe ".new" do
|
15
|
-
subject { attribute }
|
16
|
-
|
17
|
-
it { is_expected.to be_frozen }
|
18
|
-
end # describe .new
|
19
|
-
|
20
|
-
describe "#name" do
|
21
|
-
subject { attribute.name }
|
22
|
-
|
23
|
-
it { is_expected.to eql name.to_sym }
|
24
|
-
end # describe #name
|
25
|
-
|
26
|
-
describe "#default" do
|
27
|
-
subject { attribute.default }
|
28
|
-
|
29
|
-
context "when value is given" do
|
30
|
-
it { is_expected.to eql default }
|
31
|
-
end
|
32
|
-
|
33
|
-
context "when value isn't set" do
|
34
|
-
let(:attribute) { described_class.new name }
|
35
|
-
|
36
|
-
it { is_expected.to be_nil }
|
37
|
-
end
|
38
|
-
end # describe #default
|
39
|
-
|
40
|
-
describe "#required" do
|
41
|
-
subject { attribute.required }
|
42
|
-
|
43
|
-
context "when set to true without default value" do
|
44
|
-
let(:attribute) { described_class.new name, required: true }
|
45
|
-
|
46
|
-
it { is_expected.to eql true }
|
47
|
-
end
|
48
|
-
|
49
|
-
context "when set to true with default value" do
|
50
|
-
let(:attribute) { described_class.new name, required: true, default: 1 }
|
51
|
-
|
52
|
-
it { is_expected.to eql false }
|
53
|
-
end
|
54
|
-
|
55
|
-
context "when value isn't set" do
|
56
|
-
let(:attribute) { described_class.new name }
|
57
|
-
|
58
|
-
it { is_expected.to eql false }
|
59
|
-
end
|
60
|
-
end # describe #required
|
61
|
-
|
62
|
-
describe "#coercer" do
|
63
|
-
subject { attribute.coercer }
|
64
|
-
|
65
|
-
context "when block is given" do
|
66
|
-
it { is_expected.to eql coercer }
|
67
|
-
end
|
68
|
-
|
69
|
-
context "when block isn't given" do
|
70
|
-
let(:attribute) { described_class.new name }
|
71
|
-
|
72
|
-
it { is_expected.to be_nil }
|
73
|
-
end
|
74
|
-
end # describe #coercer
|
75
|
-
|
76
|
-
describe "#value" do
|
77
|
-
subject { attribute.value(1) }
|
78
|
-
|
79
|
-
context "when coercer is given" do
|
80
|
-
it "uses the coercer" do
|
81
|
-
expect(subject).to eql "1"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
context "when coercer isn't given" do
|
86
|
-
let(:attribute) { described_class.new name }
|
87
|
-
|
88
|
-
it "returns the input" do
|
89
|
-
expect(subject).to eql 1
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end # describe #value
|
93
|
-
|
94
|
-
describe "#==" do
|
95
|
-
subject { attribute == other }
|
96
|
-
|
97
|
-
context "with the same name" do
|
98
|
-
let(:other) { described_class.new name }
|
99
|
-
|
100
|
-
it { is_expected.to eql true }
|
101
|
-
end
|
102
|
-
|
103
|
-
context "with another name" do
|
104
|
-
let(:other) { described_class.new :bar }
|
105
|
-
|
106
|
-
it { is_expected.to eql false }
|
107
|
-
end
|
108
|
-
end # describe #==
|
109
|
-
|
110
|
-
describe "#eql?" do
|
111
|
-
subject { attribute.eql? other }
|
112
|
-
|
113
|
-
context "with the same name" do
|
114
|
-
let(:other) { described_class.new name }
|
115
|
-
|
116
|
-
it { is_expected.to eql true }
|
117
|
-
end
|
118
|
-
|
119
|
-
context "with another name" do
|
120
|
-
let(:other) { described_class.new :bar }
|
121
|
-
|
122
|
-
it { is_expected.to eql false }
|
123
|
-
end
|
124
|
-
end # describe #eql?
|
125
|
-
|
126
|
-
end # describe AttributesDSL::Attribute
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
describe AttributesDSL::Attributes do
|
4
|
-
|
5
|
-
let(:attributes) { described_class.new }
|
6
|
-
let(:coercer) { -> value { value.to_s } }
|
7
|
-
|
8
|
-
describe ".new" do
|
9
|
-
subject { attributes }
|
10
|
-
|
11
|
-
it { is_expected.to be_frozen }
|
12
|
-
end # describe .new
|
13
|
-
|
14
|
-
describe "#attributes" do
|
15
|
-
subject { attributes.attributes }
|
16
|
-
|
17
|
-
it { is_expected.to be_kind_of Hash }
|
18
|
-
it { is_expected.to be_empty }
|
19
|
-
end # describe #attributes
|
20
|
-
|
21
|
-
describe "#register" do
|
22
|
-
subject do
|
23
|
-
attributes.register(:bar).register(:foo, default: :FOO, &coercer)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "returns new collection" do
|
27
|
-
expect(subject).to be_kind_of described_class
|
28
|
-
end
|
29
|
-
|
30
|
-
it "adds attributes" do
|
31
|
-
expect(subject.attributes.keys).to contain_exactly(:bar, :foo)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "uses arguments" do
|
35
|
-
attribute = subject.attributes[:foo]
|
36
|
-
|
37
|
-
expect(attribute).to be_kind_of AttributesDSL::Attribute
|
38
|
-
expect(attribute.name).to eql :foo
|
39
|
-
expect(attribute.default).to eql :FOO
|
40
|
-
expect(attribute.coercer).to eql coercer
|
41
|
-
end
|
42
|
-
|
43
|
-
context "without options" do
|
44
|
-
subject { attributes.register :foo }
|
45
|
-
|
46
|
-
it { is_expected.to be_kind_of described_class }
|
47
|
-
end
|
48
|
-
end # describe #register
|
49
|
-
|
50
|
-
describe "#extract" do
|
51
|
-
subject { attributes.extract hash }
|
52
|
-
|
53
|
-
let(:hash) { { bar: :BAR } }
|
54
|
-
let(:attributes) do
|
55
|
-
described_class
|
56
|
-
.new
|
57
|
-
.register(:foo, required: true, &coercer)
|
58
|
-
.register(:bar, required: true)
|
59
|
-
.register(:baz, default: :BAZ, &coercer)
|
60
|
-
end
|
61
|
-
|
62
|
-
context "when all required attributes are present" do
|
63
|
-
let(:hash) { { foo: :FOO, bar: :BAR, qux: :QUX } }
|
64
|
-
|
65
|
-
it "returns a proper hash" do
|
66
|
-
expect(subject).to eql(foo: "FOO", bar: :BAR, baz: "BAZ")
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context "when a required attribute is absent" do
|
71
|
-
let(:hash) { { baz: :BAZ } }
|
72
|
-
|
73
|
-
it "fails" do
|
74
|
-
expect { subject }.to raise_error do |error|
|
75
|
-
expect(error).to be_kind_of ArgumentError
|
76
|
-
expect(error.message).to eql "Undefined attributes: foo, bar"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end # describe #extract
|
81
|
-
|
82
|
-
end # describe AttributeDSL::Attributes
|