superstructure 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1dba89c3e4aeda5883b1f0512c3f4e785ad206b0
4
- data.tar.gz: 27d2fbb43f389b2512ca582e9977c11c9daffe1a
3
+ metadata.gz: ee6898266d56d163225dc8e36a560df58c775ad5
4
+ data.tar.gz: 0a54cd4233764e3709894e827a199cb4c6b250a2
5
5
  SHA512:
6
- metadata.gz: 53a23c060e658cf07599f47ce5009d5b73ce88cfaa285d942fc18591e61371c6cd4982bc29f7e3ac387882d0579201b2aad24cb7d119948f412f527edbecad46
7
- data.tar.gz: a99d7e6f99bfce4d57241ed9e7e3a3cf74951f066a50b0234889a477719cde9954889d8aa3a78e12176247553edb207a9001e6658a3087715cbbbbfe0ceadfee
6
+ metadata.gz: 235118a7fc7df08713a74f8e08ff6fd603f574e73ad1e28af21c25cdd449fa85e5d2a38274efc8c12dd8ae7e87ba1e72eace08ef9a604a9503c6c0192be53edf
7
+ data.tar.gz: 820253eeb35ff0c77c0572a9b4132c0c3eb7df7e6e70a6631abb2ebf99823a2834489df12ff3bc06acf5e1f079856228e90ff65516c2601dca782520b9fffbb3
@@ -0,0 +1,27 @@
1
+ module Superstructure
2
+ class ArgumentErrorBuilder
3
+ def initialize
4
+ @errors = {
5
+ extra_params: [],
6
+ missing_params: [],
7
+ shadowed_params: []
8
+ }
9
+ end
10
+
11
+ def add_error(type, key)
12
+ add_errors(type, [key])
13
+ end
14
+
15
+ def add_errors(type, key)
16
+ @errors.fetch(type).concat(key)
17
+ end
18
+
19
+ def build
20
+ ArgumentError.new(@errors)
21
+ end
22
+
23
+ def error?
24
+ @errors.any? { |k, v| v.any? }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,45 @@
1
+ module Superstructure
2
+ class AttributeParser
3
+ attr_reader :attributes
4
+
5
+ def initialize(arguments, opts)
6
+ @attributes = {}
7
+ @possible_error = ArgumentErrorBuilder.new
8
+ @arguments = arguments
9
+ @opts = opts
10
+
11
+ parse!
12
+ end
13
+
14
+ def error?
15
+ @possible_error.error?
16
+ end
17
+
18
+ def error
19
+ @possible_error.build
20
+ end
21
+
22
+ private
23
+
24
+ def parse!
25
+ used_params = []
26
+
27
+ @arguments.each do |argument|
28
+ if @opts.has_key?(argument) && @opts.has_key?(argument.to_s)
29
+ @possible_error.add_error(:shadowed_params, argument)
30
+ used_params << argument << argument.to_s
31
+ elsif @opts.has_key?(argument)
32
+ @attributes[argument] = @opts[argument]
33
+ used_params << argument
34
+ elsif @opts.has_key?(argument.to_s)
35
+ @attributes[argument] = @opts[argument.to_s]
36
+ used_params << argument.to_s
37
+ else
38
+ @possible_error.add_error(:missing_params, argument)
39
+ end
40
+ end
41
+
42
+ @possible_error.add_errors(:extra_params, @opts.keys - used_params)
43
+ end
44
+ end
45
+ end
@@ -4,35 +4,11 @@ module Superstructure
4
4
  def new *arguments, superclass: Object, &blk
5
5
  Class.new(superclass) do
6
6
  define_method(:initialize) do |opts={}|
7
- @attributes = {}
8
- missing_params = []
9
- shadowed_params = []
10
- used_params = []
11
-
12
- arguments.each do |argument|
13
- if opts.has_key?(argument) && opts.has_key?(argument.to_s)
14
- shadowed_params << argument
15
- used_params << argument << argument.to_s
16
-
17
- elsif opts.has_key?(argument)
18
- @attributes[argument] = opts[argument]
19
- used_params << argument
20
- elsif opts.has_key?(argument.to_s)
21
- @attributes[argument] = opts[argument.to_s]
22
- used_params << argument.to_s
23
- else
24
- missing_params << argument
25
- end
26
- end
27
-
28
- extra_params = opts.keys - used_params
29
-
30
- if missing_params.any? || shadowed_params.any? || extra_params.any?
31
- raise ArgumentError.new(
32
- missing_params: missing_params,
33
- shadowed_params: shadowed_params,
34
- extra_params: extra_params
35
- )
7
+ attribute_parser = AttributeParser.new(arguments, opts)
8
+ if attribute_parser.error?
9
+ raise attribute_parser.error
10
+ else
11
+ @attributes = attribute_parser.attributes
36
12
  end
37
13
  end
38
14
 
@@ -44,7 +20,12 @@ module Superstructure
44
20
  opts = @attributes.map do |k, v|
45
21
  "#{k}=#{v.inspect}"
46
22
  end.join(", ")
47
- "#<value_obj #{self.class} #{opts}>"
23
+
24
+ unless opts.empty?
25
+ opts.prepend(" ")
26
+ end
27
+
28
+ "#<value_obj #{self.class}#{opts}>"
48
29
  end
49
30
 
50
31
  def ==(o)
@@ -53,6 +34,10 @@ module Superstructure
53
34
 
54
35
  alias :eql? :==
55
36
 
37
+ def hash
38
+ self.class.hash ^ @attributes.hash
39
+ end
40
+
56
41
  arguments.each do |argument|
57
42
  define_method(argument) do
58
43
  to_hash[argument]
@@ -1,3 +1,3 @@
1
1
  module Superstructure
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -4,3 +4,5 @@ end
4
4
  require "superstructure/version"
5
5
  require "superstructure/value_obj"
6
6
  require "superstructure/argument_error"
7
+ require "superstructure/argument_error_builder"
8
+ require "superstructure/attribute_parser"
@@ -0,0 +1,30 @@
1
+ RSpec.describe Superstructure::ArgumentErrorBuilder do
2
+ let(:builder) { described_class.new }
3
+
4
+ describe "#error?" do
5
+ subject { builder.error? }
6
+
7
+ context "when at least one error has been added" do
8
+ before do
9
+ builder.add_error(:missing_params, :hello)
10
+ end
11
+
12
+ it { should be_truthy }
13
+ end
14
+
15
+ context "when no errors have been added" do
16
+ it { should be_falsy }
17
+ end
18
+ end
19
+
20
+ it "builds an ArgumentError with all of the added errors" do
21
+ builder.add_error(:extra_params, :alpha)
22
+ builder.add_errors(:missing_params, [:beta, :charlie])
23
+
24
+ expect(builder.build).to have_attributes(
25
+ extra_params: [:alpha],
26
+ missing_params: [:beta, :charlie],
27
+ shadowed_params: []
28
+ )
29
+ end
30
+ end
@@ -64,6 +64,12 @@ RSpec.describe Superstructure::ValueObj do
64
64
  foobar = FooBar.new(foo: [:a, :b], bar: 2)
65
65
  expect(foobar.inspect).to eq '#<value_obj FooBar foo=[:a, :b], bar=2>'
66
66
  end
67
+
68
+ context "when there are no attributes" do
69
+ it "omits the attibutes" do
70
+ expect(Empty.new.inspect).to eq "#<value_obj Empty>"
71
+ end
72
+ end
67
73
  end
68
74
 
69
75
  it "can inherit from other classes" do
@@ -94,17 +100,17 @@ RSpec.describe Superstructure::ValueObj do
94
100
  end
95
101
 
96
102
  describe "equality" do
97
- shared_examples_for "equality" do |operator|
103
+ shared_examples_for "equality" do |sameness_proc|
98
104
  it "is equal if all arguments are equal" do
99
105
  alpha = FooBar.new(foo: 1, bar: 2)
100
106
  beta = FooBar.new("foo" => 1, "bar" => 2)
101
- expect(alpha.public_send(operator, beta)).to be_truthy
107
+ expect(sameness_proc.(alpha, beta)).to be_truthy
102
108
  end
103
109
 
104
110
  it "is not equal if any argument doesn't equal" do
105
111
  alpha = FooBar.new(foo: 1, bar: 2000)
106
112
  beta = FooBar.new("foo" => 1, "bar" => 2)
107
- expect(alpha.public_send(operator, beta)).to be_falsey
113
+ expect(sameness_proc.(alpha, beta)).to be_falsey
108
114
  end
109
115
 
110
116
  it "is equal only to other instances of the same class" do
@@ -114,16 +120,20 @@ RSpec.describe Superstructure::ValueObj do
114
120
  foobar = FooBar.new(opts)
115
121
  barfoo = klass.new(opts)
116
122
 
117
- expect(foobar.public_send(operator, barfoo)).to be_falsey
123
+ expect(sameness_proc.(foobar, barfoo)).to be_falsey
118
124
  end
119
125
  end
120
126
 
121
127
  describe "==" do
122
- it_behaves_like "equality", :==
128
+ it_behaves_like "equality", proc { |a, b| a == b }
123
129
  end
124
130
 
125
131
  describe "eql?" do
126
- it_behaves_like "equality", :eql?
132
+ it_behaves_like "equality", proc { |a, b| a.eql? b }
133
+ end
134
+
135
+ describe "hash" do
136
+ it_behaves_like "equality", proc { |a, b| a.hash == b.hash }
127
137
  end
128
138
  end
129
139
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superstructure
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Finnie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-15 00:00:00.000000000 Z
11
+ date: 2018-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,8 +67,11 @@ files:
67
67
  - Rakefile
68
68
  - lib/superstructure.rb
69
69
  - lib/superstructure/argument_error.rb
70
+ - lib/superstructure/argument_error_builder.rb
71
+ - lib/superstructure/attribute_parser.rb
70
72
  - lib/superstructure/value_obj.rb
71
73
  - lib/superstructure/version.rb
74
+ - spec/argument_error_builder_spec.rb
72
75
  - spec/argument_error_spec.rb
73
76
  - spec/spec_helper.rb
74
77
  - spec/value_obj_spec.rb
@@ -93,12 +96,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
96
  version: '0'
94
97
  requirements: []
95
98
  rubyforge_project:
96
- rubygems_version: 2.0.14
99
+ rubygems_version: 2.5.2
97
100
  signing_key:
98
101
  specification_version: 4
99
102
  summary: Immutable, keyword-argument based value objects for Ruby
100
103
  test_files:
104
+ - spec/argument_error_builder_spec.rb
101
105
  - spec/argument_error_spec.rb
102
106
  - spec/spec_helper.rb
103
107
  - spec/value_obj_spec.rb
104
- has_rdoc: