anima 0.0.7 → 0.1.0

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: 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