pupa 0.0.10 → 0.0.11

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: 1e1915f53def27a04384e080b43b7eaa1c024398
4
- data.tar.gz: 75b0c4e987b976448a816b3b36be99942c393ddd
3
+ metadata.gz: 88acbf7d013691871dbdaf6390f551625f6d5c4d
4
+ data.tar.gz: 5e52a9789851411377f3403196560648767fddcb
5
5
  SHA512:
6
- metadata.gz: 5800302c7e32286138dc9f64b8dc06cd13c07cb4cfc5478d572b8fdc10c04483d595c7f48ceddb82efe4330ce280dc3b58467be50db3fa264e1429a24b3b7e0f
7
- data.tar.gz: 6cf10d376b218ce4190b4b08da3dbaa1f3fddf87763623f23368eccdccc1a305d611bb3eb8a0de37c55af961eca5ef0a88f9d613bdc08b9e59139c5fc5194b30
6
+ metadata.gz: b3f55a952c0cba3c80ed2dda6492144faf0b67b92583a847f08d301d8dba83a0acd22240ff856ef2a78d76f29984743482acfef5c49c4d3384afacf17d498dcf
7
+ data.tar.gz: afc4bdfad6dcd3702d79f5cdbebfecde163305ef8dd3cea6ac02332d8284584accf26fc5de5918e0a095de4438c554615619a87af590eac40fc5712d64d511f9
@@ -18,7 +18,7 @@ module Pupa
18
18
  #
19
19
  # @param [Array] contact_details a list of contact details
20
20
  def contact_details=(contact_details)
21
- @contact_details = ContactDetailList.new(contact_details)
21
+ @contact_details = ContactDetailList.new(symbolize_keys(contact_details))
22
22
  end
23
23
 
24
24
  # Adds a contact detail.
@@ -31,7 +31,7 @@ module Pupa
31
31
  if note
32
32
  data[:note] = note
33
33
  end
34
- if type && value
34
+ if type.present? && value.present?
35
35
  @contact_details << data
36
36
  end
37
37
  end
@@ -18,7 +18,7 @@ module Pupa
18
18
  #
19
19
  # @param [Array] identifiers a list of identifiers
20
20
  def identifiers=(identifiers)
21
- @identifiers = IdentifierList.new(identifiers)
21
+ @identifiers = IdentifierList.new(symbolize_keys(identifiers))
22
22
  end
23
23
 
24
24
  # Adds an issued identifier.
@@ -30,7 +30,7 @@ module Pupa
30
30
  if scheme
31
31
  data[:scheme] = scheme
32
32
  end
33
- if identifier
33
+ if identifier.present?
34
34
  @identifiers << data
35
35
  end
36
36
  end
@@ -5,7 +5,7 @@ module Pupa
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- attr_accessor :links
8
+ attr_reader :links
9
9
  dump :links
10
10
  end
11
11
 
@@ -14,6 +14,13 @@ module Pupa
14
14
  super
15
15
  end
16
16
 
17
+ # Sets the links.
18
+ #
19
+ # @param [Array] links a list of links
20
+ def links=(links)
21
+ @links = symbolize_keys(links)
22
+ end
23
+
17
24
  # Adds a URL.
18
25
  #
19
26
  # @param [String] url a URL
@@ -23,7 +30,7 @@ module Pupa
23
30
  if note
24
31
  data[:note] = note
25
32
  end
26
- if url
33
+ if url.present?
27
34
  @links << data
28
35
  end
29
36
  end
@@ -5,7 +5,7 @@ module Pupa
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- attr_accessor :other_names
8
+ attr_reader :other_names
9
9
  dump :other_names
10
10
  end
11
11
 
@@ -14,6 +14,13 @@ module Pupa
14
14
  super
15
15
  end
16
16
 
17
+ # Sets the other names.
18
+ #
19
+ # @param [Array] other_names a list of other names
20
+ def other_names=(other_names)
21
+ @other_names = symbolize_keys(other_names)
22
+ end
23
+
17
24
  # Adds an alternate or former name.
18
25
  #
19
26
  # @param [String] name an alternate or former name
@@ -31,7 +38,7 @@ module Pupa
31
38
  if note
32
39
  data[:note] = note
33
40
  end
34
- if name
41
+ if name.present?
35
42
  @other_names << data
36
43
  end
37
44
  end
@@ -5,7 +5,7 @@ module Pupa
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- attr_accessor :sources
8
+ attr_reader :sources
9
9
  dump :sources
10
10
  end
11
11
 
@@ -14,6 +14,13 @@ module Pupa
14
14
  super
15
15
  end
16
16
 
17
+ # Sets the sources.
18
+ #
19
+ # @param [Array] sources a list of sources
20
+ def sources=(sources)
21
+ @sources = symbolize_keys(sources)
22
+ end
23
+
17
24
  # Adds a source to the object.
18
25
  #
19
26
  # @param [String] url a URL
@@ -23,7 +30,7 @@ module Pupa
23
30
  if note
24
31
  data[:note] = note
25
32
  end
26
- if url
33
+ if url.present?
27
34
  @sources << data
28
35
  end
29
36
  end
@@ -15,6 +15,8 @@ module Pupa
15
15
  end
16
16
 
17
17
  set_callback(:save, :before) do |object|
18
+ # The object may not set created_at.
19
+ object.created_at = object.document['created_at'] if object.document
18
20
  object.updated_at = Time.now.utc
19
21
  end
20
22
  end
@@ -28,8 +28,15 @@ module Pupa
28
28
  self.foreign_keys = Set.new
29
29
  self.foreign_objects = Set.new
30
30
 
31
+ # @return [String] The object's unique identifier.
31
32
  attr_reader :_id
32
- attr_accessor :_type, :extras
33
+ # @return [Hash] The object's non-schema properties.
34
+ attr_reader :extras
35
+ # @return [String] The underscored, lowercase form of the object's class.
36
+ attr_accessor :_type
37
+ # @return [Moped::BSON::Document,nil] The object's matching document in
38
+ # the database. Set before persisting the object to the database.
39
+ attr_accessor :document
33
40
 
34
41
  dump :_id, :_type, :extras
35
42
  end
@@ -124,6 +131,13 @@ module Pupa
124
131
  @_id = id.to_s # in case of Moped::BSON::ObjectId
125
132
  end
126
133
 
134
+ # Sets the extras.
135
+ #
136
+ # @param [Array] extras a list of extras
137
+ def extras=(extras)
138
+ @extras = symbolize_keys(extras)
139
+ end
140
+
127
141
  # Adds a key-value pair to the object.
128
142
  #
129
143
  # @param [Symbol] key a key
@@ -159,8 +173,8 @@ module Pupa
159
173
 
160
174
  # Returns the object as a hash.
161
175
  #
162
- # @param [Boolean] persist whether the object is being persisted, validated
163
- # or used as a MongoDB selecto, in which case foreign objects (i.e. hints)
176
+ # @param [Boolean] persist whether the object is being persisted, validated,
177
+ # or used as a MongoDB selector, in which case foreign objects (i.e. hints)
164
178
  # are excluded
165
179
  # @return [Hash] the object as a hash
166
180
  def to_h(persist: false)
@@ -189,21 +203,29 @@ module Pupa
189
203
 
190
204
  private
191
205
 
192
- def stringify_keys(object)
206
+ def transform_keys(object, meth)
193
207
  case object
194
208
  when Hash
195
209
  {}.tap do |hash|
196
210
  object.each do |key,value|
197
- hash[key.to_s] = stringify_keys(value)
211
+ hash[key.send(meth)] = transform_keys(value, meth)
198
212
  end
199
213
  end
200
214
  when Array
201
215
  object.map do |value|
202
- stringify_keys(value)
216
+ transform_keys(value, meth)
203
217
  end
204
218
  else
205
219
  object
206
220
  end
207
221
  end
222
+
223
+ def symbolize_keys(object)
224
+ transform_keys(object, :to_sym)
225
+ end
226
+
227
+ def stringify_keys(object)
228
+ transform_keys(object, :to_s)
229
+ end
208
230
  end
209
231
  end
@@ -8,7 +8,9 @@ module Pupa
8
8
  # @param [String] a string
9
9
  # @return [String] a clean string
10
10
  def clean(string)
11
- string.gsub(/[[:space:]]/, ' ').squeeze(' ').strip
11
+ if string
12
+ string.gsub(/[[:space:]]/, ' ').squeeze(' ').strip
13
+ end
12
14
  end
13
15
  end
14
16
  end
@@ -28,7 +28,7 @@ module Pupa
28
28
  end
29
29
  end
30
30
 
31
- # Saves an object to MongoDB.
31
+ # Inserts or replaces a document in MongoDB.
32
32
  #
33
33
  # @return [Array] whether the object was inserted and the object's database ID
34
34
  # @raises [Pupa::Errors::TooManyMatches] if multiple documents would be updated
@@ -37,19 +37,23 @@ module Pupa
37
37
  query = collection.find(selector)
38
38
 
39
39
  # Run query before callbacks to avoid e.g. timestamps in the selector.
40
- @object.run_callbacks(:save) do
41
- case query.count
42
- when 0
40
+ case query.count
41
+ when 0
42
+ @object.run_callbacks(:save) do
43
43
  @object.run_callbacks(:create) do
44
44
  collection.insert(@object.to_h(persist: true))
45
45
  [true, @object._id.to_s]
46
46
  end
47
- when 1
48
- query.update(@object.to_h(persist: true))
49
- [false, query.first['_id'].to_s]
50
- else
51
- raise Errors::TooManyMatches, "selector matches multiple documents during save: #{collection_name} #{MultiJson.dump(selector)}"
52
47
  end
48
+ when 1
49
+ # Make the document available to the callbacks.
50
+ @object.document = query.first
51
+ @object.run_callbacks(:save) do
52
+ query.update(@object.to_h(persist: true).except(:_id))
53
+ [false, @object.document['_id'].to_s]
54
+ end
55
+ else
56
+ raise Errors::TooManyMatches, "selector matches multiple documents during save: #{collection_name} #{MultiJson.dump(selector)}"
53
57
  end
54
58
  end
55
59
 
data/lib/pupa/runner.rb CHANGED
@@ -201,9 +201,11 @@ module Pupa
201
201
  end
202
202
  end
203
203
 
204
- report[:end] = Time.now.utc
205
- report[:time] = report[:end] - report[:start]
206
- puts MultiJson.dump(report)
204
+ if %w(DEBUG INFO).include?(options.level)
205
+ report[:end] = Time.now.utc
206
+ report[:time] = report[:end] - report[:start]
207
+ puts MultiJson.dump(report)
208
+ end
207
209
  end
208
210
  end
209
211
  end
data/lib/pupa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pupa
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.11"
3
3
  end
@@ -29,6 +29,11 @@ describe Pupa::Concerns::Contactable do
29
29
  object.contact_details = [{type: 'email', value: 'ceo@example.com', note: 'work'}]
30
30
  object.contact_details.should be_a(Pupa::ContactDetailList)
31
31
  end
32
+
33
+ it 'should symbolize keys' do
34
+ object.contact_details = [{'type' => 'email', 'value' => 'ceo@example.com', 'note' => 'work'}]
35
+ object.contact_details.should == [{type: 'email', value: 'ceo@example.com', note: 'work'}]
36
+ end
32
37
  end
33
38
 
34
39
  describe '#add_contact_detail' do
@@ -38,12 +43,14 @@ describe Pupa::Concerns::Contactable do
38
43
  end
39
44
 
40
45
  it 'should not add a contact detail without a type' do
41
- object.add_contact_detail('email', nil)
46
+ object.add_contact_detail(nil, 'ceo@example.com')
47
+ object.add_contact_detail('', 'ceo@example.com')
42
48
  object.contact_details.blank?.should == true
43
49
  end
44
50
 
45
51
  it 'should not add a contact detail without a value' do
46
- object.add_contact_detail(nil, 'ceo@example.com')
52
+ object.add_contact_detail('email', nil)
53
+ object.add_contact_detail('email', '')
47
54
  object.contact_details.blank?.should == true
48
55
  end
49
56
  end
@@ -29,6 +29,11 @@ describe Pupa::Concerns::Identifiable do
29
29
  object.identifiers = [{identifier: '123456789', scheme: 'DUNS'}]
30
30
  object.identifiers.should be_a(Pupa::IdentifierList)
31
31
  end
32
+
33
+ it 'should symbolize keys' do
34
+ object.identifiers = [{'identifier' => '123456789', 'scheme' => 'DUNS'}]
35
+ object.identifiers.should == [{identifier: '123456789', scheme: 'DUNS'}]
36
+ end
32
37
  end
33
38
 
34
39
  describe '#add_identifier' do
@@ -39,6 +44,7 @@ describe Pupa::Concerns::Identifiable do
39
44
 
40
45
  it 'should not add an identifier without an identifier' do
41
46
  object.add_identifier(nil)
47
+ object.add_identifier('')
42
48
  object.identifiers.blank?.should == true
43
49
  end
44
50
  end
@@ -12,6 +12,13 @@ describe Pupa::Concerns::Linkable do
12
12
  klass.new
13
13
  end
14
14
 
15
+ describe '#links' do
16
+ it 'should symbolize keys' do
17
+ object.links = [{'url' => 'http://example.com', 'note' => 'homepage'}]
18
+ object.links.should == [{url: 'http://example.com', note: 'homepage'}]
19
+ end
20
+ end
21
+
15
22
  describe '#add_link' do
16
23
  it 'should add a link' do
17
24
  object.add_link('http://example.com', note: 'homepage')
@@ -20,6 +27,7 @@ describe Pupa::Concerns::Linkable do
20
27
 
21
28
  it 'should not add a link without a url' do
22
29
  object.add_link(nil)
30
+ object.add_link('')
23
31
  object.links.blank?.should == true
24
32
  end
25
33
  end
@@ -12,6 +12,13 @@ describe Pupa::Concerns::Nameable do
12
12
  klass.new
13
13
  end
14
14
 
15
+ describe '#other_names' do
16
+ it 'should symbolize keys' do
17
+ object.other_names = [{'name' => 'Mr. Ziggy Q. Public, Esq.', 'start_date' => '1920-01', 'end_date' => '1949-12-31', 'note' => 'Birth name'}]
18
+ object.other_names.should == [{name: 'Mr. Ziggy Q. Public, Esq.', start_date: '1920-01', end_date: '1949-12-31', note: 'Birth name'}]
19
+ end
20
+ end
21
+
15
22
  describe '#add_name' do
16
23
  it 'should add a name' do
17
24
  object.add_name('Mr. Ziggy Q. Public, Esq.', start_date: '1920-01', end_date: '1949-12-31', note: 'Birth name')
@@ -20,6 +27,7 @@ describe Pupa::Concerns::Nameable do
20
27
 
21
28
  it 'should not add a name without a name' do
22
29
  object.add_name(nil)
30
+ object.add_name('')
23
31
  object.other_names.blank?.should == true
24
32
  end
25
33
  end
@@ -12,6 +12,13 @@ describe Pupa::Concerns::Sourceable do
12
12
  klass.new
13
13
  end
14
14
 
15
+ describe '#sources' do
16
+ it 'should symbolize keys' do
17
+ object.sources = [{'url' => 'http://example.com', 'note' => 'homepage'}]
18
+ object.sources.should == [{url: 'http://example.com', note: 'homepage'}]
19
+ end
20
+ end
21
+
15
22
  describe '#add_source' do
16
23
  it 'should add a source' do
17
24
  object.add_source('http://example.com', note: 'homepage')
@@ -20,6 +27,7 @@ describe Pupa::Concerns::Sourceable do
20
27
 
21
28
  it 'should not add a source without a url' do
22
29
  object.add_source(nil)
30
+ object.add_source('')
23
31
  object.sources.blank?.should == true
24
32
  end
25
33
  end
@@ -151,6 +151,13 @@ describe Pupa::Model do
151
151
  end
152
152
  end
153
153
 
154
+ describe '#links' do
155
+ it 'should symbolize keys' do
156
+ object.extras = {'age' => 10}
157
+ object.extras.should == {age: 10}
158
+ end
159
+ end
160
+
154
161
  describe '#add_extra' do
155
162
  it 'should add an extra property' do
156
163
  object.add_extra(:age, 10)
@@ -5,7 +5,7 @@ describe Pupa::Processor::Persistence do
5
5
  Pupa.session = Moped::Session.new(['localhost:27017'], database: 'pupa_test')
6
6
  Pupa.session.collections.each(&:drop)
7
7
 
8
- Pupa::Processor::Persistence.new(Pupa::Person.new(_id: 'existing', name: 'existing')).save
8
+ Pupa::Processor::Persistence.new(Pupa::Person.new(_id: 'existing', name: 'existing', email: 'existing@example.com')).save
9
9
 
10
10
  Pupa.session[:people].insert(_type: 'pupa/person', name: 'non-unique')
11
11
  Pupa.session[:people].insert(_type: 'pupa/person', name: 'non-unique')
@@ -27,11 +27,13 @@ describe Pupa::Processor::Persistence do
27
27
 
28
28
  describe '#save' do
29
29
  it 'should insert a document if no matches' do
30
- Pupa::Processor::Persistence.new(Pupa::Person.new(_id: 'new', name: 'new')).save.should == [true, 'new']
30
+ Pupa::Processor::Persistence.new(Pupa::Person.new(_id: 'new', name: 'new', email: 'new@example.com')).save.should == [true, 'new']
31
+ Pupa::Processor::Persistence.find(_type: 'pupa/person', name: 'new')['email'].should == 'new@example.com'
31
32
  end
32
33
 
33
34
  it 'should update a document if one match' do
34
- Pupa::Processor::Persistence.new(Pupa::Person.new(_id: 'changed', name: 'existing')).save.should == [false, 'existing']
35
+ Pupa::Processor::Persistence.new(Pupa::Person.new(_id: 'changed', name: 'existing', email: 'changed@example.com')).save.should == [false, 'existing']
36
+ Pupa::Processor::Persistence.find(_type: 'pupa/person', name: 'existing')['email'].should == 'changed@example.com'
35
37
  end
36
38
 
37
39
  it 'should raise an error if many matches' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pupa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Open North
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-06 00:00:00.000000000 Z
11
+ date: 2013-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -316,7 +316,6 @@ files:
316
316
  - spec/fixtures/baz.json
317
317
  - spec/fixtures/foo.json
318
318
  - spec/logger_spec.rb
319
- - spec/models/base_spec.rb
320
319
  - spec/models/concerns/contactable_spec.rb
321
320
  - spec/models/concerns/identifiable_spec.rb
322
321
  - spec/models/concerns/linkable_spec.rb
@@ -326,6 +325,7 @@ files:
326
325
  - spec/models/contact_detail_list_spec.rb
327
326
  - spec/models/identifier_list_spec.rb
328
327
  - spec/models/membership_spec.rb
328
+ - spec/models/model_spec.rb
329
329
  - spec/models/organization_spec.rb
330
330
  - spec/models/person_spec.rb
331
331
  - spec/models/post_spec.rb
@@ -378,7 +378,6 @@ test_files:
378
378
  - spec/fixtures/baz.json
379
379
  - spec/fixtures/foo.json
380
380
  - spec/logger_spec.rb
381
- - spec/models/base_spec.rb
382
381
  - spec/models/concerns/contactable_spec.rb
383
382
  - spec/models/concerns/identifiable_spec.rb
384
383
  - spec/models/concerns/linkable_spec.rb
@@ -388,6 +387,7 @@ test_files:
388
387
  - spec/models/contact_detail_list_spec.rb
389
388
  - spec/models/identifier_list_spec.rb
390
389
  - spec/models/membership_spec.rb
390
+ - spec/models/model_spec.rb
391
391
  - spec/models/organization_spec.rb
392
392
  - spec/models/person_spec.rb
393
393
  - spec/models/post_spec.rb