active_poro 0.0.4 → 0.0.5

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: 3c293f42fa865f7c17c588467950d0f20e7b225d
4
- data.tar.gz: c8dad835f22660be2f81ebb56d8c9df423e05a95
3
+ metadata.gz: 657deddc2134e4fcaaa62c9fbe84bece78e613bd
4
+ data.tar.gz: 0268c80ce1c30a2462997463b86e94d64bd0b03b
5
5
  SHA512:
6
- metadata.gz: a88a7027aaebd2f5192c129d21883245ac0a2ee2414841efd449de69f86a88de0a8ad99c02ba74a8f4f81cb51e5e533950fe4074f09bec8deabc78586d876eae
7
- data.tar.gz: 24c5e384586c98f5099f2d184075240e067fe052de54d44564df3450301e1bc15ccbb5984afa32931cc04251b02d07efc599dff11a6fed9b8548cfc4569c2c92
6
+ metadata.gz: 02c15b6276f732edba9595b531f9640802d6a994e21ca64e947fd15993a67fb9010c1f5163639bc888b489f3cba76a4e8ae9e0e38082a6c2be17091a114a09eb
7
+ data.tar.gz: 6ed9ae1f95d3be32edea5df94da58011f89e039a61ff900b79488275b0a51d9fcc83841d2e7dcf53efd35a0c68e7aaa8e3b8b19affc077e1e49432c8eb53b300
data/.ruby-version CHANGED
@@ -1 +1,2 @@
1
- 2.0.0-p247
1
+ 2.0.0-p451
2
+
data/README.md CHANGED
@@ -1,11 +1,9 @@
1
1
  # active_poro
2
- Makes possible the use of has_many, has_one, belongs_to relations in POROs as you would expect
3
-
4
- Important!
5
- ----------
6
2
 
7
- This project is under active development
3
+ [![Gem Version](https://badge.fury.io/rb/active_poro.svg)](http://badge.fury.io/rb/active_poro)
4
+ [![Test Coverage](https://codeclimate.com/github/codescrum/active_poro/badges/coverage.svg)](https://codeclimate.com/github/codescrum/active_poro)
8
5
 
6
+ Makes possible the use of has_many, has_one, belongs_to relations in POROs as you would expect
9
7
 
10
8
  ## Installation
11
9
 
data/active_poro.gemspec CHANGED
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency('rspec')
24
24
  spec.add_development_dependency('jazz_hands')
25
+ spec.add_development_dependency('simplecov', '0.9.0')
26
+ spec.add_development_dependency('codeclimate-test-reporter', '0.4.0')
25
27
 
26
28
  spec.add_runtime_dependency('activesupport')
27
29
  end
@@ -4,6 +4,7 @@ module ActivePoro
4
4
 
5
5
  module ClassMethods
6
6
  def has_many(target_name)
7
+
7
8
  # define getter method
8
9
  define_method target_name do
9
10
  instance_variable_get("@#{target_name}") || []
@@ -17,12 +18,12 @@ module ActivePoro
17
18
 
18
19
  # set the instance variable only if I am now the rightful owner
19
20
  instance_variable_set("@#{target_name}", members)
20
- reflected_association_name = self.class.name.underscore
21
+ singular_reflection_name = self.class.name.underscore
21
22
  members.each do |member|
22
23
 
23
- current_owner = member.send(reflected_association_name)
24
+ current_owner = member.send(singular_reflection_name)
24
25
  if current_owner.nil? # no current assignment
25
- member.send "#{reflected_association_name}=", self
26
+ member.send "#{singular_reflection_name}=", self
26
27
  elsif current_owner != self # current assignment is not me
27
28
  other_members = current_owner.send target_name
28
29
  if other_members.include?(member)
@@ -33,7 +34,7 @@ module ActivePoro
33
34
  raise "Unmatching association; Current owner (#{current_owner.class.name}) of #{member.class.name} does not have it as a member"
34
35
  end
35
36
  # add me as associated to the member I am also including
36
- member.send "#{reflected_association_name}=", self
37
+ member.send "#{singular_reflection_name}=", self
37
38
  else
38
39
  # its already me, do not do anything
39
40
  end
@@ -41,13 +42,16 @@ module ActivePoro
41
42
  end
42
43
  end
43
44
 
45
+ # the singular suffix for add and remove methods
46
+ singular_target_name = target_name.to_s.singularize
47
+
44
48
  # define the "add_<name>" method
45
- define_method "add_#{target_name.to_s.singularize}" do |member|
49
+ define_method "add_#{singular_target_name}" do |member|
46
50
  send("#{target_name}=", (send(target_name) + [member]).uniq)
47
51
  end
48
52
 
49
53
  # define the "remove_<name>" method
50
- define_method "remove_#{target_name.to_s.singularize}" do |member|
54
+ define_method "remove_#{singular_target_name}" do |member|
51
55
  send("#{target_name}=", (send(target_name) - [member]).uniq)
52
56
  end
53
57
 
@@ -61,9 +65,9 @@ module ActivePoro
61
65
 
62
66
  # define setter method
63
67
  define_method "#{target_name}=" do |member|
64
- reflected_association_name = self.class.name.underscore
65
- if member.respond_to?(reflected_association_name) && member.send(reflected_association_name) != self
66
- member.send "#{reflected_association_name}=", self
68
+ singular_reflection_name = self.class.name.underscore
69
+ if member.respond_to?(singular_reflection_name) && member.send(singular_reflection_name) != self
70
+ member.send "#{singular_reflection_name}=", self
67
71
  end
68
72
  instance_variable_set("@#{target_name}", member)
69
73
  end
@@ -79,33 +83,30 @@ module ActivePoro
79
83
  define_method "#{target_name}=" do |member|
80
84
  previous_member = instance_variable_get("@#{target_name}")
81
85
  instance_variable_set("@#{target_name}", member)
82
- reflected_association_name = self.class.name.underscore
86
+
87
+ singular_reflection_name = self.class.name.underscore
88
+ plural_reflection_name = singular_reflection_name.pluralize
89
+
83
90
  # add myself to reflected association
84
- if member.respond_to?(reflected_association_name) && member.send(reflected_association_name) != self
85
- member.send("#{reflected_association_name}=", self)
86
- elsif member.respond_to? reflected_association_name.pluralize
87
- reflected_members = member.send(reflected_association_name.pluralize)
88
- unless reflected_members.include? self
89
- member.send("#{reflected_association_name.pluralize}=", reflected_members + [self])
90
- end
91
+ if member.respond_to?(singular_reflection_name) && member.send(singular_reflection_name) != self
92
+ member.send("#{singular_reflection_name}=", self)
93
+ elsif member.respond_to? plural_reflection_name
94
+ reflected_members = member.send(plural_reflection_name)
95
+ member.send("#{plural_reflection_name}=", reflected_members + [self]) unless reflected_members.include? self
91
96
  else
92
- raise "Association definition missing: no #{reflected_association_name} or #{reflected_association_name.pluralize} association defined in #{member.class}"
97
+ raise "Association definition missing: no #{singular_reflection_name} or #{plural_reflection_name} association defined in #{member.class}"
93
98
  end
94
99
 
95
100
  # remove myself from old reflected association
96
- if previous_member.respond_to? reflected_association_name
97
- if previous_member.send(reflected_association_name) == self
98
- previous_member.send("#{reflected_association_name}=", nil)
99
- end
100
- elsif previous_member.respond_to? reflected_association_name.pluralize
101
- previous_reflected_members = previous_member.send(reflected_association_name.pluralize)
102
- if previous_reflected_members.include? self
103
- previous_member.send("#{reflected_association_name.pluralize}=", previous_reflected_members - [self])
104
- end
101
+ if previous_member.respond_to? singular_reflection_name
102
+ previous_member.send("#{singular_reflection_name}=", nil) if previous_member.send(singular_reflection_name) == self
103
+ elsif previous_member.respond_to? plural_reflection_name
104
+ previous_reflected_members = previous_member.send(plural_reflection_name)
105
+ previous_member.send("#{plural_reflection_name}=", previous_reflected_members - [self]) if previous_reflected_members.include? self
105
106
  elsif previous_member.nil?
106
- # there was not previous member
107
+ # there wasn't any previous member
107
108
  else # there was a previous member
108
- raise "Ghost association definition: no #{reflected_association_name} or #{reflected_association_name.pluralize} association defined in #{member.class}, although it was there previously, dirty contamination"
109
+ raise "Ghost association definition: no #{singular_reflection_name} or #{plural_reflection_name} association defined in #{member.class}, although it was there previously, dirty contamination"
109
110
  end
110
111
  end
111
112
  end
@@ -1,3 +1,3 @@
1
1
  module ActivePoro
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -131,26 +131,47 @@ describe 'ActivePoro' do
131
131
 
132
132
  end
133
133
 
134
- context 'when a flea jumps between dogs' do
134
+ context 'when fleas jump between dogs' do
135
135
 
136
136
  let(:small_dog){ Dog.new('Small dog') }
137
137
 
138
138
  it 'cannot be in two dogs at the same time' do
139
139
  flea_a.dog = big_dog
140
+ flea_b.dog = big_dog
140
141
  expect(flea_a.dog).to eq(big_dog)
141
- expect(big_dog.fleas).to eq([flea_a])
142
+ expect(flea_b.dog).to eq(big_dog)
143
+ expect(big_dog.fleas).to eq([flea_a, flea_b])
142
144
 
143
- # flea jumps from big dog to small dog
145
+ # flea A jumps from big dog to small dog
144
146
  flea_a.dog = small_dog
145
147
  expect(flea_a.dog).to eq(small_dog)
146
148
  expect(small_dog.fleas).to eq([flea_a])
147
149
 
148
150
  # flea A no longer in big dog
149
151
  expect(big_dog.fleas).to_not include(flea_a)
150
- expect(big_dog.fleas).to be_empty # sanity check
152
+ expect(big_dog.fleas).to eq([flea_b])# sanity check
153
+ end
154
+
155
+ end
156
+
157
+ context 'when a dog catches some fleas from another dog' do
158
+
159
+ let(:small_dog){ Dog.new('Small dog') }
160
+
161
+ it 'the other dog losses part of its fleas' do
162
+
163
+ big_dog.fleas = [flea_a, flea_b]
164
+
165
+ # small_dog is close enough to bid_dog and it caches a flea
166
+ small_dog.fleas = [flea_a]
167
+
168
+ # flea A no longer in big dog
169
+ expect(big_dog.fleas).to_not include(flea_a)
170
+ expect(big_dog.fleas).to eq([flea_b])# sanity check
151
171
  end
152
172
 
153
173
  end
174
+
154
175
  end
155
176
 
156
177
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,18 @@
1
+ # Add coverage with simple_cov and codeclimate
2
+ # These must be the first lines in the file
3
+ require 'codeclimate-test-reporter'
4
+ require 'simplecov'
5
+
6
+ formatters = [SimpleCov::Formatter::HTMLFormatter]
7
+ formatters << CodeClimate::TestReporter::Formatter if ENV['CODECLIMATE_REPO_TOKEN']
8
+
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[*formatters]
10
+ SimpleCov.start do
11
+ add_filter '/spec/'
12
+ end
13
+
14
+ #######################################################################
15
+
1
16
  require 'rubygems'
2
17
  require 'pry'
3
18
 
@@ -1,17 +1,12 @@
1
1
  # this is just a class that includes convenience methods for testing
2
2
  # such as a giving it a name so that is easy to inspect
3
- class BaseTestClass
4
- attr_accessor :name
5
-
6
- def initialize(name)
7
- self.name = name
8
- end
3
+ BaseTestClass = Struct.new(:name) do
9
4
 
10
5
  def to_s
11
6
  name
12
7
  end
13
8
 
14
9
  def inspect
15
- "\"#{to_s}\""
10
+ "\"#{self}\""
16
11
  end
17
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_poro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Diaz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-08 00:00:00.000000000 Z
11
+ date: 2014-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: codeclimate-test-reporter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.4.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.4.0
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: activesupport
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
151
  version: '0'
124
152
  requirements: []
125
153
  rubyforge_project:
126
- rubygems_version: 2.0.3
154
+ rubygems_version: 2.0.14
127
155
  signing_key:
128
156
  specification_version: 4
129
157
  summary: Makes possible the use of has_many, has_one, belongs_to relations in POROs