active-triples 0.8.1 → 0.8.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -9
  3. data/CHANGES.md +69 -0
  4. data/Gemfile +0 -2
  5. data/Guardfile +1 -2
  6. data/active-triples.gemspec +3 -3
  7. data/lib/active/triples.rb +1 -0
  8. data/lib/active_triples.rb +4 -0
  9. data/lib/active_triples/configurable.rb +3 -1
  10. data/lib/active_triples/configuration.rb +1 -0
  11. data/lib/active_triples/configuration/item.rb +1 -0
  12. data/lib/active_triples/configuration/item_factory.rb +1 -0
  13. data/lib/active_triples/configuration/merge_item.rb +5 -2
  14. data/lib/active_triples/extension_strategy.rb +1 -0
  15. data/lib/active_triples/identifiable.rb +1 -0
  16. data/lib/active_triples/list.rb +2 -0
  17. data/lib/active_triples/nested_attributes.rb +1 -1
  18. data/lib/active_triples/node_config.rb +5 -3
  19. data/lib/active_triples/persistable.rb +1 -0
  20. data/lib/active_triples/persistence_strategies/parent_strategy.rb +104 -29
  21. data/lib/active_triples/persistence_strategies/persistence_strategy.rb +15 -7
  22. data/lib/active_triples/persistence_strategies/repository_strategy.rb +26 -22
  23. data/lib/active_triples/properties.rb +84 -6
  24. data/lib/active_triples/property.rb +35 -4
  25. data/lib/active_triples/property_builder.rb +38 -4
  26. data/lib/active_triples/rdf_source.rb +225 -75
  27. data/lib/active_triples/reflection.rb +42 -3
  28. data/lib/active_triples/relation.rb +330 -73
  29. data/lib/active_triples/repositories.rb +4 -2
  30. data/lib/active_triples/resource.rb +1 -0
  31. data/lib/active_triples/schema.rb +1 -0
  32. data/lib/active_triples/undefined_property_error.rb +27 -0
  33. data/lib/active_triples/version.rb +2 -1
  34. data/spec/active_triples/configurable_spec.rb +3 -2
  35. data/spec/active_triples/configuration_spec.rb +2 -1
  36. data/spec/active_triples/extension_strategy_spec.rb +2 -1
  37. data/spec/active_triples/identifiable_spec.rb +7 -11
  38. data/spec/active_triples/list_spec.rb +1 -4
  39. data/spec/active_triples/nested_attributes_spec.rb +4 -3
  40. data/spec/active_triples/persistable_spec.rb +4 -1
  41. data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +141 -11
  42. data/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +1 -0
  43. data/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +32 -17
  44. data/spec/active_triples/properties_spec.rb +68 -33
  45. data/spec/active_triples/property_builder_spec.rb +36 -0
  46. data/spec/active_triples/property_spec.rb +15 -1
  47. data/spec/active_triples/rdf_source_spec.rb +544 -6
  48. data/spec/active_triples/reflection_spec.rb +78 -0
  49. data/spec/active_triples/relation_spec.rb +505 -3
  50. data/spec/active_triples/repositories_spec.rb +3 -1
  51. data/spec/active_triples/resource_spec.rb +90 -147
  52. data/spec/active_triples/schema_spec.rb +3 -2
  53. data/spec/active_triples_spec.rb +1 -0
  54. data/spec/integration/dummies/dummy_resource_a.rb +6 -0
  55. data/spec/integration/dummies/dummy_resource_b.rb +6 -0
  56. data/spec/integration/parent_persistence_spec.rb +18 -0
  57. data/spec/integration/reciprocal_properties_spec.rb +69 -0
  58. data/spec/pragmatic_context_spec.rb +10 -8
  59. data/spec/spec_helper.rb +5 -0
  60. data/spec/support/active_model_lint.rb +4 -6
  61. data/spec/support/dummies/basic_persistable.rb +2 -11
  62. data/spec/support/matchers.rb +11 -0
  63. data/spec/support/shared_examples/persistence_strategy.rb +3 -16
  64. metadata +20 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4928b254048d00cd2f52d050aea13407ba362425
4
- data.tar.gz: 11c44cb9efe80bfc6dd09f6e33a6aee0d288666d
3
+ metadata.gz: e1f422e5ac96c89ebdaeeb9d97d52ae3d5bfe526
4
+ data.tar.gz: b5fd9203d247be04fccab63466eee59bcc9af078
5
5
  SHA512:
6
- metadata.gz: 665fe27ad696dda89568310375194243760cfa22d8761bc10fc40eca9dcd39a81352c840e283e3501c4eb2504bdb1d663efa96138478660f5f9ab3454d3e874f
7
- data.tar.gz: ec21704f5faf6aadf57ec45c95bfb64113ef772f3fd48c8e7e26f4ddfa9dd08dfe786cd2039743c7b742d9cf24b600141f5e7dcfd1e1579f2d57fc181e625d8b
6
+ metadata.gz: 26f27fa5aae3444a211f339c2dcb5dcf26950b31f6f98697b09977f233fe0e23049a245f2ba1b3262b6104caf27b37e254ea5c829fc30f2daea675250ed4988a
7
+ data.tar.gz: 22400ed6fd5ace6f4772ca8b1c0ddb5a98e99be0d38fdeac42a8bce900d7cf65226e44c399fd38e1174770d1f040a0a98b4bd0589751fa27194443fa17591c3d
@@ -4,14 +4,13 @@ script: "bundle exec rspec spec"
4
4
  sudo: false
5
5
  cache: bundler
6
6
  rvm:
7
- - 2.0.0
8
- - 2.1.0
9
- - 2.1.1
10
- - 2.2.1
11
- - ruby-head
12
- - jruby
13
- - rbx-2
7
+ - 2.0
8
+ - 2.1
9
+ - 2.2.4
10
+ - 2.3.0
11
+ - jruby-9.0.4.0
12
+ - rbx-2
14
13
  matrix:
15
14
  allow_failures:
16
- - rvm: jruby
17
- - rvm: ruby-head
15
+ - rvm: jruby-9.0.4.0
16
+ - rvm: rbx-2
data/CHANGES.md CHANGED
@@ -1,3 +1,72 @@
1
+ 0.8.2
2
+ -----
3
+ * Allow PersistenceStrategy set by property config [Tom Johnson]
4
+ * Extend NodeConfig for arbitrary properties [Tom Johnson]
5
+ * Add `Relation#delete?` and `#swap` [Tom Johnson]
6
+ * Make Relation#delete singular; add #subtract [Tom Johnson]
7
+ * Re-add `Relation#delete` with a new implementation [Tom Johnson]
8
+ * Documentation and formatting cleanup on Relation [Tom Johnson]
9
+ * Remove Relation#reset! [Tom Johnson]
10
+ * Remove `Relation#[]=` [Tom Johnson]
11
+ * Remove Relation#delete [Tom Johnson]
12
+ * FIX #200 Use == instead of eql? for resource equality test [E. Lynette Rayle]
13
+ * Add some docs and tests for `PropertyBuilder` [Tom Johnson]
14
+ * Test undefined property on Relation#set [Tom Johnson]
15
+ * add loaded flag to lazy load property sources with parent_strategy [E. Lynette Rayle]
16
+ * Add deprecation warning [MJ Suhonos]
17
+ * Rename #obj to #source for clarity [MJ Suhonos]
18
+ * Update Guardfile [MJ Suhonos]
19
+ * Update comment terminology [MJ Suhonos]
20
+ * Remove reference to concrete persistable from abstract class [MJ Suhonos]
21
+ * Allow fetch to pass args to RDF::Reader.open [Justin Coyne]
22
+ * Delegate join to Relation. [Trey Terrell]
23
+ * Change ParentStrategy usage [Tom Johnson]
24
+ * Delegate #size in Relation. [Trey Terrell]
25
+ * Remove singleton_class call from RepositoryStrategy [Tom Johnson]
26
+ * Convert ancestors enumerator method to Class [Tom Johnson]
27
+ * Avoid circularity in `ParentStrategy` [Tom Johnson]
28
+ * Update .travis.yml Rubies to match RDF.rb [Tom Johnson]
29
+ * Add frozen_string_literals pragma [Justin Coyne]
30
+ * Fixup specs [Tom Johnson]
31
+ * Specs/docs for ValueError scenarios on #set_value [Tom Johnson]
32
+ * Add initial docs/specs for `RDFSource#attributes` [Tom Johnson]
33
+ * Add docs and specs for `Relation#first_or_create` [Tom Johnson]
34
+ * Add tests & docs for `Relation#build` [Tom Johnson]
35
+ * Make `Relation#clear` atomic [Tom Johnson]
36
+ * Test `RDFSource#rdf_label` [Tom Johnson]
37
+ * Fix for circular parent relationships [Tom Johnson]
38
+ * Add documentation and tests for key Relation [Tom Johnson]
39
+ * Refactor Relation#value_arguments [Tom Johnson]
40
+ * Move property methods from RDFSource in Properties [Tom Johnson]
41
+ * Add documentation and some tests for Properties [Tom Johnson]
42
+ * Refactor and rearrange RDFSource & Reflection [Tom Johnson]
43
+ * Finish documentation and testing of Reflection [Tom Johnson]
44
+ * Cleaner handling of undefined properties [Tom Johnson]
45
+ * Add some tests for `#get_values` [Tom Johnson]
46
+ * Make `#set_value` return the Relation it updates [Tom Johnson]
47
+ * Add triple in `#set_value` when argument is self [Tom Johnson]
48
+ * Removes odd logic surrounding property clearance [Tom Johnson]
49
+ * Removing OpenStruct in favor of PORO [Jeremy Friesen]
50
+ * Switching from Array() to Array.wrap [Jeremy Friesen]
51
+ * Fixup RDF.rb and rdf-spec dependencies [Tom Johnson]
52
+ * Track latest `rdf-spec` and `rdf-vocab` [Tom Johnson]
53
+ * Complete update to use RDF::Vocab [Tom Johnson]
54
+ * Use rdf-vocab for vocabularies [Justin Coyne]
55
+ * Add `RDFSource#graph_name` since quads aren't returned [Tom Johnson]
56
+ * Update specs to use a managable invalid statement [Tom Johnson]
57
+ * Test with develop version of rdf-spec [Justin Coyne]
58
+ * Graph#query is faster than using Queryable#query [Justin Coyne]
59
+ * Update error handling specs. [Tom Johnson]
60
+ * Adds a default block to `RDFSource#fetch` [Tom Johnson]
61
+ * Run `ActiveModel` lints on `RDFSource` [Tom Johnson]
62
+ * Fix ActiveModel linter to test `#to_key` [Tom Johnson]
63
+ * Remove unnecessary lines in `parent_strategy_spec` [Tom Johnson]
64
+ * Make `Relation#predicate` a public method [Tom Johnson]
65
+ * Cleanup and unit tests for `RDFSource#get_value` [Tom Johnson]
66
+ * Test ActiveModel validations with RDF's `#valid?` [Tom Johnson]
67
+ * Children should not be persisted? unless their parents are. Fixes #148 [Justin Coyne]
68
+
69
+
1
70
  0.8.1
2
71
  -----
3
72
 
data/Gemfile CHANGED
@@ -3,5 +3,3 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem 'pry-byebug' unless ENV["CI"]
6
-
7
- gem 'rdf-spec', :github => 'ruby-rdf/rdf-spec', :branch => 'develop'
data/Guardfile CHANGED
@@ -1,9 +1,8 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard :rspec do
4
+ guard :rspec, cmd: "bundle exec rspec" do
5
5
  watch(%r{^spec/.+_spec\.rb$})
6
6
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
7
  watch('spec/spec_helper.rb') { "spec" }
8
8
  end
9
-
@@ -14,15 +14,15 @@ Gem::Specification.new do |s|
14
14
  s.license = "APACHE2"
15
15
  s.required_ruby_version = '>= 1.9.3'
16
16
 
17
- s.add_dependency('rdf', '~> 1.1.13')
18
- s.add_dependency('linkeddata', '~> 1.1')
17
+ s.add_dependency('rdf', '1.99')
18
+ s.add_dependency('linkeddata', '~> 1.99')
19
19
  s.add_dependency('activemodel', '>= 3.0.0')
20
20
  s.add_dependency('deprecation', '~> 0.1')
21
21
  s.add_dependency('activesupport', '>= 3.0.0')
22
22
 
23
23
  s.add_development_dependency('rdoc')
24
24
  s.add_development_dependency('rspec')
25
- s.add_development_dependency('rdf-spec')
25
+ s.add_development_dependency('rdf-spec', '~> 1.99')
26
26
  s.add_development_dependency('coveralls')
27
27
  s.add_development_dependency('guard-rspec')
28
28
  s.add_development_dependency('webmock')
@@ -1 +1,2 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_triples'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'rdf'
2
3
  require 'active_triples/version'
3
4
  require 'active_support'
@@ -53,6 +54,9 @@ module ActiveTriples
53
54
  'active_triples/persistence_strategies/parent_strategy'
54
55
  autoload :RepositoryStrategy,
55
56
  'active_triples/persistence_strategies/repository_strategy'
57
+
58
+ # error classes
59
+ autoload :UndefinedPropertyError
56
60
  end
57
61
 
58
62
  ##
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require 'deprecation'
3
+ require 'active_support/core_ext/array/wrap'
2
4
 
3
5
  module ActiveTriples
4
6
  ##
@@ -61,7 +63,7 @@ module ActiveTriples
61
63
  end
62
64
 
63
65
  def transform_type(values)
64
- Array(values).map do |value|
66
+ Array.wrap(values).map do |value|
65
67
  RDF::URI.new(value).tap do |uri|
66
68
  RDFSource.type_registry[uri] = self
67
69
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  require_relative 'configuration/item'
3
4
  require_relative 'configuration/merge_item'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  class Configuration
3
4
  # Basic configuration item which overrides the value for a key on the object.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  class Configuration
3
4
  ## Returns a configuration item appropriate for a given configuration property.
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+ require 'active_support/core_ext/array/wrap'
3
+
1
4
  module ActiveTriples
2
5
  class Configuration
3
6
  # Configuration item which sets a value by turning the original into an array and
@@ -6,8 +9,8 @@ module ActiveTriples
6
9
  # This enables multiple types to be set on an object, for example.
7
10
  class MergeItem < Item
8
11
  def set(value)
9
- object.inner_hash[key] = Array(object.inner_hash[key])
10
- object.inner_hash[key] |= Array(value)
12
+ object.inner_hash[key] = Array.wrap(object.inner_hash[key])
13
+ object.inner_hash[key] |= Array.wrap(value)
11
14
  end
12
15
  end
13
16
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  ##
3
4
  # Default property applying strategy which just copies all configured properties
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support'
2
3
  require 'active_support/core_ext/module/delegation'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  ##
3
4
  # An implementation of RDF::List intregrated with ActiveTriples.
@@ -162,6 +163,7 @@ module ActiveTriples
162
163
  if subject == RDF.nil
163
164
  @subject = RDF::Node.new
164
165
  @graph = ListResource.new(subject)
166
+ @graph.list = self
165
167
  @graph.type = RDF.List
166
168
  end
167
169
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support'
2
3
  require 'active_support/concern'
3
4
  require 'active_support/core_ext/class'
@@ -121,7 +122,6 @@ module ActiveTriples
121
122
  assign_nested_attributes_for_collection_association(:#{association_name}, attributes)
122
123
  ## in lieu of autosave_association_callbacks just save all of em.
123
124
  send(:#{association_name}).each {|obj| obj.marked_for_destruction? ? obj.destroy : nil}
124
- send(:#{association_name}).reset!
125
125
  end
126
126
  eoruby
127
127
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  class NodeConfig
3
4
  attr_accessor :predicate, :term, :class_name, :type, :behaviors, :cast
@@ -5,14 +6,15 @@ module ActiveTriples
5
6
  def initialize(term, predicate, args={})
6
7
  self.term = term
7
8
  self.predicate = predicate
8
- self.class_name = args.fetch(:class_name) { default_class_name }
9
- self.cast = args.fetch(:cast) { true }
9
+ self.class_name = args.delete(:class_name) { default_class_name }
10
+ self.cast = args.delete(:cast) { true }
11
+ @opts = args
10
12
  yield(self) if block_given?
11
13
  end
12
14
 
13
15
  def [](value)
14
16
  value = value.to_sym
15
- self.respond_to?(value) ? self.send(value) : nil
17
+ self.respond_to?(value) ? self.send(value) : @opts[value]
16
18
  end
17
19
 
18
20
  def class_name
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  ##
3
4
  # Bundles the core interfaces used by ActiveTriples persistence strategies
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveTriples
2
3
  ##
3
4
  # Persistence strategy for projecting `RDFSource`s onto the graph of an owning
@@ -6,50 +7,76 @@ module ActiveTriples
6
7
  class ParentStrategy
7
8
  include PersistenceStrategy
8
9
 
9
- # @!attribute [r] obj
10
+ # @!attribute [r] source
10
11
  # the source to persist with this strategy
11
12
  # @!attribute [r] parent
12
13
  # the target parent source for persistence
13
- attr_reader :obj, :parent
14
+ attr_reader :source, :parent
14
15
 
15
16
  ##
16
- # @param obj [RDFSource, RDF::Enumerable] the `RDFSource` (or other
17
+ # @param source [RDFSource, RDF::Enumerable] the `RDFSource` (or other
17
18
  # `RDF::Enumerable` to persist with the strategy.
18
- def initialize(obj)
19
- @obj = obj
19
+ def initialize(source)
20
+ @source = source
20
21
  end
21
22
 
23
+ ##
24
+ # Resources using this strategy are persisted only if their parent is also
25
+ # persisted.
26
+ #
27
+ # @see PersistenceStrategy#persisted?
28
+ def persisted?
29
+ super && parent.persisted?
30
+ end
31
+
32
+ ##
33
+ # Indicates if the resource has been loaded from the repository (used for lazy load)
34
+ #
35
+ # @return [Boolean] true if loaded; else false.
36
+ def loaded?
37
+ @loaded ||= false
38
+ end
39
+
40
+ ##
41
+ # Destroys the resource by removing it graph and references from the
42
+ # parent.
43
+ #
44
+ # @see PersistenceStrategy#destroy
22
45
  def destroy
23
- super { parent.destroy_child(obj) }
46
+ final_parent.delete(source.statements)
47
+
48
+ parent.statements.each do |statement|
49
+ parent.delete_statement(statement) if
50
+ statement.subject == source.rdf_subject ||
51
+ statement.object == source.rdf_subject
52
+ end
53
+
54
+ super { source.clear }
24
55
  end
25
56
 
26
- # Clear out any old assertions in the repository about this node or statement
27
- # thus preparing to receive the updated assertions.
57
+ ##
58
+ # @abstract Clear out any old assertions in the datastore / repository
59
+ # about this node or statement thus preparing to receive the updated
60
+ # assertions.
28
61
  def erase_old_resource
29
- if obj.rdf_subject.node?
30
- final_parent.statements.each do |statement|
31
- final_parent.send(:delete_statement, statement) if
32
- statement.subject == obj.rdf_subject
33
- end
34
- else
35
- final_parent.delete [obj.rdf_subject, nil, nil]
62
+ final_parent.statements.each do |statement|
63
+ final_parent.send(:delete_statement, statement) if
64
+ statement.subject == source.rdf_subject
36
65
  end
37
66
  end
38
67
 
68
+ ##
69
+ # @return [Enumerator<RDFSource>]
70
+ def ancestors
71
+ Ancestors.new(source).to_enum
72
+ end
73
+
39
74
  ##
40
75
  # @return [#persist!] the last parent in a chain from `parent` (e.g.
41
76
  # the parent's parent's parent). This is the RDF::Mutable that the
42
- # object will project itself on when persisting.
77
+ # resource will project itself on when persisting.
43
78
  def final_parent
44
- raise NilParentError if parent.nil?
45
- @final_parent ||= begin
46
- current = self.parent
47
- while current && current.respond_to?(:parent) && current.parent
48
- break if current.parent == current
49
- current = current.parent
50
- end
51
- current
52
- end
79
+ ancestors.to_a.last
53
80
  end
54
81
 
55
82
  ##
@@ -64,12 +91,12 @@ module ActiveTriples
64
91
  end
65
92
 
66
93
  ##
67
- # Persists the object to the final parent.
94
+ # Persists the resource to the final parent.
68
95
  #
69
96
  # @return [true] true if the save did not error
70
97
  def persist!
71
98
  erase_old_resource
72
- final_parent << obj
99
+ final_parent << source
73
100
  @persisted = true
74
101
  end
75
102
 
@@ -78,11 +105,59 @@ module ActiveTriples
78
105
  #
79
106
  # @return [Boolean]
80
107
  def reload
81
- obj << final_parent.query(subject: obj.rdf_subject)
82
- @persisted = true unless obj.empty?
108
+ if loaded? || !persisted?
109
+ source << final_parent.query(subject: source.rdf_subject)
110
+ else
111
+ RepositoryStrategy.new(source).reload
112
+ source.persist!
113
+ @loaded=true
114
+ end
115
+ @persisted = true unless source.empty?
83
116
  true
84
117
  end
85
118
 
119
+ ##
120
+ # An enumerable over the ancestors of an resource
121
+ class Ancestors
122
+ include Enumerable
123
+
124
+ # @!attribute source
125
+ # @return [RDFSource]
126
+ attr_reader :source
127
+
128
+ ##
129
+ # @param source [RDFSource]
130
+ def initialize(source)
131
+ @source = source
132
+ end
133
+
134
+ ##
135
+ # @yield [RDFSource] gives each ancestor to the block
136
+ # @return [Enumerator<RDFSource>]
137
+ #
138
+ # @raise [NilParentError] if `source` does not persist to a parent
139
+ def each
140
+ raise NilParentError if
141
+ !source.persistence_strategy.respond_to?(:parent) ||
142
+ source.persistence_strategy.parent.nil?
143
+
144
+ current = source.persistence_strategy.parent
145
+
146
+ if block_given?
147
+ loop do
148
+ yield current
149
+
150
+ break unless (current.persistence_strategy.respond_to?(:parent) &&
151
+ current.persistence_strategy.parent)
152
+ break if current.persistence_strategy.parent == current
153
+
154
+ current = current.persistence_strategy.parent
155
+ end
156
+ end
157
+ to_enum
158
+ end
159
+ end
160
+
86
161
  class NilParentError < RuntimeError; end
87
162
  class UnmutableParentError < ArgumentError; end
88
163
  end