anima 0.0.7 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6829c500ad676f1d8e6c000f33ee32a25be03c0
4
- data.tar.gz: 7ae912dbe9f69ead50c7944dd2be42320eff08ac
3
+ metadata.gz: 8829390b1d9de51fddff518775263b3d349298bc
4
+ data.tar.gz: b7cfafb8c2c03195da23c1cfe3a26be3d20c93fb
5
5
  SHA512:
6
- metadata.gz: cd64e6435697e60ae07fdc3c1de8e5d26b432725b32748a22c106e9101682c2770261ffb284c33ff704bc15823487694c2dc97c63ca7e74e4668d1ceac801bba
7
- data.tar.gz: f343a273dd4e96cbeed7e48843aa1bf753b79719ce2a279e49b3a4d3b5ccf6a3dc11cc3f9b059801946264bfef4265577eb4c6f5130a76bd7fbd2ae57d5724c5
6
+ metadata.gz: 9ef1d565f8abe13a9914af0439b2bae68a3350819b240a1dbedf565d50a5c1639696282b676db17ede25d8d82a82aa2355fe7ad2584fbcdd502ee0cddc602769
7
+ data.tar.gz: cef667e63a0f638bd8ed31474fce8dde15df03922b1f3d069a4829b328a795e5d906267e09ca1c999cc675084beb77deb556412d784c485d865820cb141e435a
@@ -1,9 +1,8 @@
1
1
  language: ruby
2
2
  script: 'bundle exec rake ci'
3
3
  rvm:
4
- - 1.9.2
4
+ - 1.9.3
5
5
  - 2.0.0
6
- - ruby-head
7
6
  - jruby-19mode
8
7
  - jruby-head
9
8
  - rbx-19mode
data/Gemfile CHANGED
@@ -2,5 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'devtools', :git => 'https://github.com/rom-rb/devtools.git'
5
+ gem 'devtools', git: 'https://github.com/rom-rb/devtools.git'
6
6
  eval File.read('Gemfile.devtools')
data/README.md CHANGED
@@ -5,21 +5,74 @@ anima
5
5
  [![Dependency Status](https://gemnasium.com/mbj/anima.png)](https://gemnasium.com/mbj/anima)
6
6
  [![Code Climate](https://codeclimate.com/github/mbj/anima.png)](https://codeclimate.com/github/mbj/anima)
7
7
 
8
- Simple library to declare read only attributes on objects that are initializable via attributes hash.
8
+ Simple library to declare read only attributes on value-objects that are initialized via attributes hash.
9
9
 
10
10
  Installation
11
11
  ------------
12
12
 
13
- There is no gem release and the code is under development and unusable.
13
+ Install the gem `anima` via your preferred method.
14
14
 
15
15
  Examples
16
16
  --------
17
17
 
18
- See specs.
18
+ ```
19
+ # Definition
20
+ class Person
21
+ include Anima.new(:salutation, :firstname, :lastname)
22
+ end
23
+
24
+ # Every day operation
25
+ a = Person.new(
26
+ :salutation => 'Mr',
27
+ :firstname => 'Markus',
28
+ :lastname => 'Schirp'
29
+ )
30
+
31
+ a.salutation # => "Mr"
32
+ a.firstname # => "Markus"
33
+ a.lastname # => "Schirp"
34
+ a.frozen? # => true
35
+
36
+ b = Person.new(
37
+ :salutation => 'Mr',
38
+ :firstname => 'John',
39
+ :lastname => 'Doe'
40
+ )
41
+
42
+ a = Person.new(
43
+ :salutation => 'Mr',
44
+ :firstname => 'Markus',
45
+ :lastname => 'Schirp'
46
+ )
47
+
48
+ a == b # => false
49
+ a.eql?(b) # => false
50
+ a.equal?(b) # => false
51
+
52
+ a == c # => true
53
+ a.eql?(c) # => true
54
+ a.equal?(c) # => false
55
+
56
+ # Functional updates
57
+ class Person
58
+ include Anima::Update
59
+ end
60
+
61
+ d = b.update(
62
+ :salutation => 'Mrs',
63
+ :firstname => 'Sue',
64
+ )
65
+
66
+ # It returns copies, no inplace modification
67
+ d.equal?(b) # => false
68
+
69
+ ```
19
70
 
20
71
  Credits
21
72
  -------
22
73
 
74
+ * Markus Schirp <mbj@schirp-dso.com>
75
+
23
76
  Contributing
24
77
  -------------
25
78
 
@@ -34,7 +87,7 @@ Contributing
34
87
  License
35
88
  -------
36
89
 
37
- Copyright (c) 2012 Markus Schirp
90
+ Copyright (c) 2013 Markus Schirp
38
91
 
39
92
  Permission is hereby granted, free of charge, to any person obtaining
40
93
  a copy of this software and associated documentation files (the
@@ -2,12 +2,13 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'anima'
5
- s.version = '0.0.7'
5
+ s.version = '0.1.0'
6
6
 
7
7
  s.authors = ['Markus Schirp']
8
8
  s.email = 'mbj@schirp-dso.com'
9
9
  s.summary = 'Attributes for Plain Old Ruby Objects Experiment'
10
10
  s.homepage = 'http://github.com/mbj/anima'
11
+ s.license = 'MIT'
11
12
 
12
13
  s.files = `git ls-files`.split("\n")
13
14
  s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 7
3
- total_score: 29
3
+ total_score: 41
@@ -8,7 +8,7 @@ UncommunicativeParameterName:
8
8
  - !ruby/regexp /[0-9]$/
9
9
  - !ruby/regexp /[A-Z]/
10
10
  TooManyMethods:
11
- max_methods: 10
11
+ max_methods: 13
12
12
  exclude: []
13
13
  enabled: true
14
14
  max_instance_variables: 2
@@ -0,0 +1,85 @@
1
+ AllCops:
2
+ Includes:
3
+ - '../**/*.rake'
4
+ - 'Gemfile'
5
+ - 'Gemfile.devtools'
6
+ - 'mutant.gemspec'
7
+ Excludes:
8
+ - '**/vendor/**'
9
+ - '**/benchmarks/**'
10
+
11
+ # Avoid parameter lists longer than five parameters.
12
+ ParameterLists:
13
+ Max: 3
14
+ CountKeywordArgs: true
15
+
16
+ # Avoid more than `Max` levels of nesting.
17
+ BlockNesting:
18
+ Max: 3
19
+
20
+ # Align with the style guide.
21
+ CollectionMethods:
22
+ PreferredMethods:
23
+ collect: 'map'
24
+ inject: 'reduce'
25
+ find: 'detect'
26
+ find_all: 'select'
27
+
28
+ # Do not force public/protected/private keyword to be indented at the same
29
+ # level as the def keyword. My personal preference is to outdent these keywords
30
+ # because I think when scanning code it makes it easier to identify the
31
+ # sections of code and visually separate them. When the keyword is at the same
32
+ # level I think it sort of blends in with the def keywords and makes it harder
33
+ # to scan the code and see where the sections are.
34
+ AccessControl:
35
+ Enabled: false
36
+
37
+ MethodLength:
38
+ CountComments: false
39
+ Max: 17 # TODO: Bring down to 10
40
+
41
+ RegexpLiteral: # I do not agree %r(\A) is more readable than /\A/
42
+ Enabled: false
43
+
44
+ Eval:
45
+ Enabled: false # Mutant must use Kernel#eval to inject mutated source
46
+
47
+ # Limit line length
48
+ LineLength:
49
+ Max: 124 # TODO: lower to 79
50
+
51
+ # Disable documentation checking until a class needs to be documented once
52
+ Documentation:
53
+ Enabled: false
54
+
55
+ # Do not favor modifier if/unless usage when you have a single-line body
56
+ IfUnlessModifier:
57
+ Enabled: false
58
+
59
+ # Mutant needs to define methods like def bar; end in specs
60
+ Semicolon:
61
+ Enabled: false
62
+
63
+ # Mutant needs to define multiple methods on same line in specs
64
+ EmptyLineBetweenDefs:
65
+ Enabled: false
66
+
67
+ # Mutant needs to define singleton methods like Foo.bar in specs
68
+ ClassMethods:
69
+ Enabled: false
70
+
71
+ # Allow case equality operator (in limited use within the specs)
72
+ CaseEquality:
73
+ Enabled: false
74
+
75
+ # Constants do not always have to use SCREAMING_SNAKE_CASE
76
+ ConstantName:
77
+ Enabled: false
78
+
79
+ # Not all trivial readers/writers can be defined with attr_* methods
80
+ TrivialAccessors:
81
+ Enabled: false
82
+
83
+ # And also have a differend opinion here
84
+ AndOr:
85
+ Enabled: false
@@ -5,7 +5,7 @@ require 'abstract_type'
5
5
 
6
6
  # Main library namespace and mixin
7
7
  class Anima < Module
8
- include Adamantium::Flat #, Equalizer.new(:attributes)
8
+ include Adamantium::Flat, Equalizer.new(:attributes)
9
9
 
10
10
  # Return names
11
11
  #
@@ -22,7 +22,35 @@ class Anima < Module
22
22
  # @api private
23
23
  #
24
24
  def initialize(*names)
25
- @attributes = names.map { |name| Attribute.new(name) }.freeze
25
+ @attributes = names.uniq.map { |name| Attribute.new(name) }.freeze
26
+ end
27
+
28
+ # Return new anima with attributes removed
29
+ #
30
+ # @return [Anima]
31
+ #
32
+ # @example
33
+ # anima = Anima.new(:foo)
34
+ # anima.add(:foo) # equals Anima.new(:foo, :bar)
35
+ #
36
+ # @api public
37
+ #
38
+ def remove(*names)
39
+ new(attribute_names - names)
40
+ end
41
+
42
+ # Return new anima with attributes added
43
+ #
44
+ # @return [Anima]
45
+ #
46
+ # @example
47
+ # anima = Anima.new(:foo, :bar)
48
+ # anima.remove(:bar) # equals Anima.new(:foo)
49
+ #
50
+ # @api private
51
+ #
52
+ def add(*names)
53
+ new(attribute_names + names)
26
54
  end
27
55
 
28
56
  # Return attributes hash for instance
@@ -92,6 +120,18 @@ private
92
120
  define_equalizer(scope)
93
121
  end
94
122
 
123
+ # Return new instance
124
+ #
125
+ # @param [Enumerable<Symbol>] attributes
126
+ #
127
+ # @return [Anima]
128
+ #
129
+ # @api private
130
+ #
131
+ def new(attributes)
132
+ self.class.new(*attributes)
133
+ end
134
+
95
135
  # Define anima method on scope
96
136
  #
97
137
  # @param [Class, Module] scope
@@ -4,6 +4,16 @@ class Anima
4
4
  class Attribute
5
5
  include Adamantium::Flat, Equalizer.new(:name)
6
6
 
7
+ # Initialize attribute
8
+ #
9
+ # @param [Symbol] name
10
+ #
11
+ # @api private
12
+ #
13
+ def initialize(name)
14
+ @name = name
15
+ end
16
+
7
17
  # Return attribute name
8
18
  #
9
19
  # @return [Symbol]
@@ -11,7 +21,7 @@ class Anima
11
21
  # @api private
12
22
  #
13
23
  attr_reader :name
14
-
24
+
15
25
  # Load attribute
16
26
  #
17
27
  # @param [Object] object
@@ -24,7 +34,7 @@ class Anima
24
34
  def load(object, attributes)
25
35
  attribute_name = name
26
36
 
27
- value = attributes.fetch(attribute_name) do
37
+ value = attributes.fetch(attribute_name) do
28
38
  raise Error::Missing.new(object.class, attribute_name)
29
39
  end
30
40
 
@@ -35,7 +45,7 @@ class Anima
35
45
  #
36
46
  # @param [Object] object
37
47
  #
38
- # @return [Object]
48
+ # @return [Object]
39
49
  #
40
50
  # @api private
41
51
  #
@@ -83,17 +93,5 @@ class Anima
83
93
  self
84
94
  end
85
95
 
86
- private
87
-
88
-
89
- # Initialize attribute
90
- #
91
- # @param [Symbol] name
92
- #
93
- # @api private
94
- #
95
- def initialize(name)
96
- @name = name
97
- end
98
- end
99
- end
96
+ end # Attribute
97
+ end # Anima
@@ -5,14 +5,14 @@ class Anima
5
5
  # Return updated instance
6
6
  #
7
7
  # @example
8
- # klass = Class.new do
8
+ # klass = Class.new do
9
9
  # include Anima.new(:foo, :bar), Anima::Update
10
10
  # end
11
11
  #
12
12
  # foo = klass.new(:foo => 1, :bar => 2)
13
13
  # updated = foo.update(:foo => 3)
14
- # updated.foo # => 3
15
- # updated.bar # => 2
14
+ # updated.foo # => 3
15
+ # updated.bar # => 2
16
16
  #
17
17
  # @param [Hash] attributes
18
18
  #
@@ -16,8 +16,8 @@ describe Anima, 'simple integration' do
16
16
  context 'when instanciated with all attributes' do
17
17
  let(:attributes) do
18
18
  {
19
- :firstname => 'Markus',
20
- :lastname => 'Schirp'
19
+ firstname: 'Markus',
20
+ lastname: 'Schirp'
21
21
  }
22
22
  end
23
23
 
@@ -26,17 +26,17 @@ describe Anima, 'simple integration' do
26
26
  end
27
27
 
28
28
  context 'with instanciated with extra attributes' do
29
- let(:attributes) do
29
+ let(:attributes) do
30
30
  {
31
- :firstname => 'Markus',
32
- :lastname => 'Schirp',
33
- :extra => 'Foo'
31
+ firstname: 'Markus',
32
+ lastname: 'Schirp',
33
+ extra: 'Foo'
34
34
  }
35
35
  end
36
36
 
37
37
  it 'should raise error' do
38
38
  expect { subject }.to raise_error(
39
- Anima::Error::Unknown,
39
+ Anima::Error::Unknown,
40
40
  'Unknown attribute(s) [:extra] for TestClass'
41
41
  )
42
42
  end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe Anima::Attribute do
4
+ let(:object) { described_class.new(:foo) }
5
+
6
+ describe '#define_reader' do
7
+ subject { object.define_reader(target_class) }
8
+
9
+ let(:target_class) do
10
+ Class.new do
11
+ def initialize(foo)
12
+ @foo = foo
13
+ end
14
+ end
15
+ end
16
+
17
+ let(:value) { double('Value') }
18
+
19
+ it 'should create a reader' do
20
+ instance = target_class.new(value)
21
+ -> { subject }.should change { instance.respond_to?(:foo) }.from(false).to(true)
22
+ end
23
+
24
+ it_should_behave_like 'a command method'
25
+ end
26
+
27
+ describe '#get' do
28
+ subject { object.get(target) }
29
+
30
+ let(:target_class) do
31
+ Class.new do
32
+ attr_reader :foo
33
+
34
+ def initialize(foo)
35
+ @foo = foo
36
+ end
37
+ end
38
+ end
39
+
40
+ let(:target) { target_class.new(value) }
41
+ let(:value) { double('Value') }
42
+
43
+ it 'should return value' do
44
+ should be(value)
45
+ end
46
+ end
47
+
48
+ describe '#instance_variable_name' do
49
+ subject { Anima::Attribute.new(:foo).instance_variable_name }
50
+
51
+ it { should be(:@foo) }
52
+
53
+ it_should_behave_like 'an idempotent method'
54
+ end
55
+
56
+ describe '#load' do
57
+ subject { object.load(target, attribute_hash) }
58
+
59
+ let(:target) { Object.new }
60
+
61
+ let(:value) { double('Value') }
62
+
63
+ context 'when attribute hash contains key' do
64
+ let(:attribute_hash) { { foo: value } }
65
+
66
+ it 'should set value as instance variable' do
67
+ subject
68
+ target.instance_variable_get(:@foo).should be(value)
69
+ end
70
+
71
+ it_should_behave_like 'a command method'
72
+
73
+ end
74
+
75
+ context 'when attribute hash does not contain key' do
76
+ let(:attribute_hash) { {} }
77
+
78
+ it 'should raise error' do
79
+ expect { subject }.to raise_error(Anima::Error::Missing, Anima::Error::Missing.new(target.class, :foo).message)
80
+ end
81
+ end
82
+ end
83
+
84
+ describe '#set' do
85
+ subject { object.set(target, value) }
86
+
87
+ let(:target) { Object.new }
88
+
89
+ let(:value) { double('Value') }
90
+
91
+ it_should_behave_like 'a command method'
92
+
93
+ it 'should set value as instance variable' do
94
+ subject
95
+ target.instance_variable_get(:@foo).should be(value)
96
+ end
97
+ end
98
+ end
@@ -5,7 +5,7 @@ describe Anima::Error, '#message' do
5
5
 
6
6
  subject { object.message }
7
7
 
8
- let(:klass) { double(:name => 'THE-CLASS-NAME') }
8
+ let(:klass) { double(name: 'THE-CLASS-NAME') }
9
9
  let(:name) { 'THE-ATTRIBUTE-NAME' }
10
10
 
11
11
  it 'should return the message string' do
@@ -3,10 +3,10 @@ require 'spec_helper'
3
3
  describe Anima::Update, '#update' do
4
4
  subject { object.update(attributes) }
5
5
 
6
- let(:object) { class_under_test.new(:foo => 1, :bar => 2) }
6
+ let(:object) { class_under_test.new(foo: 1, bar: 2) }
7
7
 
8
8
  let(:class_under_test) do
9
- Class.new do
9
+ Class.new do
10
10
  include Anima.new(:foo, :bar), Anima::Update
11
11
  end
12
12
  end
@@ -18,8 +18,8 @@ describe Anima::Update, '#update' do
18
18
  end
19
19
 
20
20
  context 'with updated attribute' do
21
- let(:attributes) { {:foo => 3} }
21
+ let(:attributes) { { foo: 3 } }
22
22
 
23
- it { should eql(class_under_test.new(:foo => 3, :bar => 2)) }
23
+ it { should eql(class_under_test.new(foo: 3, bar: 2)) }
24
24
  end
25
25
  end
@@ -0,0 +1,134 @@
1
+ require 'spec_helper'
2
+
3
+ describe Anima do
4
+
5
+ let(:object) { described_class.new(:foo) }
6
+
7
+ describe '#attributes_hash' do
8
+
9
+ let(:value) { double('Value') }
10
+
11
+ let(:instance) { double(foo: value) }
12
+
13
+ subject { object.attributes_hash(instance) }
14
+
15
+ it { should eql(foo: value) }
16
+ end
17
+
18
+ describe '#remove' do
19
+ let(:object) { described_class.new(:foo, :bar) }
20
+
21
+ context 'with single attribute' do
22
+ subject { object.remove(:bar) }
23
+ it { should eql(described_class.new(:foo)) }
24
+ end
25
+
26
+ context 'with multiple attributes' do
27
+ subject { object.remove(:foo, :bar) }
28
+ it { should eql(described_class.new) }
29
+ end
30
+
31
+ context 'with inexisting attribute' do
32
+ subject { object.remove(:baz) }
33
+
34
+ it { should eql(object) }
35
+ end
36
+ end
37
+
38
+ describe '#add' do
39
+ context 'with single attribute' do
40
+ subject { object.add(:bar) }
41
+ it { should eql(described_class.new(:foo, :bar)) }
42
+ end
43
+
44
+ context 'with multiple attributes' do
45
+ subject { object.add(:bar, :baz) }
46
+ it { should eql(described_class.new(:foo, :bar, :baz)) }
47
+ end
48
+
49
+ context 'with duplicate attribute ' do
50
+ subject { object.add(:foo) }
51
+ it { should eql(object) }
52
+ end
53
+ end
54
+
55
+ describe '#attributes' do
56
+ subject { object.attributes }
57
+
58
+ it { should eql([Anima::Attribute.new(:foo)]) }
59
+ it { should be_frozen }
60
+ end
61
+
62
+ describe '#included' do
63
+ let(:target) do
64
+ object = self.object
65
+ Class.new do
66
+ include object
67
+ end
68
+ end
69
+
70
+ let(:value) { double('Value') }
71
+
72
+ let(:instance) { target.new(foo: value) }
73
+ let(:instance_b) { target.new(foo: value) }
74
+ let(:instance_c) { target.new(foo: double('Bar')) }
75
+
76
+ context 'on instance' do
77
+ subject { instance }
78
+
79
+ its(:foo) { should be(value) }
80
+
81
+ it { should eql(instance_b) }
82
+ end
83
+
84
+ context 'on singleton' do
85
+ subject { target }
86
+
87
+ it 'should define attribute hash reader' do
88
+ target.attributes_hash(instance).should eql(foo: value)
89
+ end
90
+
91
+ its(:anima) { should be(object) }
92
+ end
93
+ end
94
+
95
+ describe '#initialize_instance' do
96
+ let(:object) { Anima.new(:foo, :bar) }
97
+
98
+ let(:target) { Object.new }
99
+
100
+ let(:foo) { double('Foo') }
101
+ let(:bar) { double('Bar') }
102
+
103
+ subject { object.initialize_instance(target, attribute_hash) }
104
+
105
+ context 'when all keys are present in attribute hash' do
106
+ let(:attribute_hash) { { foo: foo, bar: bar } }
107
+
108
+ it 'should initialize target instance variables' do
109
+ subject
110
+ target.instance_variables.map(&:to_sym).to_set.should eql([:@foo, :@bar].to_set)
111
+ target.instance_variable_get(:@foo).should be(foo)
112
+ target.instance_variable_get(:@bar).should be(bar)
113
+ end
114
+
115
+ it_should_behave_like 'a command method'
116
+ end
117
+
118
+ context 'when extra key is missing in attribute hash' do
119
+ let(:attribute_hash) { { foo: foo, bar: bar, baz: double('Baz') } }
120
+
121
+ it 'should raise error' do
122
+ expect { subject }.to raise_error(Anima::Error::Unknown, Anima::Error::Unknown.new(target.class, [:baz]).message)
123
+ end
124
+ end
125
+
126
+ context 'when a key is missing in attribute hash' do
127
+ let(:attribute_hash) { { bar: bar } }
128
+
129
+ it 'should raise error' do
130
+ expect { subject }.to raise_error(Anima::Error::Missing, Anima::Error::Missing.new(target.class, :foo).message)
131
+ end
132
+ end
133
+ end
134
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anima
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-22 00:00:00.000000000 Z
11
+ date: 2013-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: adamantium
@@ -75,6 +75,7 @@ files:
75
75
  - config/mutant.yml
76
76
  - config/reek.yml
77
77
  - config/roodi.yml
78
+ - config/rubocop.yml
78
79
  - config/yardstick.yml
79
80
  - lib/anima.rb
80
81
  - lib/anima/attribute.rb
@@ -82,19 +83,13 @@ files:
82
83
  - lib/anima/update.rb
83
84
  - spec/integration/simple_spec.rb
84
85
  - spec/spec_helper.rb
85
- - spec/unit/anima/attribute/define_reader_spec.rb
86
- - spec/unit/anima/attribute/get_spec.rb
87
- - spec/unit/anima/attribute/instance_variable_name_spec.rb
88
- - spec/unit/anima/attribute/load_spec.rb
89
- - spec/unit/anima/attribute/set_spec.rb
90
- - spec/unit/anima/attributes_hash_spec.rb
91
- - spec/unit/anima/attributes_spec.rb
92
- - spec/unit/anima/error/message_spec.rb
93
- - spec/unit/anima/included_spec.rb
94
- - spec/unit/anima/initialize_instance_spec.rb
95
- - spec/unit/anima/update/update_spec.rb
86
+ - spec/unit/anima/attribute_spec.rb
87
+ - spec/unit/anima/error_spec.rb
88
+ - spec/unit/anima/update_spec.rb
89
+ - spec/unit/anima_spec.rb
96
90
  homepage: http://github.com/mbj/anima
97
- licenses: []
91
+ licenses:
92
+ - MIT
98
93
  metadata: {}
99
94
  post_install_message:
100
95
  rdoc_options: []
@@ -119,15 +114,8 @@ summary: Attributes for Plain Old Ruby Objects Experiment
119
114
  test_files:
120
115
  - spec/integration/simple_spec.rb
121
116
  - spec/spec_helper.rb
122
- - spec/unit/anima/attribute/define_reader_spec.rb
123
- - spec/unit/anima/attribute/get_spec.rb
124
- - spec/unit/anima/attribute/instance_variable_name_spec.rb
125
- - spec/unit/anima/attribute/load_spec.rb
126
- - spec/unit/anima/attribute/set_spec.rb
127
- - spec/unit/anima/attributes_hash_spec.rb
128
- - spec/unit/anima/attributes_spec.rb
129
- - spec/unit/anima/error/message_spec.rb
130
- - spec/unit/anima/included_spec.rb
131
- - spec/unit/anima/initialize_instance_spec.rb
132
- - spec/unit/anima/update/update_spec.rb
117
+ - spec/unit/anima/attribute_spec.rb
118
+ - spec/unit/anima/error_spec.rb
119
+ - spec/unit/anima/update_spec.rb
120
+ - spec/unit/anima_spec.rb
133
121
  has_rdoc:
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima::Attribute, '#define_reader' do
4
- let(:object) { described_class.new(:foo) }
5
-
6
- subject { object.define_reader(target_class) }
7
-
8
- let(:target_class) do
9
- Class.new do
10
- def initialize(foo)
11
- @foo = foo
12
- end
13
- end
14
- end
15
-
16
- let(:value) { double('Value') }
17
-
18
- it 'should create a reader' do
19
- instance = target_class.new(value)
20
- lambda { subject }.should change { instance.respond_to?(:foo) }.from(false).to(true)
21
- end
22
-
23
- it_should_behave_like 'a command method'
24
- end
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima::Attribute, '#get' do
4
- let(:object) { described_class.new(:foo) }
5
-
6
- subject { object.get(target) }
7
-
8
- let(:target_class) do
9
- Class.new do
10
- attr_reader :foo
11
-
12
- def initialize(foo)
13
- @foo = foo
14
- end
15
- end
16
- end
17
-
18
- let(:target) { target_class.new(value) }
19
-
20
- let(:value) { double('Value') }
21
-
22
- it 'should return value' do
23
- should be(value)
24
- end
25
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima::Attribute, '#instance_variable_name' do
4
- subject { Anima::Attribute.new(:foo).instance_variable_name }
5
-
6
- it { should be(:@foo) }
7
-
8
- it_should_behave_like 'an idempotent method'
9
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima::Attribute, '#load' do
4
- let(:object) { described_class.new(:foo) }
5
-
6
- subject { object.load(target, attribute_hash) }
7
-
8
- let(:target) { Object.new }
9
-
10
- let(:value) { double('Value') }
11
-
12
- context 'when attribute hash contains key' do
13
- let(:attribute_hash) { { :foo => value } }
14
-
15
- it 'should set value as instance variable' do
16
- subject
17
- target.instance_variable_get(:@foo).should be(value)
18
- end
19
-
20
- it_should_behave_like 'a command method'
21
-
22
- end
23
-
24
- context 'when attribute hash does not contain key' do
25
- let(:attribute_hash) { {} }
26
-
27
- it 'should raise error' do
28
- expect { subject }.to raise_error(Anima::Error::Missing, Anima::Error::Missing.new(target.class, :foo).message)
29
- end
30
- end
31
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima::Attribute, '#set' do
4
- let(:object) { described_class.new(:foo) }
5
-
6
- subject { object.set(target, value) }
7
-
8
- let(:target) { Object.new }
9
-
10
- let(:value) { double('Value') }
11
-
12
- it_should_behave_like 'a command method'
13
-
14
- it 'should set value as instance variable' do
15
- subject
16
- target.instance_variable_get(:@foo).should be(value)
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima, '#attributes_hash' do
4
- let(:object) { described_class.new(:foo) }
5
-
6
- let(:value) { double('Value') }
7
-
8
- let(:instance) { double(:foo => value) }
9
-
10
- subject { object.attributes_hash(instance) }
11
-
12
- it { should eql(:foo => value) }
13
- end
@@ -1,10 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima, '#attributes' do
4
- subject { object.attributes }
5
-
6
- let(:object) { described_class.new(:foo) }
7
-
8
- it { should eql([Anima::Attribute.new(:foo)]) }
9
- it { should be_frozen }
10
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima, '#included' do
4
- let(:object) { described_class.new(:foo) }
5
-
6
- let(:target) do
7
- object = self.object
8
- Class.new do
9
- include object
10
- end
11
- end
12
-
13
- let(:value) { double('Value') }
14
-
15
- let(:instance) { target.new(:foo => value) }
16
- let(:instance_b) { target.new(:foo => value) }
17
- let(:instance_c) { target.new(:foo => double('Bar')) }
18
-
19
- context 'on instance' do
20
- subject { instance }
21
-
22
- its(:foo) { should be(value) }
23
-
24
- it { should eql(instance_b) }
25
- end
26
-
27
- context 'on singleton' do
28
- subject { target }
29
-
30
- it 'should define attribute hash reader' do
31
- target.attributes_hash(instance).should eql(:foo => value)
32
- end
33
-
34
- its(:anima) { should be(object) }
35
- end
36
- end
@@ -1,41 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Anima, '#initialize_instance' do
4
- let(:object) { Anima.new(:foo, :bar) }
5
-
6
- let(:target) { Object.new }
7
-
8
- let(:foo) { double('Foo') }
9
- let(:bar) { double('Bar') }
10
-
11
- subject { object.initialize_instance(target, attribute_hash) }
12
-
13
- context 'when all keys are present in attribute hash' do
14
- let(:attribute_hash) { { :foo => foo, :bar => bar } }
15
-
16
- it 'should initialize target instance variables' do
17
- subject
18
- target.instance_variables.map(&:to_sym).to_set.should eql([:@foo, :@bar].to_set)
19
- target.instance_variable_get(:@foo).should be(foo)
20
- target.instance_variable_get(:@bar).should be(bar)
21
- end
22
-
23
- it_should_behave_like 'a command method'
24
- end
25
-
26
- context 'when extra key is missing in attribute hash' do
27
- let(:attribute_hash) { { :foo => foo, :bar => bar, :baz => double('Baz') } }
28
-
29
- it 'should raise error' do
30
- expect { subject }.to raise_error(Anima::Error::Unknown, Anima::Error::Unknown.new(target.class, [:baz]).message)
31
- end
32
- end
33
-
34
- context 'when a key is missing in attribute hash' do
35
- let(:attribute_hash) { { :bar => bar } }
36
-
37
- it 'should raise error' do
38
- expect { subject }.to raise_error(Anima::Error::Missing, Anima::Error::Missing.new(target.class, :foo).message)
39
- end
40
- end
41
- end