anima 0.1.0 → 0.3.2
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 +5 -5
- data/README.md +32 -24
- data/lib/anima.rb +86 -112
- data/lib/anima/attribute.rb +7 -50
- data/lib/anima/error.rb +10 -20
- metadata +38 -56
- data/.gitignore +0 -5
- data/.travis.yml +0 -14
- data/Changelog.md +0 -20
- data/Gemfile +0 -6
- data/Gemfile.devtools +0 -55
- data/Guardfile +0 -18
- data/Rakefile +0 -2
- data/TODO +0 -3
- data/anima.gemspec +0 -21
- data/config/flay.yml +0 -3
- data/config/flog.yml +0 -2
- data/config/mutant.yml +0 -3
- data/config/reek.yml +0 -93
- data/config/roodi.yml +0 -18
- data/config/rubocop.yml +0 -85
- data/config/yardstick.yml +0 -2
- data/lib/anima/update.rb +0 -29
- data/spec/integration/simple_spec.rb +0 -56
- data/spec/spec_helper.rb +0 -8
- data/spec/unit/anima/attribute_spec.rb +0 -98
- data/spec/unit/anima/error_spec.rb +0 -16
- data/spec/unit/anima/update_spec.rb +0 -25
- data/spec/unit/anima_spec.rb +0 -134
data/config/roodi.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
---
|
2
|
-
AbcMetricMethodCheck: { score: 11.0 }
|
3
|
-
AssignmentInConditionalCheck: { }
|
4
|
-
CaseMissingElseCheck: { }
|
5
|
-
ClassLineCountCheck: { line_count: 293 }
|
6
|
-
ClassNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' }
|
7
|
-
ClassVariableCheck: { }
|
8
|
-
CyclomaticComplexityBlockCheck: { complexity: 2 }
|
9
|
-
CyclomaticComplexityMethodCheck: { complexity: 4 }
|
10
|
-
EmptyRescueBodyCheck: { }
|
11
|
-
ForLoopCheck: { }
|
12
|
-
# TODO: decrease line_count to 5 to 10
|
13
|
-
MethodLineCountCheck: { line_count: 14 }
|
14
|
-
MethodNameCheck: { pattern: !ruby/regexp '/\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|[+*&|-])\z/' }
|
15
|
-
ModuleLineCountCheck: { line_count: 295 }
|
16
|
-
ModuleNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' }
|
17
|
-
# TODO: decrease parameter_count to 2 or less
|
18
|
-
ParameterNumberCheck: { parameter_count: 3 }
|
data/config/rubocop.yml
DELETED
@@ -1,85 +0,0 @@
|
|
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
|
data/config/yardstick.yml
DELETED
data/lib/anima/update.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
class Anima
|
2
|
-
# Module for mixin in update functionallity to anima infected clases
|
3
|
-
module Update
|
4
|
-
|
5
|
-
# Return updated instance
|
6
|
-
#
|
7
|
-
# @example
|
8
|
-
# klass = Class.new do
|
9
|
-
# include Anima.new(:foo, :bar), Anima::Update
|
10
|
-
# end
|
11
|
-
#
|
12
|
-
# foo = klass.new(:foo => 1, :bar => 2)
|
13
|
-
# updated = foo.update(:foo => 3)
|
14
|
-
# updated.foo # => 3
|
15
|
-
# updated.bar # => 2
|
16
|
-
#
|
17
|
-
# @param [Hash] attributes
|
18
|
-
#
|
19
|
-
# @return [Anima]
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
#
|
23
|
-
def update(attributes)
|
24
|
-
klass = self.class
|
25
|
-
klass.new(klass.attributes_hash(self).merge(attributes))
|
26
|
-
end
|
27
|
-
|
28
|
-
end # Update
|
29
|
-
end # Anima
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Anima, 'simple integration' do
|
4
|
-
subject { class_under_test.new(attributes) }
|
5
|
-
|
6
|
-
let(:class_under_test) do
|
7
|
-
Class.new do
|
8
|
-
include Anima.new(:firstname, :lastname)
|
9
|
-
|
10
|
-
def self.name
|
11
|
-
'TestClass'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'when instanciated with all attributes' do
|
17
|
-
let(:attributes) do
|
18
|
-
{
|
19
|
-
firstname: 'Markus',
|
20
|
-
lastname: 'Schirp'
|
21
|
-
}
|
22
|
-
end
|
23
|
-
|
24
|
-
its(:firstname) { should eql('Markus') }
|
25
|
-
its(:lastname) { should eql('Schirp') }
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'with instanciated with extra attributes' do
|
29
|
-
let(:attributes) do
|
30
|
-
{
|
31
|
-
firstname: 'Markus',
|
32
|
-
lastname: 'Schirp',
|
33
|
-
extra: 'Foo'
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should raise error' do
|
38
|
-
expect { subject }.to raise_error(
|
39
|
-
Anima::Error::Unknown,
|
40
|
-
'Unknown attribute(s) [:extra] for TestClass'
|
41
|
-
)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'when instanciated with missing attribute' do
|
46
|
-
|
47
|
-
let(:attributes) { {} }
|
48
|
-
|
49
|
-
it 'should raise error' do
|
50
|
-
expect { subject }.to raise_error(
|
51
|
-
Anima::Error::Missing,
|
52
|
-
'Missing attribute(s) :firstname for TestClass'
|
53
|
-
)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,98 +0,0 @@
|
|
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
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Anima::Error, '#message' do
|
4
|
-
let(:object) { described_class.new(klass, name) }
|
5
|
-
|
6
|
-
subject { object.message }
|
7
|
-
|
8
|
-
let(:klass) { double(name: 'THE-CLASS-NAME') }
|
9
|
-
let(:name) { 'THE-ATTRIBUTE-NAME' }
|
10
|
-
|
11
|
-
it 'should return the message string' do
|
12
|
-
should eql('Error attribute(s) "THE-ATTRIBUTE-NAME" for THE-CLASS-NAME')
|
13
|
-
end
|
14
|
-
|
15
|
-
it_should_behave_like 'an idempotent method'
|
16
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Anima::Update, '#update' do
|
4
|
-
subject { object.update(attributes) }
|
5
|
-
|
6
|
-
let(:object) { class_under_test.new(foo: 1, bar: 2) }
|
7
|
-
|
8
|
-
let(:class_under_test) do
|
9
|
-
Class.new do
|
10
|
-
include Anima.new(:foo, :bar), Anima::Update
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'with empty attributes' do
|
15
|
-
let(:attributes) { {} }
|
16
|
-
|
17
|
-
it { should eql(object) }
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'with updated attribute' do
|
21
|
-
let(:attributes) { { foo: 3 } }
|
22
|
-
|
23
|
-
it { should eql(class_under_test.new(foo: 3, bar: 2)) }
|
24
|
-
end
|
25
|
-
end
|
data/spec/unit/anima_spec.rb
DELETED
@@ -1,134 +0,0 @@
|
|
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
|