datacite-mapping 0.2.5 → 0.3.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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +23 -11
  3. data/.ruby-version +1 -1
  4. data/CHANGES.md +5 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.md +1 -1
  7. data/README.md +2 -2
  8. data/Rakefile +5 -3
  9. data/datacite-mapping.gemspec +9 -7
  10. data/examples/reading.rb +1 -1
  11. data/examples/writing.rb +1 -0
  12. data/lib/datacite/mapping.rb +2 -0
  13. data/lib/datacite/mapping/alternate_identifier.rb +4 -2
  14. data/lib/datacite/mapping/contributor.rb +5 -3
  15. data/lib/datacite/mapping/creator.rb +6 -4
  16. data/lib/datacite/mapping/date.rb +5 -5
  17. data/lib/datacite/mapping/date_value.rb +4 -2
  18. data/lib/datacite/mapping/description.rb +5 -3
  19. data/lib/datacite/mapping/empty_filtering_nodes.rb +2 -0
  20. data/lib/datacite/mapping/funding_reference.rb +6 -4
  21. data/lib/datacite/mapping/geo_location.rb +2 -0
  22. data/lib/datacite/mapping/geo_location_box.rb +12 -10
  23. data/lib/datacite/mapping/geo_location_node.rb +9 -7
  24. data/lib/datacite/mapping/geo_location_point.rb +8 -6
  25. data/lib/datacite/mapping/geo_location_polygon.rb +3 -1
  26. data/lib/datacite/mapping/identifier.rb +9 -7
  27. data/lib/datacite/mapping/module_info.rb +5 -3
  28. data/lib/datacite/mapping/name_identifier.rb +4 -2
  29. data/lib/datacite/mapping/namespace_extensions.rb +2 -0
  30. data/lib/datacite/mapping/read_only_nodes.rb +5 -3
  31. data/lib/datacite/mapping/related_identifier.rb +5 -3
  32. data/lib/datacite/mapping/resource.rb +15 -13
  33. data/lib/datacite/mapping/resource_type.rb +3 -1
  34. data/lib/datacite/mapping/rights.rb +3 -1
  35. data/lib/datacite/mapping/subject.rb +5 -3
  36. data/lib/datacite/mapping/title.rb +5 -3
  37. data/spec/.rubocop.yml +3 -0
  38. data/spec/rspec_custom_matchers.rb +8 -8
  39. data/spec/spec_helper.rb +2 -0
  40. data/spec/unit/datacite/mapping/alternate_identifier_spec.rb +2 -0
  41. data/spec/unit/datacite/mapping/contributor_spec.rb +2 -0
  42. data/spec/unit/datacite/mapping/creator_spec.rb +2 -0
  43. data/spec/unit/datacite/mapping/date_spec.rb +2 -0
  44. data/spec/unit/datacite/mapping/date_value_spec.rb +2 -0
  45. data/spec/unit/datacite/mapping/description_spec.rb +2 -0
  46. data/spec/unit/datacite/mapping/funding_reference_spec.rb +3 -1
  47. data/spec/unit/datacite/mapping/geo_location_box_spec.rb +2 -0
  48. data/spec/unit/datacite/mapping/geo_location_point_spec.rb +2 -0
  49. data/spec/unit/datacite/mapping/geo_location_polygon_spec.rb +22 -20
  50. data/spec/unit/datacite/mapping/geo_location_spec.rb +24 -22
  51. data/spec/unit/datacite/mapping/identifier_spec.rb +8 -6
  52. data/spec/unit/datacite/mapping/name_identifier_spec.rb +2 -0
  53. data/spec/unit/datacite/mapping/related_identifier_spec.rb +2 -0
  54. data/spec/unit/datacite/mapping/resource_spec.rb +22 -18
  55. data/spec/unit/datacite/mapping/rights_spec.rb +3 -1
  56. data/spec/unit/datacite/mapping/subject_spec.rb +2 -0
  57. data/spec/unit/datacite/mapping/title_spec.rb +2 -0
  58. metadata +26 -26
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -9,11 +11,11 @@ module Datacite
9
11
  attr_reader :coord_elements
10
12
 
11
13
  def initialize(*args)
12
- fail 'No geometry class provided' unless @geom_class
13
- fail 'No coordinate elements provided' unless @coord_elements
14
- path, *args = super(*args)
14
+ raise 'No geometry class provided' unless @geom_class
15
+ raise 'No coordinate elements provided' unless @coord_elements
16
+ path, *myargs = super(*args)
15
17
  @path = ::XML::XXPath.new(path)
16
- args
18
+ myargs # rubocop:disable Lint/Void
17
19
  end
18
20
 
19
21
  def datacite_3?
@@ -22,12 +24,12 @@ module Datacite
22
24
 
23
25
  def extract_attr_value(xml)
24
26
  return from_text(xml) || from_children(xml)
25
- rescue => e
27
+ rescue StandardError => e
26
28
  raise e, "#{@owner}.#{@attrname}: Can't extract #{self.class} from #{xml}: #{e.message}"
27
29
  end
28
30
 
29
- def set_attr_value(xml, value) # rubocop:disable Metrics/AbcSize
30
- fail "Invalid value: expected #{geom_class} instance, was #{value || 'nil'}" unless value && value.is_a?(geom_class)
31
+ def set_attr_value(xml, value)
32
+ raise "Invalid value: expected #{geom_class} instance, was #{value || 'nil'}" unless value && value.is_a?(geom_class)
31
33
  element = @path.first(xml, ensure_created: true)
32
34
 
33
35
  if datacite_3?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping'
2
4
  require 'datacite/mapping/geo_location_node'
3
5
 
@@ -33,19 +35,19 @@ module Datacite
33
35
  when 2
34
36
  init_from_array(args)
35
37
  else
36
- fail ArgumentError, "Can't construct GeoLocationPoint from arguments: #{args}"
38
+ raise ArgumentError, "Can't construct GeoLocationPoint from arguments: #{args}"
37
39
  end
38
40
  end
39
41
 
40
42
  def latitude=(value)
41
- fail ArgumentError, 'Latitude cannot be nil' unless value
42
- fail ArgumentError, "#{value} is not a valid latitude" unless value >= -90 && value <= 90
43
+ raise ArgumentError, 'Latitude cannot be nil' unless value
44
+ raise ArgumentError, "#{value} is not a valid latitude" unless value >= -90 && value <= 90
43
45
  @latitude = value
44
46
  end
45
47
 
46
48
  def longitude=(value)
47
- fail ArgumentError, 'Longitude cannot be nil' unless value
48
- fail ArgumentError, "#{value} is not a valid longitude" unless value >= -180 && value <= 180
49
+ raise ArgumentError, 'Longitude cannot be nil' unless value
50
+ raise ArgumentError, "#{value} is not a valid longitude" unless value >= -180 && value <= 180
49
51
  @longitude = value
50
52
  end
51
53
 
@@ -62,7 +64,7 @@ module Datacite
62
64
  # {GeoLocationPoint}
63
65
  def <=>(other)
64
66
  return nil unless other.class == self.class
65
- [:latitude, :longitude].each do |c|
67
+ %i[latitude longitude].each do |c|
66
68
  order = send(c) <=> other.send(c)
67
69
  return order if order.nonzero?
68
70
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping'
2
4
 
3
5
  module Datacite
@@ -14,7 +16,7 @@ module Datacite
14
16
  def initialize(points:) # TODO: allow simple array of point args, array of hashes
15
17
  self.points = points
16
18
  warn "Polygon should contain at least 4 points, but has #{points.size}" if points.size < 4
17
- warn "Polygon is not closed; last and first point should be identical, but were: [#{points[0]}], [#{points[-1]}]" if points.size > 1 unless points[0] == points[-1]
19
+ warn "Polygon is not closed; last and first point should be identical, but were: [#{points[0]}], [#{points[-1]}]" unless points[0] == points[-1] || points.size <= 1
18
20
  end
19
21
 
20
22
  def points=(value)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping'
2
4
  require 'datacite/mapping/empty_filtering_nodes'
3
5
 
@@ -14,7 +16,7 @@ module Datacite
14
16
  class Identifier
15
17
  include XML::Mapping
16
18
 
17
- DOI = 'DOI'.freeze
19
+ DOI = 'DOI'
18
20
 
19
21
  # Initializes a new {Identifier}
20
22
  # @param value [String]
@@ -25,9 +27,9 @@ module Datacite
25
27
  end
26
28
 
27
29
  def value=(v)
28
- new_value = v && v.strip
29
- fail ArgumentError, 'Identifier must have a non-nil value' unless new_value
30
- fail ArgumentError, "Identifier value '#{new_value}' is not a valid DOI" unless new_value.match(DOI_PATTERN)
30
+ new_value = v&.strip
31
+ raise ArgumentError, 'Identifier must have a non-nil value' unless new_value
32
+ raise ArgumentError, "Identifier value '#{new_value}' is not a valid DOI" unless new_value.match?(DOI_PATTERN)
31
33
  @value = new_value
32
34
  end
33
35
 
@@ -35,7 +37,7 @@ module Datacite
35
37
  # @param v [String]
36
38
  # the identifier type (always 'DOI')
37
39
  def identifier_type=(v)
38
- fail ArgumentError, "Identifier type '#{v}' must be 'DOI'" unless DOI == v
40
+ raise ArgumentError, "Identifier type '#{v}' must be 'DOI'" unless DOI == v
39
41
  @identifier_type = v
40
42
  end
41
43
 
@@ -48,7 +50,7 @@ module Datacite
48
50
  # @param doi_string [String]
49
51
  def self.from_doi(doi_string)
50
52
  match = doi_string.match(DOI_PATTERN)
51
- fail ArgumentError, "'#{doi_string}' does not appear to contain a valid DOI" unless match
53
+ raise ArgumentError, "'#{doi_string}' does not appear to contain a valid DOI" unless match
52
54
  Identifier.new(value: match[0])
53
55
  end
54
56
 
@@ -69,7 +71,7 @@ module Datacite
69
71
 
70
72
  private
71
73
 
72
- def has_element?(xml) # rubocop:disable Style/PredicateName
74
+ def has_element?(xml) # rubocop:disable Naming/PredicateName
73
75
  @path.first(xml)
74
76
  rescue XML::XXPathError
75
77
  false
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datacite
2
4
  module Mapping
3
5
  # The name of this gem
4
- NAME = 'datacite-mapping'.freeze
6
+ NAME = 'datacite-mapping'
5
7
 
6
8
  # The version of this gem
7
- VERSION = '0.2.5'.freeze
9
+ VERSION = '0.3.0'
8
10
 
9
11
  # The copyright notice for this gem
10
- COPYRIGHT = 'Copyright (c) 2016 The Regents of the University of California'.freeze
12
+ COPYRIGHT = 'Copyright (c) 2016 The Regents of the University of California'
11
13
  end
12
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -17,12 +19,12 @@ module Datacite
17
19
  end
18
20
 
19
21
  def scheme=(v)
20
- fail ArgumentError, 'Scheme cannot be empty or nil' unless v && !v.empty?
22
+ raise ArgumentError, 'Scheme cannot be empty or nil' unless v && !v.empty?
21
23
  @scheme = v
22
24
  end
23
25
 
24
26
  def value=(v)
25
- fail ArgumentError, 'Value cannot be empty or nil' unless v && !v.empty?
27
+ raise ArgumentError, 'Value cannot be empty or nil' unless v && !v.empty?
26
28
  @value = v
27
29
  end
28
30
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  # TODO: port this to xml-mapping_extensions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping'
2
4
 
3
5
  module XML
@@ -31,7 +33,7 @@ module Datacite
31
33
 
32
34
  def warn_ignored(val)
33
35
  warning = "ignoring #{@attrname} #{value_str(val)}"
34
- warning.prepend("#{warn_reason}; ") if warn_reason
36
+ warning = "#{warn_reason}; #{warning}" if warn_reason
35
37
  ReadOnlyNodes.warn(warning)
36
38
  end
37
39
 
@@ -43,7 +45,7 @@ module Datacite
43
45
 
44
46
  class ReadOnlyTextNode < XML::Mapping::TextNode
45
47
  def warn_ignored(val)
46
- fail ArgumentError, "Expected string, got #{val}" unless val.respond_to?(:strip)
48
+ raise ArgumentError, "Expected string, got #{val}" unless val.respond_to?(:strip)
47
49
  return if val.strip.empty?
48
50
  super
49
51
  end
@@ -53,7 +55,7 @@ module Datacite
53
55
 
54
56
  class ReadOnlyArrayNode < XML::Mapping::ArrayNode
55
57
  def warn_ignored(val)
56
- fail ArgumentError, "Expected array, got #{val}" unless val.respond_to?(:empty?)
58
+ raise ArgumentError, "Expected array, got #{val}" unless val.respond_to?(:empty?)
57
59
  return if val.empty?
58
60
  super
59
61
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -181,17 +183,17 @@ module Datacite
181
183
  end
182
184
 
183
185
  def value=(value)
184
- fail ArgumentError, 'Value cannot be empty or nil' unless value && !value.empty?
186
+ raise ArgumentError, 'Value cannot be empty or nil' unless value && !value.empty?
185
187
  @value = value
186
188
  end
187
189
 
188
190
  def identifier_type=(value)
189
- fail ArgumentError, 'Identifier type cannot be empty or nil' unless value
191
+ raise ArgumentError, 'Identifier type cannot be empty or nil' unless value
190
192
  @identifier_type = value
191
193
  end
192
194
 
193
195
  def relation_type=(value)
194
- fail ArgumentError, 'Relation type cannot be nil' unless value
196
+ raise ArgumentError, 'Relation type cannot be nil' unless value
195
197
  @relation_type = value
196
198
  end
197
199
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  require 'datacite/mapping/identifier'
@@ -91,33 +93,33 @@ module Datacite
91
93
  end
92
94
 
93
95
  def identifier=(value)
94
- fail ArgumentError, 'Resource must have an identifier' unless value
96
+ raise ArgumentError, 'Resource must have an identifier' unless value
95
97
  @identifier = value
96
98
  end
97
99
 
98
100
  def creators=(value)
99
- fail ArgumentError, 'Resource must have at least one creator' unless value && !value.empty?
101
+ raise ArgumentError, 'Resource must have at least one creator' unless value && !value.empty?
100
102
  @creators = value
101
103
  end
102
104
 
103
105
  def titles=(value)
104
- fail ArgumentError, 'Resource must have at least one title' unless value && !value.empty?
106
+ raise ArgumentError, 'Resource must have at least one title' unless value && !value.empty?
105
107
  @titles = value
106
108
  end
107
109
 
108
110
  def publisher=(value)
109
- new_value = value && value.strip
110
- fail ArgumentError, 'Resource must have a publisher' unless new_value && !new_value.empty?
111
+ new_value = value&.strip
112
+ raise ArgumentError, 'Resource must have a publisher' unless new_value && !new_value.empty?
111
113
  @publisher = new_value.strip
112
114
  end
113
115
 
114
116
  def publication_year=(value)
115
- fail ArgumentError, 'Resource must have a four-digit publication year' unless value && value.to_i.between?(1000, 9999)
117
+ raise ArgumentError, 'Resource must have a four-digit publication year' unless value && value.to_i.between?(1000, 9999)
116
118
  @publication_year = value.to_i
117
119
  end
118
120
 
119
121
  def subjects=(value)
120
- @subjects = (value && value.select(&:value)) || []
122
+ @subjects = (value&.select(&:value)) || []
121
123
  end
122
124
 
123
125
  def contributors=(value)
@@ -150,7 +152,7 @@ module Datacite
150
152
 
151
153
  def version=(value)
152
154
  new_value = value && value.to_s
153
- @version = new_value && new_value.strip
155
+ @version = new_value&.strip
154
156
  end
155
157
 
156
158
  def rights_list=(value)
@@ -158,11 +160,11 @@ module Datacite
158
160
  end
159
161
 
160
162
  def descriptions=(value)
161
- @descriptions = (value && value.select(&:value)) || []
163
+ @descriptions = (value&.select(&:value)) || []
162
164
  end
163
165
 
164
166
  def geo_locations=(value)
165
- @geo_locations = (value && value.select(&:location?)) || []
167
+ @geo_locations = (value&.select(&:location?)) || []
166
168
  end
167
169
 
168
170
  # @!attribute [rw] identifier
@@ -264,19 +266,19 @@ module Datacite
264
266
  # @deprecated contributor type 'funder' is deprecated. Use {FundingReference} instead.
265
267
  # @return [String, nil] the name of the funding contributor, if any.
266
268
  def funder_name
267
- funder_contrib.name if funder_contrib
269
+ funder_contrib&.name
268
270
  end
269
271
 
270
272
  # Convenience method to get the funding contributor identifier.
271
273
  # @return [NameIdentifier, nil] the identifier of the funding contributor, if any.
272
274
  def funder_id
273
- funder_contrib.identifier if funder_contrib
275
+ funder_contrib&.identifier
274
276
  end
275
277
 
276
278
  # Convenience method to get the funding contributor identifier as a string.
277
279
  # @return [String, nil] the string value of the funding contributor's identifier, if any.
278
280
  def funder_id_value
279
- funder_id.value if funder_id
281
+ funder_id&.value
280
282
  end
281
283
 
282
284
  extend Gem::Deprecate
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -62,7 +64,7 @@ module Datacite
62
64
  end
63
65
 
64
66
  def resource_type_general=(val)
65
- fail ArgumentError, 'General resource type cannot be nil' unless val
67
+ raise ArgumentError, 'General resource type cannot be nil' unless val
66
68
  @resource_type_general = val
67
69
  end
68
70
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -17,7 +19,7 @@ module Datacite
17
19
  end
18
20
 
19
21
  def value=(v)
20
- fail ArgumentError, 'Value cannot be empty or nil' unless v && !v.empty?
22
+ raise ArgumentError, 'Value cannot be empty or nil' unless v && !v.empty?
21
23
  @value = v.strip
22
24
  end
23
25
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping'
2
4
 
3
5
  module Datacite
@@ -20,12 +22,12 @@ module Datacite
20
22
  end
21
23
 
22
24
  def language=(value)
23
- @language = value && value.strip
25
+ @language = value&.strip
24
26
  end
25
27
 
26
28
  def value=(v)
27
- new_value = v && v.strip
28
- fail ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
29
+ new_value = v&.strip
30
+ raise ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
29
31
  @value = new_value
30
32
  end
31
33
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'xml/mapping_extensions'
2
4
 
3
5
  module Datacite
@@ -31,12 +33,12 @@ module Datacite
31
33
  end
32
34
 
33
35
  def language=(value)
34
- @language = value && value.strip
36
+ @language = value&.strip
35
37
  end
36
38
 
37
39
  def value=(v)
38
- new_value = v && v.strip
39
- fail ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
40
+ new_value = v&.strip
41
+ raise ArgumentError, 'Value cannot be empty or nil' unless new_value && !new_value.empty?
40
42
  @value = new_value.strip
41
43
  end
42
44
 
data/spec/.rubocop.yml CHANGED
@@ -1,5 +1,8 @@
1
1
  inherit_from: ../.rubocop.yml
2
2
 
3
+ Metrics/BlockLength:
4
+ Enabled: false
5
+
3
6
  Metrics/MethodLength:
4
7
  Enabled: false
5
8
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rspec/expectations'
2
4
  require 'equivalent-xml'
3
5
 
@@ -15,7 +17,7 @@ RSpec::Matchers.define :be_xml do |expected|
15
17
  when REXML::Element
16
18
  to_nokogiri(xml.to_s)
17
19
  else
18
- fail "be_xml() expected XML, got #{xml.class}"
20
+ raise "be_xml() expected XML, got #{xml.class}"
19
21
  end
20
22
  end
21
23
 
@@ -28,7 +30,7 @@ RSpec::Matchers.define :be_xml do |expected|
28
30
  end
29
31
 
30
32
  match do |actual|
31
- expected_xml = to_nokogiri(expected) || fail("expected value #{expected || 'nil'} does not appear to be XML")
33
+ expected_xml = to_nokogiri(expected) || raise("expected value #{expected || 'nil'} does not appear to be XML")
32
34
  actual_xml = to_nokogiri(actual)
33
35
 
34
36
  EquivalentXml.equivalent?(expected_xml, actual_xml, element_order: false, normalize_whitespace: true)
@@ -57,12 +59,10 @@ RSpec::Matchers.define :be_time do |expected|
57
59
  end
58
60
 
59
61
  match do |actual|
60
- if expected
61
- fail "Expected value #{expected} is not a Time" unless expected.is_a?(Time)
62
- actual.is_a?(Time) && (to_string(expected) == to_string(actual))
63
- else
64
- return actual.nil?
65
- end
62
+ return actual.nil? unless expected
63
+
64
+ raise "Expected value #{expected} is not a Time" unless expected.is_a?(Time)
65
+ actual.is_a?(Time) && (to_string(expected) == to_string(actual))
66
66
  end
67
67
 
68
68
  failure_message do |actual|