attributes_dsl 0.0.2 → 0.1.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 +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
|