diff --git a/Gemfile b/Gemfile index 30854d4..58b70e2 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,6 @@ -source "https://rubygems.org" +# frozen_string_literal: true + +source 'https://rubygems.org' gemspec diff --git a/Guardfile b/Guardfile index 7a5f79b..d895f99 100644 --- a/Guardfile +++ b/Guardfile @@ -1,8 +1,10 @@ +# frozen_string_literal: true + # A sample Guardfile # More info at https://github.com/guard/guard#readme -guard :rspec, cmd: "bundle exec rspec" do +guard :rspec, cmd: 'bundle exec rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec" } + watch('spec/spec_helper.rb') { 'spec' } end diff --git a/Rakefile b/Rakefile index 7216f03..91e41f8 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,6 @@ +# frozen_string_literal: true + require 'rake/clean' require 'bundler' Bundler::GemHelper.install_tasks - diff --git a/active-triples.gemspec b/active-triples.gemspec index bae75c8..5716c6e 100644 --- a/active-triples.gemspec +++ b/active-triples.gemspec @@ -1,41 +1,43 @@ -# -*- encoding: utf-8 -*- -$:.push File.expand_path("../lib", __FILE__) -require "active_triples/version" +# frozen_string_literal: true + +$LOAD_PATH.push File.expand_path('lib', __dir__) +require 'active_triples/version' Gem::Specification.new do |s| - s.name = "active-triples" + s.name = 'active-triples' s.version = ActiveTriples::VERSION s.platform = Gem::Platform::RUBY - s.authors = ["Tamsin Johnson", "Trey Pendragon"] - s.homepage = 'https://gitlab.com/no_reply/ActiveTriples' + s.authors = ['Tamsin Johnson', 'Trey Pendragon'] + s.homepage = 'https://github.com/ActiveTriples/ActiveTriples' s.email = 'tomjohnson@ucsb.edu' s.summary = %q{RDF graphs in ActiveModel wrappers.} s.description = %q{ActiveTriples provides tools for modeling RDF as discrete resources.} s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.1.0' - s.add_dependency 'rdf', '>= 2.0.2', '< 4.0' - s.add_dependency 'rdf-vocab', '>= 2.0', '< 4.0' - s.add_dependency 'activemodel', '>= 3.0.0' + s.add_dependency 'activemodel', '>= 3.0.0' s.add_dependency 'activesupport', '>= 3.0.0' + s.add_dependency 'rdf', '~> 3.2', '< 4.0' + s.add_dependency 'rdf-vocab', '~> 3.2', '< 4.0' - s.add_development_dependency 'yard', '~> 0.9' - s.add_development_dependency 'rspec', '~> 3.6' - s.add_development_dependency 'guard-rspec', '~> 4.7' - s.add_development_dependency 'rdf-spec', '~> 3.0' - s.add_development_dependency 'rdf-rdfxml', '>= 2.0', '< 4.0' - s.add_development_dependency 'rdf-turtle', '>= 2.0', '< 4.0' - s.add_development_dependency 'json-ld', '>= 2.0', '< 4.0' + s.add_development_dependency 'bixby' s.add_development_dependency 'coveralls', '~> 0.8' - s.add_development_dependency 'webmock', '~> 3.0' + s.add_development_dependency 'guard-rspec', '~> 4.7' + s.add_development_dependency 'json-ld', '~> 3.2', '< 4.0' s.add_development_dependency 'nokogiri', '~> 1.8' s.add_development_dependency 'pragmatic_context', '~> 0.1.2' + s.add_development_dependency 'pry-byebug' + s.add_development_dependency 'rdf-rdfxml', '~> 3.2', '< 4.0' + s.add_development_dependency 'rdf-spec', '~> 3.2', '< 4.0' + s.add_development_dependency 'rdf-turtle', '~> 3.2', '< 4.0' + s.add_development_dependency 'rspec', '~> 3.6' + s.add_development_dependency 'webmock', '~> 3.0' + s.add_development_dependency 'yard', '~> 0.9' s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {spec}/*`.split("\n") s.extra_rdoc_files = [ - "LICENSE", - "README.md" + 'LICENSE', + 'README.md' ] end diff --git a/lib/active/triples.rb b/lib/active/triples.rb index 22b737b..2ce22e0 100644 --- a/lib/active/triples.rb +++ b/lib/active/triples.rb @@ -1,2 +1,3 @@ # frozen_string_literal: true + require 'active_triples' diff --git a/lib/active_triples.rb b/lib/active_triples.rb index 9de596b..2e846df 100644 --- a/lib/active_triples.rb +++ b/lib/active_triples.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true -require 'rdf' -require 'active_triples/version' + require 'active_support' +require 'active_triples/version' +require 'rdf' ## -# An ActiveModel compliant ObjectGraphMapper for RDF data. -# -# Models graphs as `RDFSources` with property/attribute configuration, -# accessors, and other methods to support Linked Data in a Ruby enviornment. +# An ActiveModel compliant ObjectGraphMapper for RDF data. +# +# Models graphs as `RDFSources` with property/attribute configuration, +# accessors, and other methods to support Linked Data in a Ruby enviornment. # # @example modeling a simple resource # class Thing @@ -20,11 +21,11 @@ # obj = Thing.new('123') # obj.title = 'Resource' # obj.description = 'A resource.' -# obj.dump :ntriples +# obj.dump :ntriples # # => " .\n \"Resource\" .\n \"A resource.\" .\n" # -# @see http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/#change-over-time -# RDF Concepts and Abstract Syntax for an informal definition of an RDF +# @see http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/#change-over-time +# RDF Concepts and Abstract Syntax for an informal definition of an RDF # Source. module ActiveTriples extend ActiveSupport::Autoload @@ -58,7 +59,7 @@ module ActiveTriples # error classes autoload :UndefinedPropertyError end - + ## # Raised when a declared repository doesn't have a definition class RepositoryNotFoundError < StandardError @@ -72,18 +73,18 @@ class RepositoryNotFoundError < StandardError # ActiveTriples.class_from_string('MyClass') # => MyClass # # @example finding a class in a module - # ActiveTriples.class_from_string('MyClass', MyModule) + # ActiveTriples.class_from_string('MyClass', MyModule) # # => MyModule::MyClass # # @example when a class exists above the module, but not in it - # ActiveTriples.class_from_string('Object', MyModule) + # ActiveTriples.class_from_string('Object', MyModule) # # => Object # # @param class_name [String] # @param container_class # # @return [Class] - def self.class_from_string(class_name, container_class=Kernel) + def self.class_from_string(class_name, container_class = Kernel) container_class = container_class.name if container_class.is_a? Module container_parts = container_class.split('::') (container_parts + class_name.split('::')) @@ -114,7 +115,7 @@ def self.ActiveTripels / \\ ,---------. -eos -"Yum" + eos + 'Yum' end end diff --git a/lib/active_triples/configurable.rb b/lib/active_triples/configurable.rb index 7e524c2..fc15d9b 100644 --- a/lib/active_triples/configurable.rb +++ b/lib/active_triples/configurable.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'active_support/core_ext/array/wrap' module ActiveTriples @@ -15,7 +16,7 @@ module ActiveTriples # Available properties are base_uri, rdf_label, type, and repository module Configurable def inherited(child_class) - child_class.configure type: self.type + child_class.configure type: type super end @@ -57,9 +58,7 @@ def repository # @param options [Hash] def configure(options = {}) options = options.map do |key, value| - if self.respond_to?("transform_#{key}") - value = self.__send__("transform_#{key}", value) - end + value = __send__("transform_#{key}", value) if respond_to?("transform_#{key}") [key, value] end @configuration = configuration.merge(options) diff --git a/lib/active_triples/configuration.rb b/lib/active_triples/configuration.rb index 652c523..4913658 100644 --- a/lib/active_triples/configuration.rb +++ b/lib/active_triples/configuration.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples require_relative 'configuration/item' require_relative 'configuration/merge_item' @@ -10,8 +11,8 @@ class Configuration attr_accessor :inner_hash ## - # @param item_factory [ItemFactory] # @param [Hash] options the configuration options. (Ruby 3+) + # @param item_factory [ItemFactory] # @param [Hash] options2 the configuration options. (Ruby 2.x) def initialize(options = {}, item_factory: ItemFactory.new, **options2) @item_factory = item_factory @@ -73,9 +74,9 @@ def build_configuration_item(key) end private - - CONFIG_OPTIONS = [:base_uri, :rdf_label, :type, :repository].freeze - + + CONFIG_OPTIONS = %i[base_uri rdf_label type repository].freeze + attr_reader :item_factory def valid_config_options diff --git a/lib/active_triples/configuration/item.rb b/lib/active_triples/configuration/item.rb index 3e168dd..5ac79aa 100644 --- a/lib/active_triples/configuration/item.rb +++ b/lib/active_triples/configuration/item.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples class Configuration # Basic configuration item which overrides the value for a key on the object. diff --git a/lib/active_triples/configuration/item_factory.rb b/lib/active_triples/configuration/item_factory.rb index 0708e4d..3434e05 100644 --- a/lib/active_triples/configuration/item_factory.rb +++ b/lib/active_triples/configuration/item_factory.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples class Configuration ## Returns a configuration item appropriate for a given configuration property. diff --git a/lib/active_triples/configuration/merge_item.rb b/lib/active_triples/configuration/merge_item.rb index 1874752..4c930b1 100644 --- a/lib/active_triples/configuration/merge_item.rb +++ b/lib/active_triples/configuration/merge_item.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'active_support/core_ext/array/wrap' module ActiveTriples diff --git a/lib/active_triples/extension_strategy.rb b/lib/active_triples/extension_strategy.rb index 20abf0c..ef4735f 100644 --- a/lib/active_triples/extension_strategy.rb +++ b/lib/active_triples/extension_strategy.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # Default property applying strategy which just copies all configured properties diff --git a/lib/active_triples/identifiable.rb b/lib/active_triples/identifiable.rb index c1415d6..3c30411 100644 --- a/lib/active_triples/identifiable.rb +++ b/lib/active_triples/identifiable.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'active_support' require 'active_support/core_ext/module/delegation' @@ -11,7 +12,7 @@ module ActiveTriples::Identifiable # @return [ActiveTriples::Resource] a resource that contains this object's # graph. def resource - @resource ||= resource_class.new(to_uri) + @resource ||= resource_class.new(to_uri) end def parent @@ -25,27 +26,26 @@ def parent=(val) ## # @return [String] a uri or slug def to_uri - return id if respond_to? :id and !resource_class.base_uri.nil? + return id if respond_to?(:id) && !resource_class.base_uri.nil? + raise NotImplementedError end private - def resource_class - self.class.resource_class - end - - public - module ClassMethods + def resource_class + self.class.resource_class + end - delegate :configure, :property, :properties, to: :resource_class + module ClassMethods + delegate :configure, :property, :properties, to: :resource_class - def resource_class - @resource_class ||= self.const_set(:GeneratedResourceSchema, Class.new(ActiveTriples::Resource)) - end + def resource_class + @resource_class ||= const_set(:GeneratedResourceSchema, Class.new(ActiveTriples::Resource)) + end - def from_uri(uri, *args) - raise NotImplementedError - end + def from_uri(uri, *args) + raise NotImplementedError end + end end diff --git a/lib/active_triples/list.rb b/lib/active_triples/list.rb index 2f53691..5e71e12 100644 --- a/lib/active_triples/list.rb +++ b/lib/active_triples/list.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # An implementation of RDF::List intregrated with ActiveTriples. @@ -13,12 +14,12 @@ class List < RDF::List include Reflection delegate :rdf_subject, :mark_for_destruction, :marked_for_destruction?, :set_value, :get_values, :parent, :persist, :persist!, :type, :dump, :attributes=, to: :resource - alias_method :to_ary, :to_a + alias to_ary to_a class << self def from_uri(uri, vals) list = ListResource.from_uri(uri, vals) - self.new(subject: list.rdf_subject, graph: list) + new(subject: list.rdf_subject, graph: list) end end @@ -29,7 +30,7 @@ def resource def initialize(subject: nil, graph: nil, values: nil, &block) super @graph = ListResource.new(subject) unless - graph.kind_of? RDFSource + graph.is_a? RDFSource @graph << parent if parent @graph.list = self @graph.reload @@ -55,6 +56,7 @@ def []=(idx, value) end each_subject.with_index do |v, i| next unless i == idx + resource.set_value(v, RDF.first, value) end end @@ -64,6 +66,7 @@ def []=(idx, value) # appropriate. def each(&block) return super unless block_given? + super { |value| yield node_from_value(value) } end @@ -103,14 +106,15 @@ def reflections end def attributes=(values) - raise ArgumentError, "values must be a Hash, you provided #{values.class}" unless values.kind_of? Hash + raise ArgumentError, "values must be a Hash, you provided #{values.class}" unless values.is_a? Hash + values.with_indifferent_access.each do |key, value| - if reflections.properties.keys.map { |k| "#{k}_attributes" }.include?(key) - klass = reflections.reflect_on_property(key[0..-12])['class_name'] - klass = ActiveTriples.class_from_string(klass, final_parent.class) if klass.is_a? String - value.is_a?(Hash) ? attributes_hash_to_list(values[key], klass) : attributes_to_list(value, klass) - values.delete key - end + next unless reflections.properties.keys.map { |k| "#{k}_attributes" }.include?(key) + + klass = reflections.reflect_on_property(key[0..-12])['class_name'] + klass = ActiveTriples.class_from_string(klass, final_parent.class) if klass.is_a? String + value.is_a?(Hash) ? attributes_hash_to_list(values[key], klass) : attributes_to_list(value, klass) + values.delete key end super end @@ -125,21 +129,21 @@ def erase_old_resource private - def attributes_to_list(value, klass) - value.each do |entry| - item = klass.new() - item.attributes = entry - list << item - end + def attributes_to_list(value, klass) + value.each do |entry| + item = klass.new + item.attributes = entry + list << item end + end - def attributes_hash_to_list(value, klass) - value.each do |counter, attr| - item = klass.new() - item.attributes = attr if attr - list[counter.to_i] = item - end + def attributes_hash_to_list(value, klass) + value.each do |counter, attr| + item = klass.new + item.attributes = attr if attr + list[counter.to_i] = item end + end end ## @@ -150,10 +154,10 @@ def attributes_hash_to_list(value, klass) # @NOTE Lists built this way will return false for #valid? def <<(value) value = case value - when nil then RDF.nil - when RDF::Value then value - when Array then RDF::List.new(nil, graph, value) - else value + when nil then RDF.nil + when RDF::Value then value + when Array then RDF::List.new(nil, graph, value) + else value end if subject == RDF.nil @@ -167,11 +171,11 @@ def <<(value) @graph.type = RDF.List resource.set_value(RDF.first, value) resource.insert([subject.to_term, RDF.rest, RDF.nil]) - resource << value if value.kind_of? RDFSource + resource << value if value.is_a? RDFSource return self end super - if value.kind_of? RDFSource + if value.is_a? RDFSource resource << value value.set_persistence_strategy(ParentStrategy) value.persistence_strategy.parent = resource diff --git a/lib/active_triples/nested_attributes.rb b/lib/active_triples/nested_attributes.rb index 75b4eb5..6839b47 100644 --- a/lib/active_triples/nested_attributes.rb +++ b/lib/active_triples/nested_attributes.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'active_support' require 'active_support/concern' require 'active_support/core_ext/class' @@ -8,13 +9,13 @@ module NestedAttributes extend ActiveSupport::Concern included do - class_attribute :nested_attributes_options, :instance_writer => false + class_attribute :nested_attributes_options, instance_writer: false self.nested_attributes_options = {} end private - UNASSIGNABLE_KEYS = %w(_destroy ) + UNASSIGNABLE_KEYS = %w[_destroy].freeze # @param [Symbol] association_name # @param [Hash, Array] attributes_collection @@ -37,23 +38,23 @@ module NestedAttributes # { name: 'John' }, # { id: '2', _destroy: true } # ]) - def assign_nested_attributes_for_collection_association(association_name, + def assign_nested_attributes_for_collection_association(association_name, attributes_collection) - options = self.nested_attributes_options[association_name] + options = nested_attributes_options[association_name] # TODO - #check_record_limit!(options[:limit], attributes_collection) + # check_record_limit!(options[:limit], attributes_collection) - attributes_collection = attributes_collection.values if + attributes_collection = attributes_collection.values if attributes_collection.is_a?(Hash) - association = self.send(association_name) + association = send(association_name) attributes_collection.each do |attributes| attributes = attributes.with_indifferent_access - if !call_reject_if(association_name, attributes) - if attributes['id'] && + unless call_reject_if(association_name, attributes) + if attributes['id'] && existing_record = association.detect { |record| record.rdf_subject.to_s == attributes['id'].to_s } assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) else @@ -68,13 +69,14 @@ def assign_nested_attributes_for_collection_association(association_name, def assign_to_or_mark_for_destruction(record, attributes, allow_destroy) record.attributes = attributes.except(*UNASSIGNABLE_KEYS) - record.mark_for_destruction if has_destroy_flag?(attributes) && + record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy end def call_reject_if(association_name, attributes) return false if has_destroy_flag?(attributes) - case callback = self.nested_attributes_options[association_name][:reject_if] + + case callback = nested_attributes_options[association_name][:reject_if] when Symbol method(callback).arity == 0 ? send(callback) : send(callback, attributes) when Proc @@ -84,12 +86,12 @@ def call_reject_if(association_name, attributes) # Determines if a hash contains a truthy _destroy key. def has_destroy_flag?(hash) - ["1", "true"].include?(hash['_destroy'].to_s) + %w[1 true].include?(hash['_destroy'].to_s) end module ClassMethods - def accepts_nested_attributes_for *attr_names - options = { :allow_destroy => false, :update_only => false } + def accepts_nested_attributes_for(*attr_names) + options = { allow_destroy: false, update_only: false } options.update(attr_names.extract_options!) options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only) options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank @@ -126,9 +128,8 @@ def #{association_name}_attributes=(attributes) ## in lieu of autosave_association_callbacks just save all of em. send(:#{association_name}).each {|obj| obj.marked_for_destruction? ? obj.destroy : nil} end - eoruby + eoruby end end end end - diff --git a/lib/active_triples/node_config.rb b/lib/active_triples/node_config.rb index deb1f43..dda1f84 100644 --- a/lib/active_triples/node_config.rb +++ b/lib/active_triples/node_config.rb @@ -28,7 +28,7 @@ class NodeConfig # # @yield yields self to the block # @yieldparam config [NodeConfig] self - def initialize(term, predicate, opts={}) + def initialize(term, predicate, opts = {}) self.term = term self.predicate = predicate self.class_name = opts.delete(:class_name) { nil } @@ -42,13 +42,16 @@ def initialize(term, predicate, opts={}) # @return [Object] the attribute or option represented by the symbol def [](value) value = value.to_sym - self.respond_to?(value) ? self.public_send(value) : @opts[value] + respond_to?(value) ? public_send(value) : @opts[value] end def class_name return nil if @class_name.nil? - raise "class_name for #{term} is a #{@class_name.class}; must be a class" unless @class_name.kind_of? Class or @class_name.kind_of? String - if @class_name.kind_of?(String) + unless @class_name.is_a?(Class) || @class_name.is_a?(String) + raise "class_name for #{term} is a #{@class_name.class}; must be a class" + end + + if @class_name.is_a?(String) begin new_class = @class_name.constantize @class_name = new_class @@ -61,7 +64,7 @@ def class_name ## # @yield yields an index configuration object # @yieldparam index [NodeConfig::IndexObject] - def with_index(&block) + def with_index # needed for solrizer integration iobj = IndexObject.new yield iobj @@ -74,8 +77,8 @@ def with_index(&block) ## # @deprecated Use `nil` instead. def default_class_name - warn 'DEPRECATION: `ActiveTriples::NodeConfig#default_class_name` ' \ - 'will be removed in 1.0. Use `nil`.' + warn 'DEPRECATION: `ActiveTriples::NodeConfig#default_class_name` ' \ + 'will be removed in 1.0. Use `nil`.' nil end diff --git a/lib/active_triples/persistable.rb b/lib/active_triples/persistable.rb index e670597..09747ef 100644 --- a/lib/active_triples/persistable.rb +++ b/lib/active_triples/persistable.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # Bundles the core interfaces used by ActiveTriples persistence strategies @@ -61,7 +62,7 @@ def set_persistence_strategy(klass) def destroy persistence_strategy.destroy end - alias_method :destroy!, :destroy + alias destroy! destroy ## # @return [Boolean] true if this item is destroyed @@ -74,9 +75,10 @@ def destroyed? # `Persistable`. # # @return [Boolean] - def persist!(opts={}) + def persist!(opts = {}) result = false return result if opts[:validate] && !valid? + run_callbacks :persist do result = persistence_strategy.persist! end diff --git a/lib/active_triples/persistence_strategies/parent_strategy.rb b/lib/active_triples/persistence_strategies/parent_strategy.rb index db28769..3bb563e 100644 --- a/lib/active_triples/persistence_strategies/parent_strategy.rb +++ b/lib/active_triples/persistence_strategies/parent_strategy.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'active_triples/util/buffered_transaction' module ActiveTriples @@ -28,8 +29,8 @@ def initialize(source) def graph=(graph) final_parent.insert(graph || source.to_a) @graph = BufferedTransaction.begin(parent, - mutable: true, - subject: source.to_term) + mutable: true, + subject: source.to_term) end ## @@ -40,8 +41,8 @@ def graph=(graph) # @see ActiveTriples::ExtendedBoundedDescription def graph @graph ||= BufferedTransaction.begin(parent, - mutable: true, - subject: source.to_term) + mutable: true, + subject: source.to_term) end ## @@ -163,8 +164,8 @@ def each loop do yield current - break unless (current.persistence_strategy.respond_to?(:parent) && - current.persistence_strategy.parent) + break unless current.persistence_strategy.respond_to?(:parent) && + current.persistence_strategy.parent break if current.persistence_strategy.parent == current current = current.persistence_strategy.parent diff --git a/lib/active_triples/persistence_strategies/persistence_strategy.rb b/lib/active_triples/persistence_strategies/persistence_strategy.rb index 8f46b9d..4b41089 100644 --- a/lib/active_triples/persistence_strategies/persistence_strategy.rb +++ b/lib/active_triples/persistence_strategies/persistence_strategy.rb @@ -1,17 +1,18 @@ # frozen_string_literal: true + module ActiveTriples ## # @abstract defines the basic interface for persistence of {RDFSource}'s. # - # A `PersistenceStrategy` has an underlying resource which should + # A `PersistenceStrategy` has an underlying resource which should # be an `RDFSource` or equivalent. Strategies can be injected into `RDFSource` - # instances at runtime to change the target datastore, repository, or object + # instances at runtime to change the target datastore, repository, or object # the instance syncs its graph with on save and reload operations. # # @example Changing a PersistenceStrategy at runtime # source = ActiveTriples::Resource.new # source.persistence_strategy # => # - # + # # source.set_persistence_strategy(MyStrategy) # source.persistence_strategy # => # # @@ -22,13 +23,13 @@ module PersistenceStrategy # @yield prior to persisting, yields to allow a block that performs # deletions in the persisted graph(s). # @return [Boolean] true if the resource was sucessfully destroyed - def destroy(&block) + def destroy yield if block_given? persist! @destroyed = true end - alias_method :destroy!, :destroy + alias destroy! destroy ## # Indicates if the Resource has been destroyed. @@ -47,7 +48,7 @@ def persisted? end ## - # @abstract save the resource according to the strategy and set the + # @abstract save the resource according to the strategy and set the # @persisted flag to `true` # # @see #persisted? @@ -71,13 +72,13 @@ def graph end ## - # @abstract Clear out any old assertions in the datastore / repository - # about this node or statement thus preparing to receive the updated + # @abstract Clear out any old assertions in the datastore / repository + # about this node or statement thus preparing to receive the updated # assertions. # # @return [Boolean] def erase_old_resource - raise NotImplementedError, + raise NotImplementedError, 'Abstract method #erase_old_resource is unimplemented' end diff --git a/lib/active_triples/persistence_strategies/repository_strategy.rb b/lib/active_triples/persistence_strategies/repository_strategy.rb index be1b4bc..83bf86f 100644 --- a/lib/active_triples/persistence_strategies/repository_strategy.rb +++ b/lib/active_triples/persistence_strategies/repository_strategy.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # Persistence strategy for projecting `RDFSource` to `RDF::Repositories`. @@ -52,7 +53,8 @@ def persist! # # @return [Boolean] def reload - source << repository.query([source, nil, nil]) + solutions = repository.query([source, nil, nil]) + source << solutions @persisted = true unless source.empty? true end @@ -66,17 +68,18 @@ def repository private - ## - # Finds an appropriate repository from the calling resource's configuration. - # If no repository is configured, builds an ephemeral in-memory - # repository and 'persists' there. - # - # @todo find a way to move this logic out (PersistenceStrategyBuilder?). - # so the dependency on Repositories is externalized. - def set_repository - return RDF::Repository.new if source.class.repository.nil? - repo = Repositories.repositories[source.class.repository] - repo || raise(RepositoryNotFoundError, "The class #{source.class} expects a repository called #{source.class.repository}, but none was declared") - end + ## + # Finds an appropriate repository from the calling resource's configuration. + # If no repository is configured, builds an ephemeral in-memory + # repository and 'persists' there. + # + # @todo find a way to move this logic out (PersistenceStrategyBuilder?). + # so the dependency on Repositories is externalized. + def set_repository + return RDF::Repository.new if source.class.repository.nil? + + repo = Repositories.repositories[source.class.repository] + repo || raise(RepositoryNotFoundError, "The class #{source.class} expects a repository called #{source.class.repository}, but none was declared") + end end end diff --git a/lib/active_triples/properties.rb b/lib/active_triples/properties.rb index 3ca6096..b97610a 100644 --- a/lib/active_triples/properties.rb +++ b/lib/active_triples/properties.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true + require 'active_support/core_ext/hash' module ActiveTriples ## - # Implements property configuration in the style of RDFSource. It does its + # Implements property configuration in the style of RDFSource. It does its # work at the class level, and is meant to be extended. - # + # # Collaborates closely with ActiveTriples::Reflection # # @example define properties at the class level @@ -13,7 +14,7 @@ module ActiveTriples # property :title, predicate: RDF::DC.title, class_name: ResourceClass # # @example using property setters & getters - # resource.property :title, predicate: RDF::DC.title, + # resource.property :title, predicate: RDF::DC.title, # class_name: ResourceClass # # resource.title = 'Comet in Moominland' @@ -33,49 +34,48 @@ module Properties private - ## - # Returns the properties registered and their configurations. - # - # @return [ActiveSupport::HashWithIndifferentAccess{String => ActiveTriples::NodeConfig}] - def properties - _active_triples_config - end - - ## - # Lists fields registered as properties on the object. - # - # @return [Array] the list of registered properties. - def fields - properties.keys.map(&:to_sym).reject{ |x| x == :type } - end + ## + # Returns the properties registered and their configurations. + # + # @return [ActiveSupport::HashWithIndifferentAccess{String => ActiveTriples::NodeConfig}] + def properties + _active_triples_config + end - ## - # List of RDF predicates registered as properties on the object. - # - # @return [Array] - def registered_predicates - properties.values.map { |config| config.predicate } - end + ## + # Lists fields registered as properties on the object. + # + # @return [Array] the list of registered properties. + def fields + properties.keys.map(&:to_sym).reject { |x| x == :type } + end - ## - # List of RDF predicates used in the Resource's triples, but not - # mapped to any property or accessor methods. - # - # @return [Array] - def unregistered_predicates - registered_preds = registered_predicates << RDF.type - unregistered_preds = [] - - query([rdf_subject, nil, nil]) do |stmt| - unregistered_preds << stmt.predicate unless - registered_preds.include? stmt.predicate - end + ## + # List of RDF predicates registered as properties on the object. + # + # @return [Array] + def registered_predicates + properties.values.map(&:predicate) + end - unregistered_preds + ## + # List of RDF predicates used in the Resource's triples, but not + # mapped to any property or accessor methods. + # + # @return [Array] + def unregistered_predicates + registered_preds = registered_predicates << RDF.type + unregistered_preds = [] + + solutions = query([rdf_subject, nil, nil]) + solutions.each do |stmt| + unregistered_preds << stmt.predicate unless + registered_preds.include? stmt.predicate end - public - + unregistered_preds + end + ## # Class methods for classes with `Properties` module ClassMethods @@ -87,10 +87,10 @@ def inherited(child_class) #:nodoc: ## # If the property methods are not yet present, generates them. # - # @return [Module] a module self::GeneratedPropertyMethods which is + # @return [Module] a module self::GeneratedPropertyMethods which is # included in self and defines the property methods # - # @note this is an alias to #generated_property_methods. Use it when you + # @note this is an alias to #generated_property_methods. Use it when you # intend to initialize, rather than retrieve, the methods for code # readability # @see #generated_property_methods @@ -99,10 +99,10 @@ def initialize_generated_modules end ## - # Gives existing generated property methods. If the property methods are + # Gives existing generated property methods. If the property methods are # not yet present, generates them as a new Module and includes it. # - # @return [Module] a module self::GeneratedPropertyMethods which is + # @return [Module] a module self::GeneratedPropertyMethods which is # included in self and defines the property methods # # @note use the alias #initialize_generated_modules for clarity of intent @@ -125,8 +125,9 @@ def generated_property_methods # # @return [Hash{String=>ActiveTriples::NodeConfig}] the full current # property configuration for the class - def property(name, opts={}, &block) + def property(name, opts = {}, &block) raise ArgumentError, "#{name} is a keyword and not an acceptable property name." if protected_property_name?(name.to_sym) + reflection = PropertyBuilder.build(self, name, opts, &block) Reflection.add_reflection self, name, reflection end @@ -155,6 +156,7 @@ def protected_property_name?(name) def config_for_term_or_uri(term) return properties[term.to_s] unless term.is_a?(RDF::Resource) && !term.is_a?(RDFSource) + properties.each_value { |v| return v if v.predicate == term.to_uri } end diff --git a/lib/active_triples/property.rb b/lib/active_triples/property.rb index f67d308..8b55a5d 100644 --- a/lib/active_triples/property.rb +++ b/lib/active_triples/property.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # A value object to encapsulate what a Property is. Instantiate with a hash of @@ -17,7 +18,7 @@ class Property def initialize(options = {}, &block) self.name = options.fetch(:name) self.attributes = options.except(:name) - self.config = block + self.config = block end ## @@ -57,12 +58,12 @@ def predicate attr_writer :name, :config attr_accessor :attributes - alias_method :to_h, :attributes + alias to_h attributes ## - # Returns the property's configuration values. Will not return #name, which + # Returns the property's configuration values. Will not return #name, which # is meant to only be accessible via the accessor. - # + # # @return [Hash] Configuration values for this property. public :to_h end diff --git a/lib/active_triples/property_builder.rb b/lib/active_triples/property_builder.rb index 0f81dc7..f5b96c1 100644 --- a/lib/active_triples/property_builder.rb +++ b/lib/active_triples/property_builder.rb @@ -1,14 +1,14 @@ # frozen_string_literal: true + module ActiveTriples ## # A builder for property `NodeConfig`s # - # @example + # @example # PropertyBuilder.build(:creator, predicate: RDF::Vocab::DC.creator) - # + # # @see NodeConfig class PropertyBuilder - # @!attribute [r] name # @return # @!attribute [r] options @@ -18,7 +18,7 @@ class PropertyBuilder ## # @param name [] # @param options [] - def initialize(name, options, &block) + def initialize(name, options) @name = name @options = options end @@ -26,7 +26,7 @@ def initialize(name, options, &block) ## # @param name [Symbol] # @param options [Hash] - # @option options [RDF::URI] :predicate + # @option options [RDF::URI] :predicate # @option options [String, Class] :class_name # @option options [Boolean] :cast # @@ -39,11 +39,11 @@ def initialize(name, options, &block) # # @see #build def self.create_builder(name, options, &block) - raise ArgumentError, "property names must be a Symbol" unless - name.kind_of?(Symbol) + raise ArgumentError, 'property names must be a Symbol' unless + name.is_a?(Symbol) options[:predicate] = RDF::URI.intern(options[:predicate]) - raise ArgumentError, "must provide an RDF::URI to :predicate" unless + raise ArgumentError, 'must provide an RDF::URI to :predicate' unless options[:predicate].valid? new(name, options, &block) @@ -56,7 +56,7 @@ def self.build(model, name, options, &block) reflection end - def self.define_accessors(model, reflection, options={}) + def self.define_accessors(model, reflection, options = {}) mixin = model.generated_property_methods name = reflection.term define_readers(mixin, name) @@ -87,7 +87,7 @@ def #{name}=(value) end CODE end - + ## # @yield yields to block configuring index behaviors # @yieldparam index_object [NodeConfig::IndexObject] diff --git a/lib/active_triples/rdf_source.rb b/lib/active_triples/rdf_source.rb index 24619a7..aeedd78 100644 --- a/lib/active_triples/rdf_source.rb +++ b/lib/active_triples/rdf_source.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true + require 'active_model' require 'active_support/core_ext/hash' require 'active_support/core_ext/array/wrap' require 'set' +require 'json/ld' module ActiveTriples ## @@ -120,12 +122,13 @@ def initialize(*args, &block) persistence_strategy.parent = args.shift end - graph_params = if args.empty? || args.first.nil? - {} - else - args.shift - end - persistence_strategy.graph = RDF::Graph.new(**graph_params, &block) + merged_args = if args.blank? + {} + else + filtered_args = args.reject(&:nil?) + filtered_args.reduce(:merge) + end + persistence_strategy.graph = RDF::Graph.new(**merged_args, &block) reload # Append type to graph if necessary. @@ -248,8 +251,13 @@ def dump(*args) if args.first == :jsonld && respond_to?(:jsonld_context) args << {} unless args.last.is_a?(Hash) args.last[:context] ||= jsonld_context + + writer = args.shift + options = args.reduce(:merge) + super(writer, **options) + else + super(*args) end - super end ## @@ -327,7 +335,7 @@ def id # # @note Without a custom #inspect, we inherit from RDF::Value. def inspect - sprintf("#<%s:%#0x ID:%s>", self.class.to_s, self.object_id, self.to_base) + format('#<%s:%#0x ID:%s>', self.class.to_s, object_id, to_base) end ## @@ -358,9 +366,10 @@ def type end def type=(type) - raise(ArgumentError, - "Type must be an RDF::URI. Got: #{type.class}, #{type}") unless - type.is_a? RDF::URI + unless type.is_a? RDF::URI + raise(ArgumentError, + "Type must be an RDF::URI. Got: #{type.class}, #{type}") + end update(RDF::Statement.new(rdf_subject, RDF.type, type)) end @@ -404,13 +413,15 @@ def rdf_label def fetch(**args, &_block) begin load(rdf_subject, **args) - rescue => e + rescue StandardError => error if block_given? yield(self) else - raise "#{self} is a blank node; " \ - 'Cannot fetch a resource without a URI' if node? - raise e + if node? + raise "#{self} is a blank node; " \ + 'Cannot fetch a resource without a URI' + end + raise error end end self @@ -649,10 +660,21 @@ def delete_observer(observer) # @return [void] def notify_observers(property) return if @observers.empty? + values = get_values(property).to_a @observers.each { |o| o.notify(property, values) } end + # Determines whether or not a term is referenced by this source + # Override for ensuring that this supports RDF::Enumerable + # @todo Determine why this could work with `include(RDF::Enumerable)` + # + # @param [RDF::Term] term + # @return [Boolean] + def has_term?(term) + terms.include?(term) + end + private ## diff --git a/lib/active_triples/reflection.rb b/lib/active_triples/reflection.rb index 0ddd53c..fd3b878 100644 --- a/lib/active_triples/reflection.rb +++ b/lib/active_triples/reflection.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'active_support/core_ext/class' module ActiveTriples @@ -23,7 +24,7 @@ def reflections end def self.add_reflection(model, name, reflection) - model._active_triples_config = + model._active_triples_config = model._active_triples_config.merge(name.to_s => reflection) end @@ -33,7 +34,7 @@ module ClassMethods # # @return [ActiveTriples::NodeConfig] the configuration for the property # - # @raise [ActiveTriples::UndefinedPropertyError] when the property does + # @raise [ActiveTriples::UndefinedPropertyError] when the property does # not exist def reflect_on_property(property) _active_triples_config.fetch(property.to_s) do @@ -42,7 +43,7 @@ def reflect_on_property(property) end ## - # @return [Hash{String=>ActiveTriples::NodeConfig}] a hash of property + # @return [Hash{String=>ActiveTriples::NodeConfig}] a hash of property # names and their configurations def properties _active_triples_config @@ -51,7 +52,7 @@ def properties ## # @param [Hash{String=>ActiveTriples::NodeConfig}] a complete config hash # to set the properties to. - # @return [Hash{String=>ActiveTriples::NodeConfig}] a hash of property + # @return [Hash{String=>ActiveTriples::NodeConfig}] a hash of property # names and their configurations def properties=(val) self._active_triples_config = val diff --git a/lib/active_triples/relation.rb b/lib/active_triples/relation.rb index 6387f51..d22930e 100644 --- a/lib/active_triples/relation.rb +++ b/lib/active_triples/relation.rb @@ -1,19 +1,20 @@ # frozen_string_literal: true + require 'active_support/core_ext/module/delegation' module ActiveTriples ## # A `Relation` represents the values of a specific property/predicate on an - # `RDFSource`. Each relation is a set (`Enumerable` of the `RDF::Term`s that + # `RDFSource`. Each relation is a set (`Enumerable` of the `RDF::Term`s that # are objects in the of source's triples of the form: # # <{#parent}> <{#predicate}> [term] . # - # Relations express a binary relationships (over a predicate) between the + # Relations express a binary relationships (over a predicate) between the # parent node and a set of terms. # # When the term is a URI or Blank Node, it is represented in the results as an - # `RDFSource`. Literal values are cast to strings, Ruby native types, or + # `RDFSource`. Literal values are cast to strings, Ruby native types, or # remain as an `RDF::Literal` as documented in `#each`. # # @see RDF::Term @@ -63,7 +64,7 @@ def &(array) (objects.to_a & array.objects.to_a) .map { |object| convert_object(object) } end - + ## # @param array [#to_ary, ActiveTriples::Relation] # @return [Array] @@ -73,7 +74,7 @@ def &(array) # @see Array#| def |(array) return to_a | array unless array.is_a? Relation - + (objects.to_a | array.objects.to_a) .map { |object| convert_object(object) } end @@ -93,8 +94,8 @@ def +(array) end ## - # Mimics `Set#<=>`, returning `0` when set membership is equivalent, and - # `nil` (as non-comparable) otherwise. Unlike `Set#<=>`, uses `#==` for + # Mimics `Set#<=>`, returning `0` when set membership is equivalent, and + # `nil` (as non-comparable) otherwise. Unlike `Set#<=>`, uses `#==` for # member comparisons. # # @param [Object] other @@ -106,6 +107,7 @@ def <=>(other) # If we're empty, avoid calling `#to_a` on other. if empty? return 0 if other.each.first.nil? + return nil end @@ -126,7 +128,7 @@ def <=>(other) end length += 1 - + # Return as not comparable if we have seen more terms than are in other, # or if other does not include the current term. return nil if other_length < length || !other.include?(current) @@ -141,9 +143,9 @@ def <=>(other) # @return [Relation] a relation containing the set values; i.e. `self` def <<(values) values = prepare_relation(values) if values.is_a?(Relation) - self.set(objects.to_a | Array.wrap(values)) + set(objects.to_a | Array.wrap(values)) end - alias_method :push, :<< + alias push << ## # Builds a node with the given attributes, adding it to the relation. @@ -190,17 +192,17 @@ def <<(values) # @see RDFSource#attributes= # @see http://guides.rubyonrails.org/active_model_basics.html for some # context on ActiveModel attributes. - def build(attributes={}) + def build(attributes = {}) new_subject = attributes.fetch('id') { RDF::Node.new } make_node(new_subject).tap do |node| node.attributes = attributes.except('id') - if parent.kind_of? List::ListResource + if parent.is_a? List::ListResource parent.list << node - elsif node.kind_of? RDF::List - self.push node.rdf_subject + elsif node.is_a? RDF::List + push node.rdf_subject else - self.push node + push node end end end @@ -211,6 +213,7 @@ def build(attributes={}) # @return [Relation] self; a now empty relation def clear return self if empty? + parent.delete([rdf_subject, predicate, nil]) parent.notify_observers(property) @@ -276,16 +279,16 @@ def delete?(value) ## # Gives a result set for the `Relation`. # - # By default, `RDF::URI` and `RDF::Node` results are cast to `RDFSource`. - # When `cast?` is `false`, `RDF::Resource` values are left in their raw + # By default, `RDF::URI` and `RDF::Node` results are cast to `RDFSource`. + # When `cast?` is `false`, `RDF::Resource` values are left in their raw # form. # # `Literal` results are cast as follows: - # + # # - Simple string literals are returned as `String` - # - `rdf:langString` literals are always returned as raw `Literal` objects, + # - `rdf:langString` literals are always returned as raw `Literal` objects, # retaining their language tags. - # - Typed literals are cast to their Ruby `#object` when their datatype + # - Typed literals are cast to their Ruby `#object` when their datatype # is associated with a `Literal` subclass. # # @example results with default casting @@ -340,7 +343,7 @@ def empty? # @return [Object] the first result, if present; else a newly built node # # @see #build - def first_or_create(attributes={}) + def first_or_create(attributes = {}) warn 'DEPRECATION: #first_or_create is deprecated for removal in 1.0.0.' first || build(attributes) end @@ -361,6 +364,7 @@ def length # @see #property def predicate return property if property.is_a?(RDF::Term) + property_config[:predicate] if is_property? end @@ -393,12 +397,12 @@ def set(values) raise UndefinedPropertyError.new(property, reflections) if predicate.nil? values = prepare_relation(values) if values.is_a?(Relation) - values = [values].compact unless values.kind_of?(Array) + values = [values].compact unless values.is_a?(Array) clear values.each { |val| set_value(val) } parent.notify_observers(property) - + parent.persist! if parent.persistence_strategy.respond_to?(:ancestors) && parent.persistence_strategy.ancestors.any? { |r| r.is_a?(ActiveTriples::List::ListResource) } @@ -447,209 +451,209 @@ def swap(swap_out, swap_in) protected - ## - # Converts an object to the appropriate class. - # - # Literals are cast only when the datatype is known. - # - # @private - def convert_object(value) - case value - when RDFSource - value - when RDF::Literal - if value.simple? - value.object - elsif value.has_datatype? - RDF::Literal.datatyped_class(value.datatype.to_s) ? value.object : value - else - value - end - when RDF::Resource - cast? ? make_node(value) : value + ## + # Converts an object to the appropriate class. + # + # Literals are cast only when the datatype is known. + # + # @private + def convert_object(value) + case value + when RDFSource + value + when RDF::Literal + if value.simple? + value.object + elsif value.has_datatype? + RDF::Literal.datatyped_class(value.datatype.to_s) ? value.object : value else value end + when RDF::Resource + cast? ? make_node(value) : value + else + value end + end - ## - # @private - def node_cache - @node_cache ||= {} - end + ## + # @private + def node_cache + @node_cache ||= {} + end - ## - # @private - def objects(&block) - solutions = parent.query([rdf_subject, predicate, nil]) - solutions.extend(RDF::Enumerable) unless solutions.respond_to?(:each_object) - - solutions.each_object(&block) - end + ## + # @private + def objects(&block) + solutions = parent.query([rdf_subject, predicate, nil]) + solutions.extend(RDF::Enumerable) unless solutions.respond_to?(:each_object) + + solutions.each_object(&block) + end private - ## - # @private - def is_property? - reflections.has_property?(property) || is_type? - end - ## - # @private - def is_type? - (property == RDF.type || property.to_s == "type") && - (!reflections.kind_of?(RDFSource) || !is_property?) - end + ## + # @private + def is_property? + reflections.has_property?(property) || is_type? + end - ## - # @private - # @return [Hash 2 - raise(ArgumentError, - "wrong number of arguments (#{value_arguments.length} for 1-2)") - end + ## + # @private + def class_for_value(v) + uri_class(v) || class_for_property + end + + ## + # @private + def uri_class(v) + v = RDF::URI.intern(v) if v.is_a? String + type_uri = parent.query([v, RDF.type, nil]).to_a.first.try(:object) + RDFSource.type_registry[type_uri] + end - value_arguments.length > 1 ? value_arguments.first : parent.rdf_subject + ## + # @private + def class_for_property + klass = property_config[:class_name] if is_property? + klass ||= Resource + klass = ActiveTriples.class_from_string(klass, final_parent.class) if + klass.is_a? String + klass + end + + ## + # @private + # @return [RDF::Term] the subject of the relation + def rdf_subject + if value_arguments.empty? || value_arguments.length > 2 + raise(ArgumentError, + "wrong number of arguments (#{value_arguments.length} for 1-2)") end - public + value_arguments.length > 1 ? value_arguments.first : parent.rdf_subject + end ## # An error class for unallowable values in relations. diff --git a/lib/active_triples/repositories.rb b/lib/active_triples/repositories.rb index c995654..9c48396 100644 --- a/lib/active_triples/repositories.rb +++ b/lib/active_triples/repositories.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # Defines module methods for registering an RDF::Repository for @@ -18,7 +19,6 @@ module ActiveTriples # # @see Configurable module Repositories - ## # Register a repository to be configured by name # @@ -29,8 +29,9 @@ module Repositories # # @raise [ArgumentError] raised if the repository is not an `RDF::Repository` def add_repository(name, repo) - raise ArgumentError, "Repositories must be an RDF::Repository" unless - repo.kind_of? RDF::Repository + raise ArgumentError, 'Repositories must be an RDF::Repository' unless + repo.is_a? RDF::Repository + repositories[name] = repo end module_function :add_repository @@ -45,7 +46,7 @@ def clear_repositories! module_function :clear_repositories! ## - # @return [Hash] a hash of currrently registered names + # @return [Hash] a hash of currrently registered names # and repositories def repositories @repositories ||= {} @@ -58,10 +59,10 @@ def repositories # # @param [String] rdf_subject # @param [Symbol] repository name - # - # @return [Boolean] true if the repository contains at least one statement + # + # @return [Boolean] true if the repository contains at least one statement # with the given subject term - def has_subject?(rdf_subject, repo_name=nil) + def has_subject?(rdf_subject, repo_name = nil) search_repositories = [repositories[repo_name]] if repo_name search_repositories ||= repositories.values found = false diff --git a/lib/active_triples/resource.rb b/lib/active_triples/resource.rb index 1d38325..104f933 100644 --- a/lib/active_triples/resource.rb +++ b/lib/active_triples/resource.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples ## # Defines a generic RDF `Resource` as an `ActiveTriples::Entity`. This @@ -12,8 +13,9 @@ def type_registry end def property(*) - raise "Properties not definable directly on ActiveTriples::Resource, use a subclass" if + raise 'Properties not definable directly on ActiveTriples::Resource, use a subclass' if self == ActiveTriples::Resource + super end end diff --git a/lib/active_triples/schema.rb b/lib/active_triples/schema.rb index 29c58ea..a930e4a 100644 --- a/lib/active_triples/schema.rb +++ b/lib/active_triples/schema.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true + module ActiveTriples ## # Super class which provides a simple property DSL for defining property -> # predicate mappings. - # + # # @example defining and applying a custom schema # class MySchema < ActiveTriples::Schema # property :title, predicate: RDF::Vocab::DC.title @@ -21,15 +22,15 @@ class << self # @param [Symbol] property The property name on the object. # @param [Hash] options Options for the property. # @option options [Boolean] :cast - # @option options [String, Class] :class_name + # @option options [String, Class] :class_name # @option options [RDF::URI] :predicate The predicate to map the property # to. # # @see ActiveTriples::Property for more about options def property(property, options) - properties << Property.new(options.merge(:name => property)) + properties << Property.new(options.merge(name: property)) end - + ## # @return [Array] def properties diff --git a/lib/active_triples/undefined_property_error.rb b/lib/active_triples/undefined_property_error.rb index 50e9196..c565d1b 100644 --- a/lib/active_triples/undefined_property_error.rb +++ b/lib/active_triples/undefined_property_error.rb @@ -1,17 +1,18 @@ # frozen_string_literal: true + module ActiveTriples ## - # An error class to be raised when attempting to reflect on an undefined + # An error class to be raised when attempting to reflect on an undefined # property. # # @example - # begin + # begin # my_source.set_value(:fake_property, 'blah') # rescue ActiveTriples::UndefinedPropertyError => e # e.property => 'fake_property' # e.klass => 'MySourceClass' # end - # + # class UndefinedPropertyError < ArgumentError attr_reader :property, :klass diff --git a/lib/active_triples/util/buffered_transaction.rb b/lib/active_triples/util/buffered_transaction.rb index 76ba167..9bf0907 100644 --- a/lib/active_triples/util/buffered_transaction.rb +++ b/lib/active_triples/util/buffered_transaction.rb @@ -1,23 +1,25 @@ +# frozen_string_literal: true + require 'active_triples/util/extended_bounded_description' module ActiveTriples ## # A buffered trasaction for use with `ActiveTriples::ParentStrategy`. # - # If an `ActiveTriples::RDFSource` instance is passed as the underlying - # repository, this transaction will try to find an existing - # `BufferedTransaction` to use as the basis for a snapshot. When the + # If an `ActiveTriples::RDFSource` instance is passed as the underlying + # repository, this transaction will try to find an existing + # `BufferedTransaction` to use as the basis for a snapshot. When the # transaction is executed, the inserts and deletes are replayed against the # `RDFSource`. # - # If a `RDF::Transaction::TransactionError` is raised on commit, this + # If a `RDF::Transaction::TransactionError` is raised on commit, this # transaction optimistically attempts to replay the changes. # - # Reads are projected onto a specialized "Extended Bounded Description" - # subgraph. + # Reads are projected onto a specialized "Extended Bounded Description" + # subgraph. # # @see ActiveTriples::Util::ExtendedBoundedDescription - class BufferedTransaction < + class BufferedTransaction < RDF::Repository::Implementation::SerializedTransaction # @!attribute snapshot [r] # @return RDF::Dataset @@ -26,12 +28,12 @@ class BufferedTransaction < # @!attribute ancestors [r] # @return Array attr_reader :snapshot, :subject, :ancestors - + def initialize(repository, ancestors: [], - subject: nil, - graph_name: nil, - mutable: false, + subject: nil, + graph_name: nil, + mutable: false, **options, &block) @subject = subject @@ -47,7 +49,7 @@ def initialize(repository, end end - return super + super end ## @@ -93,23 +95,25 @@ def delete_statement(statement) end ## - # Executes optimistically. If errors are encountered, we replay the buffer + # Executes optimistically. If errors are encountered, we replay the buffer # on the latest version. - # - # If the `repository` is a transaction, we immediately replay the buffer + # + # If the `repository` is a transaction, we immediately replay the buffer # onto it. # # @see RDF::Transaction#execute def execute - raise TransactionError, 'Cannot execute a rolled back transaction. ' \ - 'Open a new one instead.' if @rolledback + if @rolledback + raise TransactionError, 'Cannot execute a rolled back transaction. ' \ + 'Open a new one instead.' + end return if changes.empty? return super unless repository.is_a?(ActiveTriples::RDFSource) repository.insert(changes.inserts) repository.delete(changes.deletes) - rescue RDF::Transaction::TransactionError => err - raise err if @rolledback + rescue RDF::Transaction::TransactionError => e + raise e if @rolledback # replay changest on the current version of the repository repository.delete(*changes.deletes) @@ -117,9 +121,10 @@ def execute end private - + def read_target return super unless subject + ExtendedBoundedDescription.new(super, subject, ancestors) end end diff --git a/lib/active_triples/util/extended_bounded_description.rb b/lib/active_triples/util/extended_bounded_description.rb index 38a16b2..84a5e52 100644 --- a/lib/active_triples/util/extended_bounded_description.rb +++ b/lib/active_triples/util/extended_bounded_description.rb @@ -1,33 +1,35 @@ +# frozen_string_literal: true + module ActiveTriples ## - # Bounds the scope of an `RDF::Queryable` to a subgraph defined from a source - # graph, a starting node, and a list of "ancestors" terms, by the following + # Bounds the scope of an `RDF::Queryable` to a subgraph defined from a source + # graph, a starting node, and a list of "ancestors" terms, by the following # process: # # Include in the subgraph: - # 1. All statements in the source graph where the subject of the statement + # 1. All statements in the source graph where the subject of the statement # is the starting node. # 2. Add the starting node to the ancestors list. - # 2. Recursively, for all statements already in the subgraph, include in - # the subgraph the Extended Bounded Description for each object node, + # 2. Recursively, for all statements already in the subgraph, include in + # the subgraph the Extended Bounded Description for each object node, # unless the object is in the ancestors list. # - # The list of "ancestors" is empty by default. + # The list of "ancestors" is empty by default. # - # This subgraph this process yields can be considered as a description of + # This subgraph this process yields can be considered as a description of # the starting node. # - # Compare to Concise Bounded Description - # (https://www.w3.org/Submission/CBD/), the common subgraph scope used for + # Compare to Concise Bounded Description + # (https://www.w3.org/Submission/CBD/), the common subgraph scope used for # SPARQL DESCRIBE queries. # - # @note this implementation requires that the `source_graph` remain unchanged - # while iterating over the description. The safest way to achive this is to + # @note this implementation requires that the `source_graph` remain unchanged + # while iterating over the description. The safest way to achive this is to # use an immutable `RDF::Dataset` (e.g. a `Repository#snapshot`). class ExtendedBoundedDescription include RDF::Enumerable include RDF::Queryable - + ## # @!attribute ancestors [r] # @return Array @@ -35,7 +37,7 @@ class ExtendedBoundedDescription # @return RDF::Queryable # @!attribute starting_node [r] # @return RDF::Term - attr_reader :ancestors, :source_graph, :starting_node + attr_reader :ancestors, :source_graph, :starting_node ## # By analogy to Concise Bounded Description. @@ -48,20 +50,22 @@ def initialize(source_graph, starting_node, ancestors = []) @starting_node = starting_node @ancestors = ancestors end - + ## # @see RDF::Enumerable#each def each_statement ancestors = @ancestors.dup if block_given? - statements = source_graph.query([starting_node, nil, nil]).each + results = source_graph.query([starting_node, nil, nil]) + statements = results.each statements.each_statement { |st| yield st } - + ancestors << starting_node - + statements.each_object do |object| - next if object.literal? || ancestors.include?(object) + next if object.literal? || ancestors.include?(object) + ExtendedBoundedDescription .new(source_graph, object, ancestors).each do |statement| yield statement @@ -70,6 +74,6 @@ def each_statement end enum_statement end - alias_method :each, :each_statement + alias each each_statement end end diff --git a/lib/active_triples/version.rb b/lib/active_triples/version.rb index f18791e..cf3c50f 100644 --- a/lib/active_triples/version.rb +++ b/lib/active_triples/version.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + module ActiveTriples VERSION = '1.1.1'.freeze end diff --git a/spec/active_triples/configurable_spec.rb b/spec/active_triples/configurable_spec.rb index b8d2755..754a23c 100644 --- a/spec/active_triples/configurable_spec.rb +++ b/spec/active_triples/configurable_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' describe ActiveTriples::Configurable do before do @@ -8,14 +9,14 @@ class DummyConfigurable end end - after { Object.send(:remove_const, "DummyConfigurable") } + after { Object.send(:remove_const, 'DummyConfigurable') } - it "should be okay if not configured" do + it 'should be okay if not configured' do expect(DummyConfigurable.type).to eq nil end - it "should be okay if configured to nil" do - DummyConfigurable.configure :type => nil + it 'should be okay if configured to nil' do + DummyConfigurable.configure type: nil expect(DummyConfigurable.type).to eq [] end @@ -33,7 +34,7 @@ class ConfigurableSubclass < DummyConfigurable; end let(:rdf_label) { RDF::Vocab::DC.title } let(:repository) { RDF::Repository.new } - after { Object.send(:remove_const, "ConfigurableSubclass") } + after { Object.send(:remove_const, 'ConfigurableSubclass') } it 'inherits type from parent' do expect(ConfigurableSubclass.type).to eq DummyConfigurable.type @@ -42,16 +43,16 @@ class ConfigurableSubclass < DummyConfigurable; end describe '#configure' do before do - DummyConfigurable.configure base_uri: "http://example.org/base", - type: RDF::RDFS.Class, + DummyConfigurable.configure base_uri: 'http://example.org/base', + type: RDF::RDFS.Class, rdf_label: RDF::Vocab::DC.title end it 'should set a base uri' do - expect(DummyConfigurable.base_uri).to eq "http://example.org/base" + expect(DummyConfigurable.base_uri).to eq 'http://example.org/base' end - it "should be able to set multiple types" do + it 'should be able to set multiple types' do DummyConfigurable.configure type: [RDF::RDFS.Container, RDF::RDFS.ContainerMembershipProperty] @@ -69,7 +70,7 @@ class ConfigurableSubclass < DummyConfigurable; end expect(DummyConfigurable.type).to eq [RDF::RDFS.Class] end - it "should be able to set multiple types" do + it 'should be able to set multiple types' do DummyConfigurable.configure type: RDF::RDFS.Container expect(DummyConfigurable.type) diff --git a/spec/active_triples/configuration_spec.rb b/spec/active_triples/configuration_spec.rb index 5111ff0..ab2de95 100644 --- a/spec/active_triples/configuration_spec.rb +++ b/spec/active_triples/configuration_spec.rb @@ -1,59 +1,62 @@ # frozen_string_literal: true + require 'spec_helper' -RSpec.describe ActiveTriples::Configuration do - subject { described_class.new(starting_hash) } - let(:starting_hash) { {} } - describe "[]" do - context "with bad config values" do - let(:starting_hash) { {:bad => 1} } - it "should not return them" do +describe ActiveTriples::Configuration do + subject { described_class.new(**starting_hash) } + let(:starting_hash) do + {} + end + describe '[]' do + context 'with bad config values' do + let(:starting_hash) { { bad: 1 } } + it 'should not return them' do expect(subject[:bad]).to be_nil end end - context "with good config values" do - let(:starting_hash) { {:type => 1} } - it "should return them" do + context 'with good config values' do + let(:starting_hash) { { type: 1 } } + it 'should return them' do expect(subject[:type]).to eq 1 end end end - describe "to_h" do - context "with bad and good config" do + describe 'to_h' do + context 'with bad and good config' do let(:starting_hash) do { - :bad => 1, - :type => 2 + bad: 1, + type: 2 } end - it "should return only good ones" do - expect(subject.to_h).to eq ({:type => 2}) + it 'should return only good ones' do + expect(subject.to_h).to eq({ type: 2 }) end end end - describe "#items" do - let(:starting_hash) { {:rdf_label => 1} } - it "should return a configuration item for each config" do + describe '#items' do + let(:starting_hash) { { rdf_label: 1 } } + it 'should return a configuration item for each config' do expect(subject.items.keys.length).to eq 1 expect(subject.items[:rdf_label]).to be_kind_of ActiveTriples::Configuration::Item end end - describe "#merge" do + describe '#merge' do let(:starting_hash) do { - :rdf_label => RDF::Vocab::SKOS.prefLabel, - :type => RDF::RDFS.Class + rdf_label: RDF::Vocab::SKOS.prefLabel, + type: RDF::RDFS.Class } end - it "should override some values" do - new_hash = {:rdf_label => RDF::RDFS.label} + it 'should override some values' do + new_hash = { rdf_label: RDF::RDFS.label } expect(subject.merge(new_hash)[:rdf_label]).to eq RDF::RDFS.label end - it "should merge type" do - new_hash = {:type => RDF::RDFS.Container} + it 'should merge type' do + new_hash = { type: RDF::RDFS.Container } expect(subject.merge(new_hash)[:type]).to eq [RDF::RDFS.Class, RDF::RDFS.Container] end end diff --git a/spec/active_triples/extension_strategy_spec.rb b/spec/active_triples/extension_strategy_spec.rb index cd47c2c..6534b14 100644 --- a/spec/active_triples/extension_strategy_spec.rb +++ b/spec/active_triples/extension_strategy_spec.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true + require 'spec_helper' RSpec.describe ActiveTriples::ExtensionStrategy do subject { described_class } - describe ".apply" do - it "should copy the property to the asset" do + describe '.apply' do + it 'should copy the property to the asset' do asset = build_asset - property = build_property("name", {:predicate => RDF::Vocab::DC.title}) + property = build_property('name', { predicate: RDF::Vocab::DC.title }) subject.apply(asset, property) @@ -15,9 +16,9 @@ end it 'execute the block' do - block = Proc.new {} + block = proc {} asset = build_asset - property = build_property("name", {:predicate => RDF::Vocab::DC.title}, &block) + property = build_property('name', { predicate: RDF::Vocab::DC.title }, &block) subject.apply(asset, property) @@ -25,11 +26,11 @@ end def build_asset - object_double(ActiveTriples::Resource, :property => nil) + object_double(ActiveTriples::Resource, property: nil) end def build_property(name, options, &block) - property = object_double(ActiveTriples::Property.new(:name => nil)) + property = object_double(ActiveTriples::Property.new(name: nil)) allow(property).to receive(:name).and_return(name) allow(property).to receive(:to_h).and_return(options) allow(property).to receive(:config).and_return(block) diff --git a/spec/active_triples/identifiable_spec.rb b/spec/active_triples/identifiable_spec.rb index b2f2943..efe3687 100644 --- a/spec/active_triples/identifiable_spec.rb +++ b/spec/active_triples/identifiable_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' require 'active_model' @@ -41,13 +42,13 @@ class MyResource context 'without implementation' do describe '::from_uri' do it 'raises a NotImplementedError' do - expect{ klass.from_uri(RDF::URI('http://example.org/blah')) }.to raise_error NotImplementedError + expect { klass.from_uri(RDF::URI('http://example.org/blah')) }.to raise_error NotImplementedError end end describe '#to_uri' do it 'raises a NotImplementedError' do - expect{ subject.to_uri }.to raise_error NotImplementedError + expect { subject.to_uri }.to raise_error NotImplementedError end end end @@ -65,13 +66,12 @@ def self.property(*args) resource.get_values(prop) end - define_method "#{prop.to_s}=" do |*args| + define_method "#{prop}=" do |*args| resource.set_value(prop, *args) end resource_class.property(*args) end - end subject.id = '123' @@ -79,7 +79,7 @@ def self.property(*args) describe '::properties' do before do - klass.property :title, :predicate => RDF::Vocab::DC.title + klass.property :title, predicate: RDF::Vocab::DC.title end it 'can be set' do expect(klass.properties).to include 'title' @@ -111,7 +111,7 @@ class ActiveExampleTwo end it 'does not effect other classes' do - klass.property :identifier, :predicate => RDF::Vocab::DC.identifier + klass.property :identifier, predicate: RDF::Vocab::DC.identifier expect(ActiveExampleTwo.properties).to be_empty end end @@ -160,15 +160,15 @@ class ActiveExampleTwo end end - describe "adding it as a property for an AT Resource" do + describe 'adding it as a property for an AT Resource' do include_context 'with data' - it "returns the same in-memory object added" do + it 'returns the same in-memory object added' do resource = MyResource.new resource.relation = subject expect(resource.relation).to eq [subject] end - it "can share that object with another resource" do + it 'can share that object with another resource' do resource = MyResource.new resource_2 = MyResource.new diff --git a/spec/active_triples/list_spec.rb b/spec/active_triples/list_spec.rb index 3f516da..7a3d064 100644 --- a/spec/active_triples/list_spec.rb +++ b/spec/active_triples/list_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' require 'nokogiri' require 'rdf/rdfxml' @@ -58,7 +59,7 @@ context 'with properties' do before :each do - class MADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#") + class MADS < RDF::Vocabulary('http://www.loc.gov/mads/rdf/v1#') property :complexSubject property :authoritativeLabel property :elementList @@ -68,20 +69,20 @@ class MADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#") end class DemoList include ActiveTriples::RDFSource - property :elementList, :predicate => MADS.elementList, :class_name => 'DemoList::List' + property :elementList, predicate: MADS.elementList, class_name: 'DemoList::List' class List < ActiveTriples::List - property :topicElement, :predicate => MADS.TopicElement, :class_name => 'DemoList::List::TopicElement' - property :temporalElement, :predicate => MADS.TemporalElement, :class_name => 'DemoList::List::TemporalElement' + property :topicElement, predicate: MADS.TopicElement, class_name: 'DemoList::List::TopicElement' + property :temporalElement, predicate: MADS.TemporalElement, class_name: 'DemoList::List::TemporalElement' class TopicElement include ActiveTriples::RDFSource - configure :type => MADS.TopicElement - property :elementValue, :predicate => MADS.elementValue + configure type: MADS.TopicElement + property :elementValue, predicate: MADS.elementValue end class TemporalElement include ActiveTriples::RDFSource - configure :type => MADS.TemporalElement - property :elementValue, :predicate => MADS.elementValue + configure type: MADS.TemporalElement + property :elementValue, predicate: MADS.elementValue end end end @@ -91,75 +92,75 @@ class TemporalElement Object.send(:remove_const, :MADS) end - describe "a new list" do - let (:ds) { DemoList.new('http://example.org/foo') } - subject { ds.elementList.build} + describe 'a new list' do + let(:ds) { DemoList.new('http://example.org/foo') } + subject { ds.elementList.build } - it "should insert at the end" do + it 'should insert at the end' do expect(subject).to be_kind_of DemoList::List expect(subject.size).to eq 0 subject[1] = DemoList::List::TopicElement.new expect(subject.size).to eq 2 end - it "should insert at the head" do + it 'should insert at the head' do expect(subject).to be_kind_of DemoList::List expect(subject.size).to eq 0 subject[0] = DemoList::List::TopicElement.new expect(subject.size).to eq 1 end - describe "that has 4 elements" do + describe 'that has 4 elements' do before do subject[3] = DemoList::List::TopicElement.new expect(subject.size).to eq 4 end - it "should insert in the middle" do + it 'should insert in the middle' do subject[1] = DemoList::List::TopicElement.new expect(subject.size).to eq 4 end end - describe "return updated xml" do - it "should be built" do - subject[0] = RDF::URI.new "http://library.ucsd.edu/ark:/20775/bbXXXXXXX6" + describe 'return updated xml' do + it 'should be built' do + subject[0] = RDF::URI.new 'http://library.ucsd.edu/ark:/20775/bbXXXXXXX6' subject[1] = DemoList::List::TopicElement.new - subject[1].elementValue = "Relations with Mexican Americans" - subject[2] = RDF::URI.new "http://library.ucsd.edu/ark:/20775/bbXXXXXXX4" + subject[1].elementValue = 'Relations with Mexican Americans' + subject[2] = RDF::URI.new 'http://library.ucsd.edu/ark:/20775/bbXXXXXXX4' subject[3] = DemoList::List::TemporalElement.new - subject[3].elementValue = "20th century" + subject[3].elementValue = '20th century' ds.elementList = subject doc = Nokogiri::XML(ds.dump(:rdfxml)) - ns = {rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", mads: "http://www.loc.gov/mads/rdf/v1#"} - expect(doc.xpath('/rdf:RDF/rdf:Description/@rdf:about', ns).map(&:value)).to eq ["http://example.org/foo"] - expect(doc.xpath('//rdf:Description/mads:elementList/@rdf:parseType', ns).map(&:value)).to eq ["Collection"] - expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 1]/@rdf:about', ns).map(&:value)).to eq ["http://library.ucsd.edu/ark:/20775/bbXXXXXXX6"] - expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 2]/mads:elementValue', ns).map(&:text)).to eq ["Relations with Mexican Americans"] - expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 3]/@rdf:about', ns).map(&:value)).to eq ["http://library.ucsd.edu/ark:/20775/bbXXXXXXX4"] - expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 4]/mads:elementValue', ns).map(&:text)).to eq ["20th century"] + ns = { rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', mads: 'http://www.loc.gov/mads/rdf/v1#' } + expect(doc.xpath('/rdf:RDF/rdf:Description/@rdf:about', ns).map(&:value)).to eq ['http://example.org/foo'] + expect(doc.xpath('//rdf:Description/mads:elementList/@rdf:parseType', ns).map(&:value)).to eq ['Collection'] + expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 1]/@rdf:about', ns).map(&:value)).to eq ['http://library.ucsd.edu/ark:/20775/bbXXXXXXX6'] + expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 2]/mads:elementValue', ns).map(&:text)).to eq ['Relations with Mexican Americans'] + expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 3]/@rdf:about', ns).map(&:value)).to eq ['http://library.ucsd.edu/ark:/20775/bbXXXXXXX4'] + expect(doc.xpath('//rdf:Description/mads:elementList/*[position() = 4]/mads:elementValue', ns).map(&:text)).to eq ['20th century'] end end end - describe "an empty list" do + describe 'an empty list' do subject { DemoList.new.elementList.build } - it "should have to_ary" do + it 'should have to_ary' do expect(subject.to_ary).to eq [] end end - describe "a list that has a constructed element" do + describe 'a list that has a constructed element' do let(:ds) { DemoList.new('http://example.org/foo') } let(:list) { ds.elementList.build } let!(:topic) { list.topicElement.build } - it "should have to_ary" do + it 'should have to_ary' do expect(list.to_ary.size).to eq 1 expect(list.to_ary.first.class).to eq DemoList::List::TopicElement end describe 'clearing a list' do - it "should be able to be cleared" do + it 'should be able to be cleared' do list.topicElement.build list.topicElement.build list.topicElement.build @@ -178,7 +179,7 @@ class TemporalElement end end - describe "a list with content" do + describe 'a list with content' do subject do subject = DemoList.new('http://example.org/foo') subject << RDF::RDFXML::Reader.for(:rdfxml).new(< END - ) + ) subject end - it "should have a subject" do - expect(subject.rdf_subject.to_s).to eq "http://example.org/foo" + it 'should have a subject' do + expect(subject.rdf_subject.to_s).to eq 'http://example.org/foo' end - let (:list) { subject.elementList.first } + let(:list) { subject.elementList.first } - it "should have fields" do - expect(list.first.rdf_subject).to eq "http://library.ucsd.edu/ark:/20775/bbXXXXXXX6" + it 'should have fields' do + expect(list.first.rdf_subject).to eq 'http://library.ucsd.edu/ark:/20775/bbXXXXXXX6' expect(list[1]).to be_kind_of DemoList::List::TopicElement - expect(list[1].elementValue).to eq ["Relations with Mexican Americans"] - expect(list[2].rdf_subject).to eq "http://library.ucsd.edu/ark:/20775/bbXXXXXXX4" + expect(list[1].elementValue).to eq ['Relations with Mexican Americans'] + expect(list[2].rdf_subject).to eq 'http://library.ucsd.edu/ark:/20775/bbXXXXXXX4' expect(list[3]).to be_kind_of DemoList::List::TemporalElement - expect(list[3].elementValue).to eq ["20th century"] + expect(list[3].elementValue).to eq ['20th century'] end - it "should have each" do + it 'should have each' do foo = [] list.each { |n| foo << n.class } expect(foo).to eq [ActiveTriples::Resource, @@ -227,7 +228,7 @@ class TemporalElement DemoList::List::TemporalElement] end - it "should have to_ary" do + it 'should have to_ary' do ary = list.to_ary expect(ary.size).to eq 4 @@ -235,33 +236,32 @@ class TemporalElement .to contain_exactly 'Relations with Mexican Americans' end - it "should have size" do + it 'should have size' do expect(list.size).to eq 4 end - - describe "updating fields" do - it "stores the values in a containing node" do - list[3].elementValue = ["1900s"] - doc = Nokogiri::XML(subject.dump :rdfxml) - ns = {rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", mads: "http://www.loc.gov/mads/rdf/v1#"} + describe 'updating fields' do + it 'stores the values in a containing node' do + list[3].elementValue = ['1900s'] + doc = Nokogiri::XML(subject.dump(:rdfxml)) + ns = { rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', mads: 'http://www.loc.gov/mads/rdf/v1#' } expect(doc.xpath('/rdf:RDF/mads:ComplexSubject/@rdf:about', ns).map(&:value)) - .to contain_exactly "http://example.org/foo" + .to contain_exactly 'http://example.org/foo' expect(doc.xpath('//mads:ComplexSubject/mads:elementList/@rdf:parseType', ns).map(&:value)) - .to contain_exactly "Collection" + .to contain_exactly 'Collection' expect(doc.xpath('//mads:ComplexSubject/mads:elementList/*[position() = 1]/@rdf:about', ns).map(&:value)) - .to contain_exactly "http://library.ucsd.edu/ark:/20775/bbXXXXXXX6" + .to contain_exactly 'http://library.ucsd.edu/ark:/20775/bbXXXXXXX6' expect(doc.xpath('//mads:ComplexSubject/mads:elementList/*[position() = 2]/mads:elementValue', ns).map(&:text)) - .to contain_exactly "Relations with Mexican Americans" + .to contain_exactly 'Relations with Mexican Americans' expect(doc.xpath('//mads:ComplexSubject/mads:elementList/*[position() = 3]/@rdf:about', ns).map(&:value)) - .to contain_exactly "http://library.ucsd.edu/ark:/20775/bbXXXXXXX4" + .to contain_exactly 'http://library.ucsd.edu/ark:/20775/bbXXXXXXX4' expect(doc.xpath('//mads:ComplexSubject/mads:elementList/*[position() = 4]/mads:elementValue', ns).map(&:text)) - .to contain_exactly "1900s" + .to contain_exactly '1900s' expect(RDF::List.new(subject: list.rdf_subject, graph: subject)).to be_valid end - it "should be a valid list" do - list << "Val" + it 'should be a valid list' do + list << 'Val' expect(RDF::List.new(subject: list.rdf_subject, graph: subject)).to be_valid end end diff --git a/spec/active_triples/nested_attributes_spec.rb b/spec/active_triples/nested_attributes_spec.rb index 8fc3a0e..6722f1d 100644 --- a/spec/active_triples/nested_attributes_spec.rb +++ b/spec/active_triples/nested_attributes_spec.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true + require 'spec_helper' -describe "nesting attribute behavior" do - describe ".attributes=" do - describe "complex properties" do +describe 'nesting attribute behavior' do + describe '.attributes=' do + describe 'complex properties' do before do - class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#") + class DummyMADS < RDF::Vocabulary('http://www.loc.gov/mads/rdf/v1#') # componentList and Types of components property :componentList property :Topic @@ -14,7 +15,6 @@ class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#") property :CorporateName property :ComplexSubject - # elementList and elementList values property :elementList property :elementValue @@ -27,27 +27,26 @@ class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#") class ComplexResource include ActiveTriples::RDFSource - property :topic, predicate: DummyMADS.Topic, class_name: "Topic" - property :personalName, predicate: DummyMADS.PersonalName, class_name: "PersonalName" + property :topic, predicate: DummyMADS.Topic, class_name: 'Topic' + property :personalName, predicate: DummyMADS.PersonalName, class_name: 'PersonalName' property :title, predicate: RDF::Vocab::DC.title - accepts_nested_attributes_for :topic, :personalName class Topic include ActiveTriples::RDFSource - property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexResource::ElementList" + property :elementList, predicate: DummyMADS.elementList, class_name: 'ComplexResource::ElementList' accepts_nested_attributes_for :elementList end class PersonalName include ActiveTriples::RDFSource - property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexResource::ElementList" - property :extraProperty, predicate: DummyMADS.elementValue, class_name: "ComplexResource::Topic" + property :elementList, predicate: DummyMADS.elementList, class_name: 'ComplexResource::ElementList' + property :extraProperty, predicate: DummyMADS.elementValue, class_name: 'ComplexResource::Topic' accepts_nested_attributes_for :elementList, :extraProperty end class ElementList < ActiveTriples::List configure type: DummyMADS.elementList - property :topicElement, predicate: DummyMADS.TopicElement, class_name: "ComplexResource::MadsTopicElement" + property :topicElement, predicate: DummyMADS.TopicElement, class_name: 'ComplexResource::MadsTopicElement' property :temporalElement, predicate: DummyMADS.TemporalElement property :fullNameElement, predicate: DummyMADS.FullNameElement property :dateNameElement, predicate: DummyMADS.DateNameElement @@ -57,7 +56,7 @@ class ElementList < ActiveTriples::List end class MadsTopicElement include ActiveTriples::RDFSource - configure :type => DummyMADS.TopicElement + configure type: DummyMADS.TopicElement property :elementValue, predicate: DummyMADS.elementValue end end @@ -76,14 +75,14 @@ class MadsTopicElement elementList_attributes: [{ topicElement_attributes: [{ id: 'http://library.ucsd.edu/ark:/20775/bb3333333x', - elementValue:"Cosmology" - }] + elementValue: 'Cosmology' }] + }] }, '1' => { elementList_attributes: [{ - topicElement_attributes: {'0' => {elementValue:"Quantum Behavior"}} + topicElement_attributes: { '0' => { elementValue: 'Quantum Behavior' } } }] } }, @@ -91,36 +90,35 @@ class MadsTopicElement { id: 'http://library.ucsd.edu/ark:20775/jefferson', elementList_attributes: [{ - fullNameElement: "Jefferson, Thomas", - dateNameElement: "1743-1826" + fullNameElement: 'Jefferson, Thomas', + dateNameElement: '1743-1826' }] } - #, "Hemings, Sally" - ], - } - } + # , "Hemings, Sally" + ] + } } end - describe "on lists" do + describe 'on lists' do subject { ComplexResource::PersonalName.new } - it "should accept a hash" do - subject.elementList_attributes = [{ topicElement_attributes: {'0' => { elementValue:"Quantum Behavior" }, '1' => { elementValue:"Wave Function" }}}] + it 'should accept a hash' do + subject.elementList_attributes = [{ topicElement_attributes: { '0' => { elementValue: 'Quantum Behavior' }, '1' => { elementValue: 'Wave Function' } } }] expect(subject.elementList.first[0].elementValue) - .to contain_exactly "Quantum Behavior" + .to contain_exactly 'Quantum Behavior' expect(subject.elementList.first[1].elementValue) - .to contain_exactly "Wave Function" + .to contain_exactly 'Wave Function' end - it "should accept an array" do - subject.elementList_attributes = [{ topicElement_attributes: [{ elementValue:"Quantum Behavior" }, { elementValue:"Wave Function" }]}] + it 'should accept an array' do + subject.elementList_attributes = [{ topicElement_attributes: [{ elementValue: 'Quantum Behavior' }, { elementValue: 'Wave Function' }] }] expect(subject.elementList.first[0].elementValue) - .to contain_exactly "Quantum Behavior" + .to contain_exactly 'Quantum Behavior' expect(subject.elementList.first[1].elementValue) - .to contain_exactly "Wave Function" + .to contain_exactly 'Wave Function' end end - context "from nested objects" do + context 'from nested objects' do before do # Replace the graph's contents with the Hash subject.attributes = params[:myResource] @@ -130,9 +128,9 @@ class MadsTopicElement expect(subject.topic.map { |topic| topic.elementList.first[0].elementValue }) .to contain_exactly ['Cosmology'], ['Quantum Behavior'] expect(subject.personalName.first.elementList.first.fullNameElement) - .to contain_exactly "Jefferson, Thomas" + .to contain_exactly 'Jefferson, Thomas' expect(subject.personalName.first.elementList.first.dateNameElement) - .to contain_exactly "1743-1826" + .to contain_exactly '1743-1826' end it 'should build nodes with ids' do @@ -143,22 +141,22 @@ class MadsTopicElement end it 'should fail when writing to a non-predicate' do - attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ fake_predicate:"Cosmology" }] }]}}} - expect{ subject.attributes = attributes }.to raise_error ArgumentError + attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ fake_predicate: 'Cosmology' }] }] } } } + expect { subject.attributes = attributes }.to raise_error ArgumentError end it 'should fail when writing to a non-predicate with a setter method' do - attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ name:"Cosmology" }] }]}}} - expect{ subject.attributes = attributes }.to raise_error ArgumentError + attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ name: 'Cosmology' }] }] } } } + expect { subject.attributes = attributes }.to raise_error ArgumentError end end end - context "a simple model" do + context 'a simple model' do before do class SpecResource include ActiveTriples::RDFSource - property :parts, predicate: RDF::Vocab::DC.hasPart, :class_name=>'Component' + property :parts, predicate: RDF::Vocab::DC.hasPart, class_name: 'Component' accepts_nested_attributes_for :parts, allow_destroy: true class Component @@ -167,82 +165,85 @@ class Component end end - SpecResource.accepts_nested_attributes_for *args + SpecResource.accepts_nested_attributes_for(*args) end after { Object.send(:remove_const, :SpecResource) } let(:args) { [:parts] } subject { SpecResource.new } - context "for an existing B-nodes" do + context 'for an existing B-nodes' do before do subject.attributes = { parts_attributes: [ - {label: 'Alternator'}, - {label: 'Distributor'}, - {label: 'Transmission'}, - {label: 'Fuel Filter'}]} + { label: 'Alternator' }, + { label: 'Distributor' }, + { label: 'Transmission' }, + { label: 'Fuel Filter' } + ] } subject.parts_attributes = new_attributes end - context "that allows destroy" do + context 'that allows destroy' do let(:args) { [:parts, allow_destroy: true] } - let (:replace_object_id) { subject.parts[1].rdf_subject.to_s } - let (:remove_object_id) { subject.parts[3].rdf_subject.to_s } + let(:replace_object_id) { subject.parts[1].rdf_subject.to_s } + let(:remove_object_id) { subject.parts[3].rdf_subject.to_s } let(:new_attributes) do - [{ id: replace_object_id, label: "Universal Joint" }, - { label:"Oil Pump" }, - { id: remove_object_id, _destroy: '1', label: "bar1 uno" }] + [{ id: replace_object_id, label: 'Universal Joint' }, + { label: 'Oil Pump' }, + { id: remove_object_id, _destroy: '1', label: 'bar1 uno' }] end - it "should update nested objects" do + it 'should update nested objects' do expect(subject.parts.map { |p| p.label.first }) - .to contain_exactly 'Universal Joint', 'Oil Pump', + .to contain_exactly 'Universal Joint', 'Oil Pump', an_instance_of(String), an_instance_of(String) end end - context "when an id is provided" do - let(:new_attributes) { [{ id: 'http://example.com/part#1', label: "Universal Joint" }] } + context 'when an id is provided' do + let(:new_attributes) { [{ id: 'http://example.com/part#1', label: 'Universal Joint' }] } - it "creates a new statement" do + it 'creates a new statement' do expect(subject.parts.map(&:rdf_subject)) .to include RDF::URI('http://example.com/part#1') end end end - context "for an existing resources" do + context 'for an existing resources' do before do subject.attributes = { parts_attributes: [ - { id: 'http://id.loc.gov/authorities/subjects/sh85010251' }, - { id: 'http://id.loc.gov/authorities/subjects/sh2001009145' }]} + { id: 'http://id.loc.gov/authorities/subjects/sh85010251' }, + { id: 'http://id.loc.gov/authorities/subjects/sh2001009145' } + ] } subject.parts_attributes = new_attributes end let(:args) { [:parts] } - let(:new_attributes) { [{ id: 'http://id.loc.gov/authorities/subjects/sh85010251' }, - { id: 'http://id.loc.gov/authorities/subjects/sh2001009145' }, - { id: 'http://id.loc.gov/authorities/subjects/sh85052223' }] } + let(:new_attributes) do + [{ id: 'http://id.loc.gov/authorities/subjects/sh85010251' }, + { id: 'http://id.loc.gov/authorities/subjects/sh2001009145' }, + { id: 'http://id.loc.gov/authorities/subjects/sh85052223' }] + end - it "should update nested objects" do - expect(subject.parts.map{|p| p.id}) - .to contain_exactly "http://id.loc.gov/authorities/subjects/sh85010251", - "http://id.loc.gov/authorities/subjects/sh2001009145", - "http://id.loc.gov/authorities/subjects/sh85052223" + it 'should update nested objects' do + expect(subject.parts.map(&:id)) + .to contain_exactly 'http://id.loc.gov/authorities/subjects/sh85010251', + 'http://id.loc.gov/authorities/subjects/sh2001009145', + 'http://id.loc.gov/authorities/subjects/sh85052223' end end - - context "for a new B-node" do - context "when called with reject_if" do + context 'for a new B-node' do + context 'when called with reject_if' do let(:args) { [:parts, reject_if: reject_proc] } - let(:reject_proc) { lambda { |attributes| attributes[:label] == 'Bar' } } - let(:new_attributes) { [{ label: "Universal Joint" }, { label: 'Bar'} ] } + let(:reject_proc) { ->(attributes) { attributes[:label] == 'Bar' } } + let(:new_attributes) { [{ label: 'Universal Joint' }, { label: 'Bar' }] } before { subject.parts_attributes = new_attributes } - it "should call the reject if proc" do + it 'should call the reject if proc' do expect(subject.parts.map(&:label)) .to contain_exactly(['Universal Joint']) end diff --git a/spec/active_triples/node_config_spec.rb b/spec/active_triples/node_config_spec.rb index bdf11f0..5884c19 100644 --- a/spec/active_triples/node_config_spec.rb +++ b/spec/active_triples/node_config_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::NodeConfig do diff --git a/spec/active_triples/persistable_spec.rb b/spec/active_triples/persistable_spec.rb index 8656547..383da7a 100644 --- a/spec/active_triples/persistable_spec.rb +++ b/spec/active_triples/persistable_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::Persistable do @@ -73,8 +74,8 @@ it 'sets new persistence strategy as an instance of the given class' do expect { subject.set_persistence_strategy(strategy_class) } .to change { subject.persistence_strategy } - .from(an_instance_of(ActiveTriples::RepositoryStrategy)) - .to(strategy) + .from(an_instance_of(ActiveTriples::RepositoryStrategy)) + .to(strategy) end end diff --git a/spec/active_triples/persistence_strategies/parent_strategy_spec.rb b/spec/active_triples/persistence_strategies/parent_strategy_spec.rb index 73dc943..c6905c8 100644 --- a/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +++ b/spec/active_triples/persistence_strategies/parent_strategy_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::ParentStrategy do @@ -27,12 +28,12 @@ end context 'after persist!' do - context "when the parent is not persisted" do + context 'when the parent is not persisted' do before { subject.persist! } it { is_expected.not_to be_persisted } end - context "when the parent is persisted" do + context 'when the parent is persisted' do before do allow(parent).to receive(:persisted?).and_return(true) subject.persist! @@ -146,11 +147,11 @@ end describe '#parent' do - it { is_expected.to have_attributes(:parent => nil) } + it { is_expected.to have_attributes(parent: nil) } context 'with a parent' do include_context 'with a parent' - it { is_expected.to have_attributes(:parent => parent) } + it { is_expected.to have_attributes(parent: parent) } end end @@ -189,7 +190,7 @@ expect { subject.persist! } .to change { subject.parent.statements } - .to contain_exactly *rdf_source.statements + .to contain_exactly(*rdf_source.statements) end it 'writes to #parent graph when parent changes while child is live' do @@ -200,8 +201,8 @@ expect { subject.persist! } .to change { parent.statements } - .from(contain_exactly(parent_st)) - .to(contain_exactly(parent_st, child_st)) + .from(contain_exactly(parent_st)) + .to(contain_exactly(parent_st, child_st)) end context 'with nested parents' do @@ -221,8 +222,8 @@ expect { subject.persist! } .to change { parent.statements } - .from(contain_exactly(parent_st)) - .to(contain_exactly(parent_st, child_st)) + .from(contain_exactly(parent_st)) + .to(contain_exactly(parent_st, child_st)) end it 'writes to #last graph when persisting' do @@ -233,8 +234,8 @@ expect { subject.persist!; parent.persist! } .to change { last.statements } - .from(contain_exactly(parent_st)) - .to(contain_exactly(parent_st, child_st)) + .from(contain_exactly(parent_st)) + .to(contain_exactly(parent_st, child_st)) end end end diff --git a/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb b/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb index af3b1ee..c3fdc74 100644 --- a/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb +++ b/spec/active_triples/persistence_strategies/persistence_strategy_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::PersistenceStrategy do @@ -7,19 +8,19 @@ describe '#persist!' do it 'raises as not implemented' do - expect { subject.persist! }.to raise_error NotImplementedError + expect { subject.persist! }.to raise_error NotImplementedError end end describe '#erase_old_resource' do it 'raises as not implemented' do - expect { subject.erase_old_resource }.to raise_error NotImplementedError + expect { subject.erase_old_resource }.to raise_error NotImplementedError end end describe '#reload' do it 'raises as not implemented' do - expect { subject.reload }.to raise_error NotImplementedError + expect { subject.reload }.to raise_error NotImplementedError end end end diff --git a/spec/active_triples/persistence_strategies/repository_strategy_spec.rb b/spec/active_triples/persistence_strategies/repository_strategy_spec.rb index dc06008..5d932bf 100644 --- a/spec/active_triples/persistence_strategies/repository_strategy_spec.rb +++ b/spec/active_triples/persistence_strategies/repository_strategy_spec.rb @@ -1,26 +1,50 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::RepositoryStrategy do subject { described_class.new(rdf_source) } - let(:source_class) { class MySource; include ActiveTriples::RDFSource; end } + let(:source_class) do + class MySource + include ActiveTriples::RDFSource + end + end let(:rdf_source) { source_class.new } let(:statement) do RDF::Statement.new(rdf_source.to_term, RDF::Vocab::DC.title, 'moomin') end - it_behaves_like 'a persistence strategy' + shared_context 'with repository' do + let(:repo) { RDF::Repository.new } + before do + source_class.configure repository: :my_repo + + allow(ActiveTriples::Repositories.repositories) + .to receive(:[]).with(:my_repo).and_return(repo) + end + end + + shared_context 'with no repository' do + before do + source_class.configure(repository: nil) + end + end + include_context 'with repository' do + it_behaves_like 'a persistence strategy' + end describe '#persisted?' do context 'before persist!' do + include_context 'with repository' it 'returns false' do expect(subject).not_to be_persisted end end context 'after persist!' do + include_context 'with repository' it 'returns true' do subject.persist! expect(subject).to be_persisted @@ -28,17 +52,9 @@ end end - shared_context 'with repository' do - let(:repo) { RDF::Repository.new } - before do - source_class.configure repository: :my_repo - - allow(ActiveTriples::Repositories.repositories) - .to receive(:[]).with(:my_repo).and_return(repo) - end - end - describe '#destroy' do + include_context 'with repository' + shared_examples 'destroy resource' do it 'removes the resource from the repository' do subject.persist! @@ -75,17 +91,21 @@ end describe '#destroyed?' do + include_context 'with repository' + it 'is false' do expect(subject).not_to be_destroyed end end describe '#persist!' do + include_context 'with repository' + it 'writes to #repository' do rdf_source << statement subject.persist! expect(subject.repository.statements) - .to contain_exactly *rdf_source.statements + .to contain_exactly(*rdf_source.statements) end end @@ -95,24 +115,32 @@ end describe '#reload' do - it 'when both repository and object are empty returns true' do + include_context 'with repository' + + it 'returns true' do expect(subject.reload).to be true end - context 'with unknown content in repo' do - include_context 'with repository' do - before { repo << statement } - end + include_context 'with repository' do + before { repo << statement } end end describe '#repository' do - it 'gives a repository when none is configured' do - expect(subject.repository).to be_a RDF::Repository - end + context 'with repository configured' do + include_context 'with repository' + + it 'gives a repository when none is configured' do + expect(subject.repository).to be_a RDF::Repository + end - it 'defaults to an ad-hoc in memory RDF::Repository' do - expect(subject.repository).to be_ephemeral + it 'defaults to an ad-hoc in memory RDF::Repository' do + expect(subject.repository).to be_ephemeral + end + + it 'gets repository' do + expect(subject.repository).to eq repo + end end context 'with repository configured' do @@ -126,10 +154,6 @@ expect { subject.repository } .to raise_error ActiveTriples::RepositoryNotFoundError end - - it 'gets repository' do - expect(subject.repository).to eq repo - end end end end diff --git a/spec/active_triples/properties_spec.rb b/spec/active_triples/properties_spec.rb index 81e8330..ba36a81 100644 --- a/spec/active_triples/properties_spec.rb +++ b/spec/active_triples/properties_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' describe ActiveTriples::Properties do before do class DummyProperties @@ -9,63 +10,63 @@ class DummyProperties end after do - Object.send(:remove_const, "DummyProperties") + Object.send(:remove_const, 'DummyProperties') end describe '#property' do it 'sets a property as a NodeConfig' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title + DummyProperties.property :title, predicate: RDF::Vocab::DC.title expect(DummyProperties.reflect_on_property(:title)).to be_kind_of ActiveTriples::NodeConfig end it 'sets the correct property' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title + DummyProperties.property :title, predicate: RDF::Vocab::DC.title expect(DummyProperties.reflect_on_property(:title).predicate).to eql RDF::Vocab::DC.title end it 'sets the correct property from string' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title.to_s + DummyProperties.property :title, predicate: RDF::Vocab::DC.title.to_s expect(DummyProperties.reflect_on_property(:title).predicate).to eql RDF::Vocab::DC.title end it 'sets index behaviors' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title do |index| + DummyProperties.property :title, predicate: RDF::Vocab::DC.title do |index| index.as :facetable, :searchable end expect(DummyProperties.reflect_on_property(:title)[:behaviors]) - .to eq [:facetable, :searchable] + .to eq %i[facetable searchable] end it 'sets class name' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title, :class_name => RDF::Literal + DummyProperties.property :title, predicate: RDF::Vocab::DC.title, class_name: RDF::Literal expect(DummyProperties.reflect_on_property(:title)[:class_name]).to eq RDF::Literal end it 'sets persistence strategy' do DummyProperties - .property :title, :predicate => RDF::Vocab::DC.title, :persist_to => :moomin + .property :title, predicate: RDF::Vocab::DC.title, persist_to: :moomin expect(DummyProperties.reflect_on_property(:title)[:persist_to]).to eq :moomin end it 'sets arbitrary properties' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title, :moomin => :moomin + DummyProperties.property :title, predicate: RDF::Vocab::DC.title, moomin: :moomin expect(DummyProperties.reflect_on_property(:title)[:moomin]).to eq :moomin end it 'constantizes string class names' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title, :class_name => "RDF::Literal" + DummyProperties.property :title, predicate: RDF::Vocab::DC.title, class_name: 'RDF::Literal' expect(DummyProperties.reflect_on_property(:title)[:class_name]).to eq RDF::Literal end it "keeps strings which it can't constantize as strings" do - DummyProperties.property :title, - :predicate => RDF::Vocab::DC.title, - :class_name => "FakeClassName" - expect(DummyProperties.reflect_on_property(:title)[:class_name]).to eq "FakeClassName" + DummyProperties.property :title, + predicate: RDF::Vocab::DC.title, + class_name: 'FakeClassName' + expect(DummyProperties.reflect_on_property(:title)[:class_name]).to eq 'FakeClassName' end it 'raises error when defining properties that are already methods' do - DummyProperties.send :define_method, :type, lambda { } + DummyProperties.send :define_method, :type, -> {} expect { DummyProperties.property :type, predicate: RDF::Vocab::DC.type } .to raise_error ArgumentError end @@ -75,12 +76,12 @@ class DummyProperties end it 'raises error when defining properties with a non-Roesource predicate' do - expect { DummyProperties.property :type, :predicate => 123 }.to raise_error ArgumentError + expect { DummyProperties.property :type, predicate: 123 }.to raise_error ArgumentError end it 'raises error when defining properties already have method setters' do - DummyProperties.send :define_method, :type=, lambda { } - expect { DummyProperties.property :type, :predicate => RDF::Vocab::DC.type }.to raise_error ArgumentError + DummyProperties.send :define_method, :type=, -> {} + expect { DummyProperties.property :type, predicate: RDF::Vocab::DC.type }.to raise_error ArgumentError end it 'allows resetting of properties' do @@ -93,7 +94,7 @@ class DummyProperties describe '#config_for_term_or_uri' do before do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title + DummyProperties.property :title, predicate: RDF::Vocab::DC.title end it 'finds property configuration by term symbol' do @@ -114,8 +115,8 @@ class DummyProperties describe '#fields' do before do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title - DummyProperties.property :name, :predicate => RDF::Vocab::FOAF.name + DummyProperties.property :title, predicate: RDF::Vocab::DC.title + DummyProperties.property :name, predicate: RDF::Vocab::FOAF.name end it 'lists its terms' do @@ -123,16 +124,16 @@ class DummyProperties end end - context "when using a subclass" do + context 'when using a subclass' do before do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title + DummyProperties.property :title, predicate: RDF::Vocab::DC.title class DummySubClass < DummyProperties - property :source, :predicate => RDF::Vocab::DC11[:source] + property :source, predicate: RDF::Vocab::DC11[:source] end end after do - Object.send(:remove_const, "DummySubClass") + Object.send(:remove_const, 'DummySubClass') end it 'should carry properties from superclass' do @@ -144,13 +145,13 @@ class DummySubClass < DummyProperties end describe '#generated_property_methods' do - it 'returns a GeneratedPropertyMethods module' do + it 'returns a GeneratedPropertyMethods module' do expect(DummyProperties.generated_property_methods) .to eq DummyProperties::GeneratedPropertyMethods end - it 'has setter and getter instance methods for set properties' do - DummyProperties.property :title, :predicate => RDF::Vocab::DC.title + it 'has setter and getter instance methods for set properties' do + DummyProperties.property :title, predicate: RDF::Vocab::DC.title expect(DummyProperties.generated_property_methods.instance_methods) .to contain_exactly(:title, :title=) end diff --git a/spec/active_triples/property_builder_spec.rb b/spec/active_triples/property_builder_spec.rb index e73403d..4411b54 100644 --- a/spec/active_triples/property_builder_spec.rb +++ b/spec/active_triples/property_builder_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::PropertyBuilder do @@ -15,7 +16,7 @@ expect(subject.build) .to have_attributes(term: name, predicate: predicate) end - + it 'yields an IndexObject' do expect { |b| subject.build(&b) }.to yield_control end diff --git a/spec/active_triples/property_spec.rb b/spec/active_triples/property_spec.rb index eda03c0..3f8d75c 100644 --- a/spec/active_triples/property_spec.rb +++ b/spec/active_triples/property_spec.rb @@ -1,20 +1,21 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::Property do subject { described_class.new(options) } let(:options) do { - :name => :title, - :predicate => RDF::Vocab::DC.title, - :class_name => "Test" + name: :title, + predicate: RDF::Vocab::DC.title, + class_name: 'Test' } end - it "should create accessors for each passed option" do + it 'should create accessors for each passed option' do expect(subject.name).to eq :title expect(subject.predicate).to eq RDF::Vocab::DC.title - expect(subject.class_name).to eq "Test" + expect(subject.class_name).to eq 'Test' end it 'should hold a block' do @@ -27,12 +28,12 @@ property.config.call end - describe "#to_h" do + describe '#to_h' do it "should not return the property's name" do - expect(subject.to_h).to eq ( + expect(subject.to_h).to eq( { - :predicate => RDF::Vocab::DC.title, - :class_name => "Test" + predicate: RDF::Vocab::DC.title, + class_name: 'Test' } ) end @@ -44,10 +45,10 @@ context '#cast' do it 'has a default of false' do - expect(described_class.new(:name => :title).cast).to eq(false) + expect(described_class.new(name: :title).cast).to eq(false) end it 'allows for the default to be overridden' do - expect(described_class.new(:name => :title, :cast => true).cast).to eq(true) + expect(described_class.new(name: :title, cast: true).cast).to eq(true) end end end diff --git a/spec/active_triples/rdf_source_spec.rb b/spec/active_triples/rdf_source_spec.rb index ab35e82..ff902b3 100644 --- a/spec/active_triples/rdf_source_spec.rb +++ b/spec/active_triples/rdf_source_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' require 'rdf/turtle' require 'rdf/spec/enumerable' @@ -125,7 +126,7 @@ class SourceWithCreator it 'notifies muliple observers of changes' do other_observer = double('second observer') - values = ['moomin', 'snork'] + values = %w[moomin snork] expect(observer) .to receive(:notify) @@ -428,7 +429,13 @@ class SourceWithCreator it 'is a no-op' do subject << RDF::Statement(subject, RDF::Vocab::DC.title, 'Moomin') - expect { subject.set_value(:not_a_property, '') rescue nil } + expect do + begin + subject.set_value(:not_a_property, '') + rescue StandardError + nil + end + end .not_to change { subject.triples.to_a } end end @@ -489,7 +496,7 @@ class SourceWithCreator context 'with multiple values' do include_examples 'setting values' do - let(:value) { %w('moominpapa moominmama') } + let(:value) { %w['moominpapa moominmama'] } end end diff --git a/spec/active_triples/reflection_spec.rb b/spec/active_triples/reflection_spec.rb index 3b9b8df..3b2a6d5 100644 --- a/spec/active_triples/reflection_spec.rb +++ b/spec/active_triples/reflection_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples::Reflection do @@ -23,7 +24,7 @@ .to change { klass._active_triples_config }.to config_hash end end - + describe '.properties' do it 'gets the set properties' do klass.properties = config_hash @@ -36,13 +37,13 @@ before { klass.properties = config_hash } it 'returns true for properties it has' do - klass._active_triples_config.each do |property, _| + klass._active_triples_config.each do |property, _| expect(klass).to have_property property end end it 'coerces to a string' do - klass._active_triples_config.each do |property, _| + klass._active_triples_config.each do |property, _| expect(klass).to have_property property.to_sym end end @@ -56,13 +57,13 @@ before { klass.properties = config_hash } it 'gets the config for the requested property' do - klass._active_triples_config.each do |property, config| + klass._active_triples_config.each do |property, config| expect(klass.reflect_on_property(property)).to eq config end end it 'coerces to a string' do - klass._active_triples_config.each do |property, config| + klass._active_triples_config.each do |property, config| expect(klass.reflect_on_property(property.to_sym)).to eq config end end diff --git a/spec/active_triples/relation_spec.rb b/spec/active_triples/relation_spec.rb index 7db1c0d..92b7612 100644 --- a/spec/active_triples/relation_spec.rb +++ b/spec/active_triples/relation_spec.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true + require 'spec_helper' require 'rdf/isomorphic' describe ActiveTriples::Relation do + subject { described_class.new(parent_resource, value_args) } + let(:parent_resource) { double('parent resource', reflections: {}) } let(:value_args) { double('value args', last: {}) } - let(:uri) { RDF::URI('http://example.org/moomin') } - subject { described_class.new(parent_resource, value_args) } - shared_context 'with URI property' do subject { described_class.new(parent_resource, [property]) } @@ -59,8 +59,8 @@ let(:other_property) { :snork } end - [:&, :|, :+].each do |array_method| - describe "#{array_method}" do + %i[& | +].each do |array_method| + describe array_method.to_s do shared_examples 'array method behavior' do it "behaves like `Array##{array_method}`" do expect(subject.send(array_method.to_sym, other_array)) @@ -202,15 +202,14 @@ end types = { numeric: [0, 1, 2, 3_000_000_000], - string: ['moomin', 'snork', 'snufkin'], - lang: [RDF::Literal('Moomin', language: :en), - RDF::Literal('Mummi', language: :fi)], - date: [Date.today, Date.today - 1], - uri: [RDF::URI('one'), RDF::URI('two'), RDF::URI('three')], - node: [RDF::Node.new, RDF::Node.new], - } - - types.each do |type, values| + string: %w[moomin snork snufkin], + lang: [RDF::Literal('Moomin', language: :en), + RDF::Literal('Mummi', language: :fi)], + date: [Date.today, Date.today - 1], + uri: [RDF::URI('one'), RDF::URI('two'), RDF::URI('three')], + node: [RDF::Node.new, RDF::Node.new] } + + types.each do |type, _values| it "gives 0 when containing the same #{type} elements" do subject << 1 other << 1 @@ -228,27 +227,27 @@ end end - it "gives 0 when containing the same varied elements" do + it 'gives 0 when containing the same varied elements' do expect(subject <=> other).to eq 0 end - it "gives nil when other contains a subset of varied elements" do + it 'gives nil when other contains a subset of varied elements' do subject << 'extra' expect(subject <=> other).to be_nil end - it "gives nil when other contains a superset of varied elements" do + it 'gives nil when other contains a superset of varied elements' do other << 'extra' expect(subject <=> other).to be_nil end - it "gives nil when other contains a subset by language" do - subject << RDF::Literal("Moomin", language: :aa) + it 'gives nil when other contains a subset by language' do + subject << RDF::Literal('Moomin', language: :aa) expect(subject <=> other).to be_nil end - it "gives nil when other contains a superset by language" do - other << RDF::Literal("Moomin", language: :aa) + it 'gives nil when other contains a superset by language' do + other << RDF::Literal('Moomin', language: :aa) expect(subject <=> other).to be_nil end end @@ -302,8 +301,8 @@ include_context 'with symbol property' do before do reflections.property :moomin, - cast: false, - predicate: RDF::Vocab::DC.relation + cast: false, + predicate: RDF::Vocab::DC.relation end end @@ -320,7 +319,7 @@ include_context 'with symbol property' do before do reflections.property :moomin, - predicate: RDF::Vocab::DC.relation, + predicate: RDF::Vocab::DC.relation, class_name: 'WithTitle' class WithTitle include ActiveTriples::RDFSource @@ -468,8 +467,8 @@ class WithTitle end it 'subtracts token values' do - subject.set([:one, :two, :three]) - expect { subject.subtract([:two, :three]) } + subject.set(%i[one two three]) + expect { subject.subtract(%i[two three]) } .to change { subject.to_a }.to contain_exactly(:one) end @@ -568,14 +567,14 @@ class WithTitle end it 'adds multiple values' do - values = [:moomin, :snork] + values = %i[moomin snork] expect { subject << values } .to change { subject.to_a }.to contain_exactly(*values) end it 'notifies observers on the parent' do observer = double(:observer) - values = [:moomin, :snork] + values = %i[moomin snork] parent_resource.add_observer(observer) expect(observer) @@ -591,24 +590,24 @@ class WithTitle expect { values.each { |v| subject << v } } .to change { subject.send(:objects).to_a } - .to contain_exactly(*values) + .to contain_exactly(*values) end it 'keeps languages' do - values = [RDF::Literal("Moomin", language: :en), - RDF::Literal("Mummi", language: :fi)] + values = [RDF::Literal('Moomin', language: :en), + RDF::Literal('Mummi', language: :fi)] expect { values.each { |v| subject << v } } .to change { subject.send(:objects).to_a } - .to contain_exactly(*values) + .to contain_exactly(*values) end context 'when given a Relation' do it 'keeps datatypes and languages of values' do values = [RDF::Literal(Date.today), RDF::Literal(:moomin), - RDF::Literal("Moomin", language: :en), - RDF::Literal("Mummi", language: :fi)] + RDF::Literal('Moomin', language: :en), + RDF::Literal('Mummi', language: :fi)] subject.set(values) expect(subject.send(:objects)).to contain_exactly(*values) @@ -626,8 +625,7 @@ class WithTitle expect { subject << 'snowflake' } .to change { subject.to_a } - .to contain_exactly(literal, 'snowflake') - + .to contain_exactly(literal, 'snowflake') end context 'with a datatyped literal' do @@ -646,7 +644,7 @@ class DummySnowflake < RDF::Literal expect { subject << 'special' } .to change { subject.send(:objects).to_a } - .to contain_exactly(literal, RDF::Literal('special')) + .to contain_exactly(literal, RDF::Literal('special')) end end end @@ -774,7 +772,7 @@ class DummySnowflake < RDF::Literal reflections .property property, class_name: this_class, - predicate: RDF::URI('http://example.org/moomin') + predicate: RDF::URI('http://example.org/moomin') end it 'casts values with no type to the class' do @@ -854,7 +852,14 @@ class DummySnowflake < RDF::Literal subject { described_class.new(parent_resource, double('value args')) } context 'when relation has 0 value arguments' do - before { subject.value_arguments = double(length: 0) } + let(:value_arguments) { double } + + before do + allow(value_arguments).to receive(:length).and_return(0) + allow(value_arguments).to receive(:empty?).and_return(true) + + subject.value_arguments = value_arguments + end it 'should raise an error' do expect { subject.send(:rdf_subject) }.to raise_error ArgumentError @@ -862,9 +867,14 @@ class DummySnowflake < RDF::Literal end context 'when term has 1 value argument' do + let(:value_arguments) { double } + before do + allow(value_arguments).to receive(:length).and_return(1) + allow(value_arguments).to receive(:empty?).and_return(false) + allow(subject.parent).to receive(:rdf_subject) { 'parent subject' } - subject.value_arguments = double(length: 1) + subject.value_arguments = value_arguments end it "should call `rdf_subject' on the parent" do @@ -877,7 +887,15 @@ class DummySnowflake < RDF::Literal end context 'when relation has 2 value arguments' do - before { subject.value_arguments = double(length: 2, first: 'first') } + let(:value_arguments) { double } + + before do + allow(value_arguments).to receive(:length).and_return(2) + allow(value_arguments).to receive(:first).and_return('first') + allow(value_arguments).to receive(:empty?).and_return(false) + + subject.value_arguments = value_arguments + end it 'should return the first value argument' do expect(subject.send(:rdf_subject)).to eq 'first' @@ -885,7 +903,13 @@ class DummySnowflake < RDF::Literal end context 'when relation has 3 value arguments' do - before { subject.value_arguments = double(length: 3) } + let(:value_arguments) { double } + before do + allow(value_arguments).to receive(:length).and_return(3) + allow(value_arguments).to receive(:empty?).and_return(false) + + subject.value_arguments = value_arguments + end it 'should raise an error' do expect { subject.send(:rdf_subject) }.to raise_error ArgumentError @@ -937,14 +961,14 @@ class DummySnowflake < RDF::Literal end it 'sets mulitple values' do - values = [:moomin, :snork] + values = %i[moomin snork] expect { subject.set(values) } .to change { subject.to_a }.to contain_exactly(*values) end it 'notifies observers on the parent' do observer = double(:observer) - values = [:moomin, :snork] + values = %i[moomin snork] parent_resource.add_observer(observer) expect(observer) @@ -967,9 +991,9 @@ class DummySnowflake < RDF::Literal values = [Date.today, 'Moomin', :moomin, - RDF::Literal("Moomin", language: :en), - RDF::Literal("Mummi", language: :fi), - RDF::Literal("Moomin", datatype: RDF::URI('custom')), + RDF::Literal('Moomin', language: :en), + RDF::Literal('Mummi', language: :fi), + RDF::Literal('Moomin', datatype: RDF::URI('custom')), DummySnowflake.new('Moomin')] subject.set(values) diff --git a/spec/active_triples/repositories_spec.rb b/spec/active_triples/repositories_spec.rb index 9a56c3f..5a21418 100644 --- a/spec/active_triples/repositories_spec.rb +++ b/spec/active_triples/repositories_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' describe ActiveTriples::Repositories do subject { ActiveTriples::Repositories } @@ -16,7 +17,7 @@ end it 'should throw an error if passed something that is not a repository' do - expect{subject.add_repository :name, :not_a_repo} + expect { subject.add_repository :name, :not_a_repo } .to raise_error ArgumentError end end @@ -29,7 +30,6 @@ end describe '#has_subject?' do - let(:resource2) do DummyResource2.new(2) end @@ -37,21 +37,21 @@ before do class DummyResource1 include ActiveTriples::RDFSource - configure :base_uri => "http://example.org/r1/", - :type => RDF::URI("http://example.org/SomeClass"), - :repository => :repo1 + configure base_uri: 'http://example.org/r1/', + type: RDF::URI('http://example.org/SomeClass'), + repository: :repo1 end class DummyResource2 include ActiveTriples::RDFSource - configure :base_uri => "http://example.org/r2/", - :type => RDF::URI("http://example.org/SomeClass"), - :repository => :repo2 + configure base_uri: 'http://example.org/r2/', + type: RDF::URI('http://example.org/SomeClass'), + repository: :repo2 end class DummyResource3 include ActiveTriples::RDFSource - configure :base_uri => "http://example.org/r3/", - :type => RDF::URI("http://example.org/SomeClass"), - :repository => :repo3 + configure base_uri: 'http://example.org/r3/', + type: RDF::URI('http://example.org/SomeClass'), + repository: :repo3 end ActiveTriples::Repositories.add_repository :repo1, RDF::Repository.new ActiveTriples::Repositories.add_repository :repo2, RDF::Repository.new @@ -60,16 +60,15 @@ class DummyResource3 DummyResource1.new('1').persist! DummyResource2.new('2').persist! DummyResource3.new('3').persist! - end after do DummyResource1.new('1').destroy! DummyResource2.new('2').destroy! DummyResource3.new('3').destroy! - Object.send(:remove_const, "DummyResource1") if Object - Object.send(:remove_const, "DummyResource2") if Object - Object.send(:remove_const, "DummyResource3") if Object + Object&.send(:remove_const, 'DummyResource1') + Object&.send(:remove_const, 'DummyResource2') + Object&.send(:remove_const, 'DummyResource3') ActiveTriples::Repositories.clear_repositories! end @@ -77,7 +76,7 @@ class DummyResource3 context 'and rdf_subject exists in the repository' do it 'should return true' do expect(ActiveTriples::Repositories - .has_subject?(resource2.rdf_subject,:repo2)) + .has_subject?(resource2.rdf_subject, :repo2)) .to be_truthy end end @@ -85,7 +84,7 @@ class DummyResource3 context 'and rdf_subject exists in another repository' do it 'should return false' do expect(ActiveTriples::Repositories - .has_subject?(resource2.rdf_subject,:repo1)) + .has_subject?(resource2.rdf_subject, :repo1)) .to be_falsey end end @@ -93,7 +92,7 @@ class DummyResource3 context 'and rdf_subject does not exists in any repository' do it 'should return false' do expect(ActiveTriples::Repositories - .has_subject?("#{resource2.rdf_subject}_NOEXIST",:repo1)) + .has_subject?("#{resource2.rdf_subject}_NOEXIST", :repo1)) .to be_falsey end end diff --git a/spec/active_triples/resource_spec.rb b/spec/active_triples/resource_spec.rb index 5b3890f..9e6551a 100644 --- a/spec/active_triples/resource_spec.rb +++ b/spec/active_triples/resource_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true + require 'spec_helper' +require 'rdf/turtle' describe ActiveTriples::Resource do it_behaves_like 'an ActiveModel' do @@ -8,18 +10,18 @@ before do class DummyLicense < ActiveTriples::Resource - property :title, :predicate => RDF::Vocab::DC.title + property :title, predicate: RDF::Vocab::DC.title end class DummyResource < ActiveTriples::Resource - configure :type => RDF::URI('http://example.org/SomeClass') - property :license, :predicate => RDF::Vocab::DC.license, :class_name => DummyLicense - property :title, :predicate => RDF::Vocab::DC.title + configure type: RDF::URI('http://example.org/SomeClass') + property :license, predicate: RDF::Vocab::DC.license, class_name: DummyLicense + property :title, predicate: RDF::Vocab::DC.title end end after do - Object.send(:remove_const, "DummyResource") if Object - Object.send(:remove_const, "DummyLicense") if Object + Object&.send(:remove_const, 'DummyResource') + Object&.send(:remove_const, 'DummyLicense') end subject { DummyResource.new } @@ -35,20 +37,20 @@ class DummyResource < ActiveTriples::Resource describe 'setting properties' do before do class DummyWithClass < ActiveTriples::Resource - configure :type => RDF::URI('http://example.org/DummyClass') + configure type: RDF::URI('http://example.org/DummyClass') end end - after { Object.send(:remove_const, "DummyWithClass") } + after { Object.send(:remove_const, 'DummyWithClass') } it 'should replace property value when Resource class has a rdf type' do dl1 = DummyWithClass.new('http://example.org/dl1') dl2 = DummyWithClass.new('http://example.org/dl2') subject.title = dl1 - expect( subject.title ).to eq [dl1] + expect(subject.title).to eq [dl1] subject.title = dl2 - expect( subject.title ).to eq [dl2] + expect(subject.title).to eq [dl2] end end @@ -57,13 +59,13 @@ class DummyWithClass < ActiveTriples::Resource expect(subject.rdf_subject.node?).to be true end - it "should be settable" do + it 'should be settable' do subject.set_subject! RDF::URI('http://example.org/moomin') expect(subject.rdf_subject).to eq RDF::URI('http://example.org/moomin') end - it "should raise an error when setting to an invalid uri" do - expect{ subject.set_subject!('not_a_uri') }.to raise_error "could not make a valid RDF::URI from not_a_uri" + it 'should raise an error when setting to an invalid uri' do + expect { subject.set_subject!('not_a_uri') }.to raise_error 'could not make a valid RDF::URI from not_a_uri' end describe 'when changing subject' do @@ -79,7 +81,12 @@ class DummyWithClass < ActiveTriples::Resource end it 'should update graph objects' do - expect(subject.has_statement?(RDF::Statement.new(RDF::URI('http://example.org/moomin_comics'), RDF::Vocab::DC.isPartOf, subject.rdf_subject))).to be true + subject_uri = RDF::URI('http://example.org/moomin_comics') + predicate_uri = RDF::Vocab::DC.isPartOf + object_uri = subject.rdf_subject + statement = RDF::Statement.new(subject_uri, predicate_uri, object_uri) + + expect(subject.has_statement?(statement)).to be true end it 'should leave other uris alone' do @@ -93,7 +100,7 @@ class DummyWithClass < ActiveTriples::Resource end it 'should not be settable' do - expect{ subject.set_subject! RDF::URI('http://example.org/moomin2') } + expect { subject.set_subject! RDF::URI('http://example.org/moomin2') } .to raise_error 'Refusing to update URI when one is already assigned!' end end @@ -114,48 +121,48 @@ class DummyWithClass < ActiveTriples::Resource end end - describe "#persisted?" do + describe '#persisted?' do context 'with a repository' do before do repository = RDF::Repository.new allow(subject).to receive(:repository).and_return(repository) end - context "when the object is new" do - it "should return false" do + context 'when the object is new' do + it 'should return false' do expect(subject).not_to be_persisted end end - context "when it is saved" do + context 'when it is saved' do before do - subject.title = "bla" + subject.title = 'bla' subject.persist! end - it "should return true" do + it 'should return true' do expect(subject).to be_persisted end - context "and then modified" do + context 'and then modified' do before do - subject.title = "newbla" + subject.title = 'newbla' end - it "should return true" do + it 'should return true' do expect(subject).to be_persisted end end - context "and then reloaded" do + context 'and then reloaded' do before do subject.reload end - it "should reset the title" do - expect(subject.title).to eq ["bla"] + it 'should reset the title' do + expect(subject.title).to eq ['bla'] end - it "should be persisted" do + it 'should be persisted' do expect(subject).to be_persisted end end @@ -163,32 +170,31 @@ class DummyWithClass < ActiveTriples::Resource end end - describe "#persist!" do - context "when the repository is set" do - context "and the item is not a blank node" do - - subject {DummyResource.new("info:fedora/example:pid")} + describe '#persist!' do + context 'when the repository is set' do + context 'and the item is not a blank node' do + subject { DummyResource.new('info:fedora/example:pid') } let(:result) { subject.persist! } before do @repo = RDF::Repository.new allow(subject.class).to receive(:repository).and_return(nil) allow(subject.persistence_strategy).to receive(:repository).and_return(@repo) - subject.title = "bla" + subject.title = 'bla' result end - it "should return true" do + it 'should return true' do expect(result).to eq true end - it "should persist to the repository" do + it 'should persist to the repository' do expect(@repo.statements.first).to eq subject.statements.first end - it "should delete from the repository" do + it 'should delete from the repository' do subject.reload - expect(subject.title).to eq ["bla"] + expect(subject.title).to eq ['bla'] subject.title = [] expect(subject.title).to eq [] subject.persist! @@ -197,23 +203,23 @@ class DummyWithClass < ActiveTriples::Resource expect(@repo.statements.to_a.length).to eq 1 # Only the type statement end - context "and validations are checked" do - let(:result) { subject.persist!(:validate => true) } + context 'and validations are checked' do + let(:result) { subject.persist!(validate: true) } context "and it's valid" do - it "should return true" do + it 'should return true' do expect(result).to eq true end end context "and it's invalid" do subject do - a = DummyResource.new("info:fedora/example:pid") + a = DummyResource.new('info:fedora/example:pid') allow(a).to receive(:valid?).and_return(false) a end - it "should return false" do + it 'should return false' do expect(result).to eq false end - it "should not be persisted" do + it 'should not be persisted' do expect(subject).not_to be_persisted end end @@ -222,100 +228,98 @@ class DummyWithClass < ActiveTriples::Resource end end - describe "#id_persisted?" do - - subject {DummyResourceWithBaseURI.new('1')} + describe '#id_persisted?' do + subject { DummyResourceWithBaseURI.new('1') } before do class DummyResourceWithBaseURI < ActiveTriples::Resource - configure :base_uri => "http://example.org", - :type => RDF::URI("http://example.org/SomeClass"), - :repository => :default + configure base_uri: 'http://example.org', + type: RDF::URI('http://example.org/SomeClass'), + repository: :default end ActiveTriples::Repositories.add_repository :default, RDF::Repository.new subject.persist! end after do - Object.send(:remove_const, "DummyResourceWithBaseURI") if Object + Object&.send(:remove_const, 'DummyResourceWithBaseURI') ActiveTriples::Repositories.clear_repositories! end - context "when ID is a string" do - it "should be false if ID does not exist" do + context 'when ID is a string' do + it 'should be false if ID does not exist' do expect(DummyResourceWithBaseURI.id_persisted?('2')).to be_falsey end - it "should be true if ID exists" do + it 'should be true if ID exists' do expect(DummyResourceWithBaseURI.id_persisted?('1')).to be_truthy end end - context "when ID is numeric" do - it "should be false if ID does not exist" do + context 'when ID is numeric' do + it 'should be false if ID does not exist' do expect(DummyResourceWithBaseURI.id_persisted?(2)).to be_falsey end - it "should be true if ID exists" do + it 'should be true if ID exists' do expect(DummyResourceWithBaseURI.id_persisted?(1)).to be_truthy end end - context "when object with ID in use is not persisted" do - it "should be false" do + context 'when object with ID in use is not persisted' do + it 'should be false' do DummyResourceWithBaseURI.new('3') expect(DummyResourceWithBaseURI.id_persisted?(3)).to be_falsey end end end - describe "#uri_persisted?" do - - subject {DummyResourceWithBaseURI.new('11')} + describe '#uri_persisted?' do + subject { DummyResourceWithBaseURI.new('11') } before do class DummyResourceWithBaseURI < ActiveTriples::Resource - configure :base_uri => "http://example.org", - :type => RDF::URI("http://example.org/SomeClass"), - :repository => :default + configure base_uri: 'http://example.org', + type: RDF::URI('http://example.org/SomeClass'), + repository: :default end ActiveTriples::Repositories.add_repository :default, RDF::Repository.new subject.persist! end after do - Object.send(:remove_const, "DummyResourceWithBaseURI") if Object + Object&.send(:remove_const, 'DummyResourceWithBaseURI') ActiveTriples::Repositories.clear_repositories! end - context "when URI is a http string" do - it "should be false if URI does not exist" do - expect(DummyResourceWithBaseURI.uri_persisted?("http://example.org/22")).to be_falsey + context 'when URI is a http string' do + it 'should be false if URI does not exist' do + expect(DummyResourceWithBaseURI.uri_persisted?('http://example.org/22')).to be_falsey end - it "should be true if URI does exist" do - expect(DummyResourceWithBaseURI.uri_persisted?("http://example.org/11")).to be_truthy + it 'should be true if URI does exist' do + expect(DummyResourceWithBaseURI.uri_persisted?('http://example.org/11')).to be_truthy end end - context "when URI is a RDF::URI" do - it "should be false if URI does not exist" do - expect(DummyResourceWithBaseURI.uri_persisted?(RDF::URI("http://example.org/22"))).to be_falsey + context 'when URI is a RDF::URI' do + it 'should be false if URI does not exist' do + expect(DummyResourceWithBaseURI.uri_persisted?(RDF::URI('http://example.org/22'))).to be_falsey end - it "should be true if URI does exist" do - expect(DummyResourceWithBaseURI.uri_persisted?(RDF::URI("http://example.org/11"))).to be_truthy + it 'should be true if URI does exist' do + expect(DummyResourceWithBaseURI.uri_persisted?(RDF::URI('http://example.org/11'))).to be_truthy end end - context "when object with URI is not persisted" do - it "should be false" do + context 'when object with URI is not persisted' do + it 'should be false' do DummyResourceWithBaseURI.new('13') - expect(DummyResourceWithBaseURI.uri_persisted?("http://example.org/13")).to be_falsey + expect(DummyResourceWithBaseURI.uri_persisted?('http://example.org/13')).to be_falsey end end end describe '#repository' do - subject { DummyLicense.new('http://example.org/cc')} + subject { DummyLicense.new('http://example.org/cc') } it "should warn when the repo doesn't exist" do allow(DummyLicense).to receive(:repository).and_return('repo2') @@ -329,7 +333,7 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource subject << RDF::Statement(RDF::Vocab::DC.LicenseDocument, RDF::Vocab::DC.title, 'LICENSE') end - subject { DummyLicense.new('http://example.org/cc')} + subject { DummyLicense.new('http://example.org/cc') } it 'should return true' do expect(subject.destroy!).to be true @@ -355,16 +359,15 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource describe 'class_name' do it 'should raise an error when not a class or string' do - DummyResource.property :relation, :predicate => RDF::Vocab::DC.relation, :class_name => RDF::URI('http://example.org') + DummyResource.property :relation, predicate: RDF::Vocab::DC.relation, class_name: RDF::URI('http://example.org') d = DummyResource.new d.relation = RDF::Vocab::DC.type - expect { d.relation.first }.to raise_error "class_name for relation is a RDF::URI; must be a class" + expect { d.relation.first }.to raise_error 'class_name for relation is a RDF::URI; must be a class' end it 'should return nil when none is given' do expect(DummyResource.reflect_on_property('title')[:class_name]).to be_nil end - end context 'property configuration' do @@ -423,13 +426,13 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource end it 'should build deep data for Resources' do - expect(subject.attributes[RDF::Vocab::DC.relation.to_s].first.get_values(RDF::Vocab::DC.relation). - first.get_values(RDF::Vocab::DC.title)).to eq ['bnode'] + expect(subject.attributes[RDF::Vocab::DC.relation.to_s].first.get_values(RDF::Vocab::DC.relation) + .first.get_values(RDF::Vocab::DC.title)).to eq ['bnode'] end it 'should include deep data in serializable_hash' do - expect(subject.serializable_hash[RDF::Vocab::DC.relation.to_s].first.get_values(RDF::Vocab::DC.relation). - first.get_values(RDF::Vocab::DC.title)).to eq ['bnode'] + expect(subject.serializable_hash[RDF::Vocab::DC.relation.to_s].first.get_values(RDF::Vocab::DC.relation) + .first.get_values(RDF::Vocab::DC.title)).to eq ['bnode'] end end @@ -458,7 +461,7 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource it 'should return an object with the correct URI when the value is a URI ' do subject.license = DummyLicense.new('http://example.org/license') - expect(subject.license.first.rdf_subject).to eq RDF::URI("http://example.org/license") + expect(subject.license.first.rdf_subject).to eq RDF::URI('http://example.org/license') end it 'should return an object of the correct class when the value is a bnode' do @@ -470,43 +473,44 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource describe '#set_value' do it 'should set a value in the graph' do subject.set_value(RDF::Vocab::DC.title, 'Comet in Moominland') - subject.query([subject.rdf_subject, nil, RDF::Vocab::DC.title]).each_statement do |s| + solutions = subject.query([subject.rdf_subject, RDF::Vocab::DC.title, nil]) + solutions.each_statement do |s| expect(s.object.to_s).to eq 'Comet in Moominland' end end - context "when given a URI" do + context 'when given a URI' do before do - subject.set_value(RDF::Vocab::DC.title, RDF::URI("http://opaquenamespace.org/jokes/1")) + subject.set_value(RDF::Vocab::DC.title, RDF::URI('http://opaquenamespace.org/jokes/1')) end - it "should return a resource" do + it 'should return a resource' do expect(subject.title.first).to be_kind_of(ActiveTriples::RDFSource) end context "and it's configured to not cast" do before do subject.class.property :title, predicate: RDF::Vocab::DC.title, cast: false end - it "should return a URI" do + it 'should return a URI' do expect(subject.title.first).to be_kind_of(RDF::URI) end end end - it "safely handles terms passed in" do + it 'safely handles terms passed in' do vals = subject.get_values('license') - vals << "foo" - subject.set_value('license',vals) + vals << 'foo' + subject.set_value('license', vals) expect(subject.get_values('license')) - .to contain_exactly "foo" + .to contain_exactly 'foo' end - it "safely handles terms passed in with pre-existing values" do - subject.license = "foo" + it 'safely handles terms passed in with pre-existing values' do + subject.license = 'foo' vals = subject.get_values('license') - vals << "bar" - subject.set_value('license',vals) + vals << 'bar' + subject.set_value('license', vals) expect(subject.get_values('license')) - .to contain_exactly "foo","bar" + .to contain_exactly 'foo', 'bar' end it 'should set a value in the when given a registered property symbol' do @@ -515,21 +519,23 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource .to contain_exactly 'Comet in Moominland' end - it "raise an error if the value is not a Term" do - expect{ subject.set_value(RDF::Vocab::DC.title, Object.new) } + it 'raise an error if the value is not a Term' do + expect { subject.set_value(RDF::Vocab::DC.title, Object.new) } .to raise_error ActiveTriples::Relation::ValueError end - it "should be able to accept a subject" do - expect{subject.set_value(RDF::URI("http://opaquenamespace.org/jokes"), RDF::Vocab::DC.title, 'Comet in Moominland')}.not_to raise_error - expect(subject.query([RDF::URI("http://opaquenamespace.org/jokes"), RDF::Vocab::DC.title, nil]).statements.to_a.length).to eq 1 + it 'should be able to accept a subject' do + expect { subject.set_value(RDF::URI('http://opaquenamespace.org/jokes'), RDF::Vocab::DC.title, 'Comet in Moominland') }.not_to raise_error + solutions = subject.query([RDF::URI('http://opaquenamespace.org/jokes'), RDF::Vocab::DC.title, nil]) + expect(solutions.statements.to_a.length).to eq 1 end end describe '#[]=' do it 'should set a value in the graph' do subject[RDF::Vocab::DC.title] = 'Comet in Moominland' - subject.query([subject.rdf_subject, nil, RDF::Vocab::DC.title]).each_statement do |s| + solutions = subject.query([subject.rdf_subject, nil, RDF::Vocab::DC.title, nil]) + solutions.each_statement do |s| expect(s.object.to_s).to eq 'Comet in Moominland' end end @@ -539,7 +545,7 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource expect(subject.title).to contain_exactly 'Comet in Moominland' end - it "raise an error if the value is not a URI, Node, Literal, RdfResource, or string" do + it 'raise an error if the value is not a URI, Node, Literal, RdfResource, or string' do expect { subject[RDF::Vocab::DC.title] = Object.new } .to raise_error ActiveTriples::Relation::ValueError end @@ -547,7 +553,7 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource describe '#get_values' do before do - subject.title = ['Comet in Moominland', "Finn Family Moomintroll"] + subject.title = ['Comet in Moominland', 'Finn Family Moomintroll'] end it 'should return values for a predicate uri' do @@ -560,24 +566,24 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource .to contain_exactly 'Comet in Moominland', 'Finn Family Moomintroll' end - it "should return values for other subjects if asked" do - expect(subject.get_values(RDF::URI("http://opaquenamespace.org/jokes"),:title)).to eq [] - subject.set_value(RDF::URI("http://opaquenamespace.org/jokes"), RDF::Vocab::DC.title, 'Comet in Moominland') + it 'should return values for other subjects if asked' do + expect(subject.get_values(RDF::URI('http://opaquenamespace.org/jokes'), :title)).to eq [] + subject.set_value(RDF::URI('http://opaquenamespace.org/jokes'), RDF::Vocab::DC.title, 'Comet in Moominland') - expect(subject.get_values(RDF::URI("http://opaquenamespace.org/jokes"),:title)) - .to contain_exactly "Comet in Moominland" + expect(subject.get_values(RDF::URI('http://opaquenamespace.org/jokes'), :title)) + .to contain_exactly 'Comet in Moominland' end - context "literals are set" do - let(:literal1) { RDF::Literal.new("test", :language => :en) } - let(:literal2) { RDF::Literal.new("test", :language => :fr) } + context 'literals are set' do + let(:literal1) { RDF::Literal.new('test', language: :en) } + let(:literal2) { RDF::Literal.new('test', language: :fr) } before do subject.set_value(RDF::Vocab::DC.title, [literal1, literal2]) end - it "should return literals" do - expect(subject.get_values(RDF::Vocab::DC.title, :literal => true)) + it 'should return literals' do + expect(subject.get_values(RDF::Vocab::DC.title, literal: true)) .to contain_exactly literal1, literal2 end end @@ -585,7 +591,7 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource describe '#[]' do before do - subject.title = ['Comet in Moominland', "Finn Family Moomintroll"] + subject.title = ['Comet in Moominland', 'Finn Family Moomintroll'] end it 'should return values for a predicate uri' do @@ -598,10 +604,10 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource .to contain_exactly('Comet in Moominland', 'Finn Family Moomintroll') end - it "should return values for other subjects if asked" do - expect(subject.get_values(RDF::URI("http://opaquenamespace.org/jokes"),:title)).to eq [] - subject.set_value(RDF::URI("http://opaquenamespace.org/jokes"), RDF::Vocab::DC.title, 'Comet in Moominland') - expect(subject.get_values(RDF::URI("http://opaquenamespace.org/jokes"),:title)).to eq ["Comet in Moominland"] + it 'should return values for other subjects if asked' do + expect(subject.get_values(RDF::URI('http://opaquenamespace.org/jokes'), :title)).to eq [] + subject.set_value(RDF::URI('http://opaquenamespace.org/jokes'), RDF::Vocab::DC.title, 'Comet in Moominland') + expect(subject.get_values(RDF::URI('http://opaquenamespace.org/jokes'), :title)).to eq ['Comet in Moominland'] end end @@ -616,7 +622,8 @@ class DummyResourceWithBaseURI < ActiveTriples::Resource end it 'should be the type in the graph' do - subject.query([subject.rdf_subject, nil, RDF.type]).statements do |s| + solutions = subject.query([subject.rdf_subject, nil, RDF.type]) + solutions.statements do |s| expect(s.object).to eq RDF::URI('http://example.org/AnotherClass') end end @@ -673,7 +680,8 @@ class DummyBook < ActiveTriples::Resource \"#{@chapter_title}\" ]; \"#{@book_title}\" ." - book_graph = ::RDF::Graph.new.from_ttl ttl + parsed = RDF::Turtle::Reader.new(ttl) + book_graph = ::RDF::Graph.new << parsed r = ActiveTriples::Repositories.repositories[:default] r << book_graph @@ -754,66 +762,67 @@ class DummyBook < ActiveTriples::Resource before do class DummyPerson include ActiveTriples::RDFSource - configure :type => RDF::URI('http://example.org/Person') - property :foaf_name, :predicate => RDF::Vocab::FOAF.name - property :publications, :predicate => RDF::Vocab::FOAF.publications, :class_name => 'DummyDocument' - property :knows, :predicate => RDF::Vocab::FOAF.knows, :class_name => DummyPerson + configure type: RDF::URI('http://example.org/Person') + property :foaf_name, predicate: RDF::Vocab::FOAF.name + property :publications, predicate: RDF::Vocab::FOAF.publications, class_name: 'DummyDocument' + property :knows, predicate: RDF::Vocab::FOAF.knows, class_name: DummyPerson end class DummyDocument include ActiveTriples::RDFSource - configure :type => RDF::URI('http://example.org/Document') - property :title, :predicate => RDF::Vocab::DC.title - property :creator, :predicate => RDF::Vocab::DC.creator, :class_name => 'DummyPerson' + configure type: RDF::URI('http://example.org/Document') + property :title, predicate: RDF::Vocab::DC.title + property :creator, predicate: RDF::Vocab::DC.creator, class_name: 'DummyPerson' end - DummyResource.property :item, :predicate => RDF::Vocab::DC.relation, :class_name => DummyDocument + DummyResource.property :item, predicate: RDF::Vocab::DC.relation, class_name: DummyDocument end subject { DummyResource.new } - let (:document1) do + let(:document1) do d = DummyDocument.new d.title = 'Document One' d end - let (:document2) do + let(:document2) do d = DummyDocument.new d.title = 'Document Two' d end - let (:person1) do + let(:person1) do p = DummyPerson.new p.foaf_name = 'Alice' p end - let (:person2) do + let(:person2) do p = DummyPerson.new p.foaf_name = 'Bob' p end - let (:data) { < . -_:1 _:2 . -_:2 . -_:2 "Document One" . -_:2 _:3 . -_:2 _:4 . -_:4 . -_:4 "Bob" . -_:3 . -_:3 "Alice" . -_:3 _:4 ." -END - } + let(:data) do + <<~END + _:1 . + _:1 _:2 . + _:2 . + _:2 "Document One" . + _:2 _:3 . + _:2 _:4 . + _:4 . + _:4 "Bob" . + _:3 . + _:3 "Alice" . + _:3 _:4 ." + END + end after do - Object.send(:remove_const, "DummyDocument") - Object.send(:remove_const, "DummyPerson") + Object.send(:remove_const, 'DummyDocument') + Object.send(:remove_const, 'DummyPerson') end it 'should allow access to deep nodes' do @@ -824,27 +833,27 @@ class DummyDocument subject.item = [document1] expect(subject.item.first.creator.first.knows.first.foaf_name) - .to satisfy { |names| ['Alice', 'Bob'].include? names.first } + .to satisfy { |names| %w[Alice Bob].include? names.first } end end - describe "callbacks" do - describe ".before_persist" do + describe 'callbacks' do + describe '.before_persist' do before do class DummyResource include ActiveTriples::RDFSource def bla - self.title = "test" + self.title = 'test' end end DummyResource.before_persist :bla repository = RDF::Repository.new allow(subject).to receive(:repository).and_return(repository) end - it "should call prior to persisting" do + it 'should call prior to persisting' do expect(subject.title).to be_blank subject.persist! - expect(subject.title).to contain_exactly "test" + expect(subject.title).to contain_exactly 'test' end end end diff --git a/spec/active_triples/schema_spec.rb b/spec/active_triples/schema_spec.rb index d7ba5c8..332b52b 100644 --- a/spec/active_triples/schema_spec.rb +++ b/spec/active_triples/schema_spec.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true + require 'spec_helper' RSpec.describe ActiveTriples::Schema do subject { described_class } - describe ".property" do - it "should define a property" do - subject.property :title, :predicate => RDF::Vocab::DC.title + describe '.property' do + it 'should define a property' do + subject.property :title, predicate: RDF::Vocab::DC.title property = subject.properties.first expect(property.name).to eq :title @@ -14,7 +15,7 @@ end it 'should hold a block' do - subject.property :title, :predicate => RDF::Vocab::DC.title do + subject.property :title, predicate: RDF::Vocab::DC.title do configure end end diff --git a/spec/active_triples/undefined_property_error_spec.rb b/spec/active_triples/undefined_property_error_spec.rb index 8b6aee1..7283eff 100644 --- a/spec/active_triples/undefined_property_error_spec.rb +++ b/spec/active_triples/undefined_property_error_spec.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' describe ActiveTriples::UndefinedPropertyError do subject { described_class.new(property, klass) } - + let(:property) { :a_property } let(:klass) { :a_class } it { expect(subject.message).to be_a String } - + it { expect(subject.property).to eq property } it { expect(subject.klass).to eq klass } end - diff --git a/spec/active_triples/util/buffered_transaction_spec.rb b/spec/active_triples/util/buffered_transaction_spec.rb index 5e37fa9..c4f8548 100644 --- a/spec/active_triples/util/buffered_transaction_spec.rb +++ b/spec/active_triples/util/buffered_transaction_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' require 'rdf/spec/transaction' require 'active_triples/util/buffered_transaction' @@ -77,7 +78,7 @@ end describe '#snapshot' do - it 'returns its current internal state' + it 'returns its current internal state' end describe '#each' do @@ -108,7 +109,7 @@ # it_behaves_like 'a buffered changeset' # it_behaves_like 'an optimist' - + # describe '#execute' do # it 'does not reflect changes to parent' do # st = [:s, RDF::URI(:p), 'o'] @@ -120,7 +121,7 @@ # expect { repository.insert(st); repository.execute } # .not_to change { subject.statements } # end - + # context 'with no changes' do # it 'leaves parent tx unchanged' do # expect { subject.execute }.not_to change { repository.statements } @@ -143,7 +144,7 @@ # context 'with changes' do # let(:ins) { RDF::Statement(:ins, RDF::URI('p'), 'o') } # let(:del) { RDF::Statement(:del, RDF::URI('p'), 'o') } - + # before do # subject.insert(ins) # subject.delete(del) diff --git a/spec/active_triples/util/extended_bounded_description_spec.rb b/spec/active_triples/util/extended_bounded_description_spec.rb index d3977e9..f283a45 100644 --- a/spec/active_triples/util/extended_bounded_description_spec.rb +++ b/spec/active_triples/util/extended_bounded_description_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' require 'rdf/spec/enumerable' require 'rdf/spec/queryable' require 'active_triples/util/extended_bounded_description' @@ -14,7 +15,7 @@ it { is_expected.not_to be_mutable } shared_examples 'a bounded description' do - before do + before do source_graph.insert(*included_statements) source_graph.insert(*excluded_statements) end @@ -27,7 +28,7 @@ expect(subject).to contain_exactly(*included_statements) expect(subject).to contain_exactly(*included_statements) end - + it 'is queryable' do expect(subject.query([nil, nil, nil])) .to contain_exactly(*included_statements) @@ -62,7 +63,7 @@ # # *** end boring stuff ## - + let(:included_statements) do [RDF::Statement(starting_node, RDF::URI('p1'), 'o'), RDF::Statement(starting_node, RDF::URI('p2'), 0), @@ -86,10 +87,10 @@ included_statements << RDF::Statement(starting_node, RDF::URI('a'), ancestor) - excluded_statements << + excluded_statements << RDF::Statement(ancestor, RDF::URI('a'), starting_node) end - + let(:ancestor) { RDF::Node.new(:ancestor) } let(:ancestors) { [ancestor] } diff --git a/spec/active_triples/value_error_spec.rb b/spec/active_triples/value_error_spec.rb index a2f3e61..3af8474 100644 --- a/spec/active_triples/value_error_spec.rb +++ b/spec/active_triples/value_error_spec.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true -require "spec_helper" + +require 'spec_helper' describe ActiveTriples::Relation::ValueError do subject { described_class.new(value) } - + let(:value) { :a_value } it { expect(subject.message).to be_a String } diff --git a/spec/active_triples_spec.rb b/spec/active_triples_spec.rb index 2eb0a2a..3a6b3a4 100644 --- a/spec/active_triples_spec.rb +++ b/spec/active_triples_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' describe ActiveTriples do @@ -10,7 +11,7 @@ class TestClass; end class TestBase; end end - + after do Object.send(:remove_const, :TestModule) Object.send(:remove_const, :TestBase) @@ -50,7 +51,7 @@ class TestBase; end .to eq TestModule::TestClass end end - + describe '.ActiveTripels' do it 'outputs a string' do expect { described_class.ActiveTripels }.to output.to_stdout diff --git a/spec/integration/dummies/dummy_resource_a.rb b/spec/integration/dummies/dummy_resource_a.rb index 652d33e..fd3bfe6 100644 --- a/spec/integration/dummies/dummy_resource_a.rb +++ b/spec/integration/dummies/dummy_resource_a.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + class DummyResourceA include ActiveTriples::RDFSource - configure :type => RDF::URI('http://example.org/type/ResourceA') - property :label, :predicate => RDF::URI('http://example.org/ontology/label') - property :has_resource, :predicate => RDF::URI('http://example.org/ontology/has_resource'), :class_name => DummyResourceB + configure type: RDF::URI('http://example.org/type/ResourceA') + property :label, predicate: RDF::URI('http://example.org/ontology/label') + property :has_resource, predicate: RDF::URI('http://example.org/ontology/has_resource'), class_name: DummyResourceB end diff --git a/spec/integration/dummies/dummy_resource_b.rb b/spec/integration/dummies/dummy_resource_b.rb index 7f5f2d5..c4b2151 100644 --- a/spec/integration/dummies/dummy_resource_b.rb +++ b/spec/integration/dummies/dummy_resource_b.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + class DummyResourceB include ActiveTriples::RDFSource - configure :type => RDF::URI('http://example.org/type/ResourceB') - property :label, :predicate => RDF::URI('http://example.org/ontology/label') - property :in_resource, :predicate => RDF::URI('http://example.org/ontology/in_resource'), :class_name => DummyResourceA + configure type: RDF::URI('http://example.org/type/ResourceB') + property :label, predicate: RDF::URI('http://example.org/ontology/label') + property :in_resource, predicate: RDF::URI('http://example.org/ontology/in_resource'), class_name: DummyResourceA end diff --git a/spec/integration/parent_persistence_spec.rb b/spec/integration/parent_persistence_spec.rb index 3cfdc0c..39b66dc 100644 --- a/spec/integration/parent_persistence_spec.rb +++ b/spec/integration/parent_persistence_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true + require 'spec_helper' -describe "When using the ParentPersistenceStrategy" do - context "a new child object" do +describe 'When using the ParentPersistenceStrategy' do + context 'a new child object' do before do class ParentThing < ActiveTriples::Resource property :child, predicate: RDF::URI('http://example.org/#child') diff --git a/spec/integration/reciprocal_properties_spec.rb b/spec/integration/reciprocal_properties_spec.rb index 21fb4b0..483a199 100644 --- a/spec/integration/reciprocal_properties_spec.rb +++ b/spec/integration/reciprocal_properties_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' autoload :DummyResourceA, 'integration/dummies/dummy_resource_a' autoload :DummyResourceB, 'integration/dummies/dummy_resource_b' @@ -8,14 +10,14 @@ ActiveTriples::Repositories.add_repository :default, RDF::Repository.new end - let (:a) do + let(:a) do # a = DummyResourceA.new(RDF::URI('http://example.com/a')) a = DummyResourceA.new a.label = 'resource A' a end - let (:b) do + let(:b) do # b = DummyResourceB.new(RDF::URI('http://example.com/b')) b = DummyResourceB.new b.label = 'resource B' @@ -39,13 +41,13 @@ end context 'when using parent_strategy for some' do - let (:a) do + let(:a) do d = DummyResourceA.new(RDF::URI('http://example.com/a')) d.label = 'resource A' d end - let (:b) do + let(:b) do p = DummyResourceB.new(RDF::URI('http://example.com/b'), a) p.label = 'resource B' p diff --git a/spec/pragmatic_context_spec.rb b/spec/pragmatic_context_spec.rb new file mode 100644 index 0000000..df74661 --- /dev/null +++ b/spec/pragmatic_context_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'pragmatic_context' + +describe 'PragmaticContext integration' do + before do + class DummyLicense + include ActiveTriples::RDFSource + include PragmaticContext::Contextualizable + property :title, predicate: RDF::Vocab::DC.title + + contextualize :title, as: RDF::Vocab::DC.title.to_s + end + + class DummyResource + include ActiveTriples::RDFSource + include PragmaticContext::Contextualizable + + configure type: RDF::URI('http://example.org/SomeClass') + property :license, predicate: RDF::Vocab::DC.license, + class_name: DummyLicense + property :title, predicate: RDF::Vocab::DC.title + + contextualize :title, as: RDF::Vocab::DC.title.to_s + contextualize :license, as: RDF::Vocab::DC.license.to_s + end + + license.title = 'cc' + subject.title = 'my resource' + subject.license = license + subject.license << RDF::Literal('Creative Commons') + end + + after do + Object.send(:remove_const, 'DummyResource') + Object.send(:remove_const, 'DummyLicense') + end + + subject { DummyResource.new('http://example.org/test') } + let(:license) { DummyLicense.new } + + xit 'should output a valid jsonld representation of itself' do + g = RDF::Graph.new << JSON::LD::API.toRdf(subject.as_jsonld) + expect(subject == g).to be true + end + + it 'should have contexts' do + expect(subject.as_jsonld['@context'].keys).to contain_exactly('license', 'title') + end + + it 'should use context with dump' do + context = JSON.parse(subject.dump(:jsonld))['@context'] + subject.class.properties.keys.each do |prop| + expect(context).to include prop + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f1ff138..0cf7ee7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,11 @@ # frozen_string_literal: true + require 'simplecov' SimpleCov.start +require 'coveralls' +Coveralls.wear! + require 'bundler/setup' Bundler.setup @@ -10,9 +14,9 @@ require 'webmock/rspec' require 'active_triples' -require 'pry' unless ENV["CI"] +require 'pry-byebug' unless ENV['CI'] -Dir['./spec/support/**/*.rb'].each { |f| require f } +Dir['./spec/support/**/*.rb'].sort.each { |f| require f } WebMock.disable_net_connect! diff --git a/spec/support/active_model_lint.rb b/spec/support/active_model_lint.rb index db1cf0a..c373516 100644 --- a/spec/support/active_model_lint.rb +++ b/spec/support/active_model_lint.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -shared_examples_for "an ActiveModel" do + +shared_examples_for 'an ActiveModel' do subject { am_lint_class.new } describe '#to_key' do @@ -8,7 +9,9 @@ end it 'should return an array of keys ' do - def subject.persisted?() false end + def subject.persisted? + false + end expect(subject.to_key).to contain_exactly(subject.id) end end @@ -19,7 +22,9 @@ def subject.persisted?() false end end it 'should return nil when #persisted? is false ' do - def subject.persisted?() false end + def subject.persisted? + false + end expect(subject.to_param).to eq nil end end @@ -76,7 +81,7 @@ def subject.persisted?() false end private - def match_boolean(result) - result == true || result == false - end + def match_boolean(result) + result == true || result == false + end end diff --git a/spec/support/dummies/basic_persistable.rb b/spec/support/dummies/basic_persistable.rb index 81bcb39..138dd09 100644 --- a/spec/support/dummies/basic_persistable.rb +++ b/spec/support/dummies/basic_persistable.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class BasicPersistable include ActiveTriples::RDFSource end diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 774508e..a788b5e 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'spec_helper' RSpec::Matchers.define :be_a_relation_containing do |*expected| @@ -20,4 +21,3 @@ true end end - diff --git a/spec/support/shared_examples/persistence_strategy.rb b/spec/support/shared_examples/persistence_strategy.rb index 88f6862..1b78840 100644 --- a/spec/support/shared_examples/persistence_strategy.rb +++ b/spec/support/shared_examples/persistence_strategy.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true + shared_examples 'a persistence strategy' do shared_context 'with changes' do before do - subject.source << + subject.source << RDF::Statement.new(RDF::Node.new, RDF::Vocab::DC.title, 'moomin') end end