valkyrie 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -3
  3. data/.rubocop.yml +28 -0
  4. data/Gemfile +6 -1
  5. data/README.md +145 -10
  6. data/Rakefile +59 -1
  7. data/bin/console +1 -1
  8. data/config/valkyrie.yml +8 -0
  9. data/db/config.yml +17 -0
  10. data/db/migrate/20160111215816_enable_uuid_extension.rb +6 -0
  11. data/db/migrate/20161007101725_create_orm_resources.rb +10 -0
  12. data/db/migrate/20170124135846_add_model_type_to_orm_resources.rb +6 -0
  13. data/db/migrate/20170531004548_change_model_type_to_internal_model.rb +6 -0
  14. data/db/schema.rb +65 -0
  15. data/db/seeds.rb +8 -0
  16. data/lib/config/database_connection.rb +15 -0
  17. data/lib/generators/valkyrie/resource_generator.rb +27 -0
  18. data/lib/generators/valkyrie/templates/resource.rb.erb +9 -0
  19. data/lib/generators/valkyrie/templates/resource_spec.rb.erb +13 -0
  20. data/lib/valkyrie.rb +76 -1
  21. data/lib/valkyrie/adapter_container.rb +12 -0
  22. data/lib/valkyrie/change_set.rb +84 -0
  23. data/lib/valkyrie/decorators/decorator_list.rb +15 -0
  24. data/lib/valkyrie/decorators/decorator_with_arguments.rb +14 -0
  25. data/lib/valkyrie/derivative_service.rb +42 -0
  26. data/lib/valkyrie/engine.rb +10 -0
  27. data/lib/valkyrie/file_characterization_service.rb +42 -0
  28. data/lib/valkyrie/id.rb +32 -0
  29. data/lib/valkyrie/indexers/access_controls_indexer.rb +19 -0
  30. data/lib/valkyrie/local_file_service.rb +11 -0
  31. data/lib/valkyrie/metadata_adapter.rb +22 -0
  32. data/lib/valkyrie/persist_derivatives.rb +29 -0
  33. data/lib/valkyrie/persistence.rb +14 -0
  34. data/lib/valkyrie/persistence/buffered_persister.rb +28 -0
  35. data/lib/valkyrie/persistence/composite_persister.rb +29 -0
  36. data/lib/valkyrie/persistence/delete_tracking_buffer.rb +21 -0
  37. data/lib/valkyrie/persistence/fedora.rb +11 -0
  38. data/lib/valkyrie/persistence/fedora/list_node.rb +88 -0
  39. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +45 -0
  40. data/lib/valkyrie/persistence/fedora/ordered_list.rb +146 -0
  41. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +28 -0
  42. data/lib/valkyrie/persistence/fedora/persister.rb +47 -0
  43. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +199 -0
  44. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +338 -0
  45. data/lib/valkyrie/persistence/fedora/persister/resource_factory.rb +21 -0
  46. data/lib/valkyrie/persistence/fedora/query_service.rb +80 -0
  47. data/lib/valkyrie/persistence/memory.rb +8 -0
  48. data/lib/valkyrie/persistence/memory/metadata_adapter.rb +22 -0
  49. data/lib/valkyrie/persistence/memory/persister.rb +58 -0
  50. data/lib/valkyrie/persistence/memory/query_service.rb +86 -0
  51. data/lib/valkyrie/persistence/postgres.rb +6 -0
  52. data/lib/valkyrie/persistence/postgres/metadata_adapter.rb +20 -0
  53. data/lib/valkyrie/persistence/postgres/orm.rb +9 -0
  54. data/lib/valkyrie/persistence/postgres/orm/resource.rb +7 -0
  55. data/lib/valkyrie/persistence/postgres/orm_converter.rb +118 -0
  56. data/lib/valkyrie/persistence/postgres/persister.rb +33 -0
  57. data/lib/valkyrie/persistence/postgres/queries.rb +8 -0
  58. data/lib/valkyrie/persistence/postgres/queries/find_inverse_references_query.rb +31 -0
  59. data/lib/valkyrie/persistence/postgres/queries/find_members_query.rb +33 -0
  60. data/lib/valkyrie/persistence/postgres/queries/find_references_query.rb +33 -0
  61. data/lib/valkyrie/persistence/postgres/query_service.rb +53 -0
  62. data/lib/valkyrie/persistence/postgres/resource_converter.rb +18 -0
  63. data/lib/valkyrie/persistence/postgres/resource_factory.rb +30 -0
  64. data/lib/valkyrie/persistence/solr.rb +6 -0
  65. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +42 -0
  66. data/lib/valkyrie/persistence/solr/model_converter.rb +270 -0
  67. data/lib/valkyrie/persistence/solr/orm_converter.rb +252 -0
  68. data/lib/valkyrie/persistence/solr/persister.rb +32 -0
  69. data/lib/valkyrie/persistence/solr/queries.rb +11 -0
  70. data/lib/valkyrie/persistence/solr/queries/default_paginator.rb +16 -0
  71. data/lib/valkyrie/persistence/solr/queries/find_all_query.rb +33 -0
  72. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +24 -0
  73. data/lib/valkyrie/persistence/solr/queries/find_inverse_references_query.rb +30 -0
  74. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +43 -0
  75. data/lib/valkyrie/persistence/solr/queries/find_references_query.rb +34 -0
  76. data/lib/valkyrie/persistence/solr/query_service.rb +48 -0
  77. data/lib/valkyrie/persistence/solr/repository.rb +36 -0
  78. data/lib/valkyrie/persistence/solr/resource_factory.rb +24 -0
  79. data/lib/valkyrie/rdf_patches.rb +17 -0
  80. data/lib/valkyrie/resource.rb +106 -0
  81. data/lib/valkyrie/resource/access_controls.rb +13 -0
  82. data/lib/valkyrie/specs/shared_specs.rb +10 -0
  83. data/lib/valkyrie/specs/shared_specs/change_set_persister.rb +60 -0
  84. data/lib/valkyrie/specs/shared_specs/derivative_service.rb +30 -0
  85. data/lib/valkyrie/specs/shared_specs/file.rb +12 -0
  86. data/lib/valkyrie/specs/shared_specs/file_characterization_service.rb +33 -0
  87. data/lib/valkyrie/specs/shared_specs/metadata_adapter.rb +10 -0
  88. data/lib/valkyrie/specs/shared_specs/persister.rb +154 -0
  89. data/lib/valkyrie/specs/shared_specs/queries.rb +128 -0
  90. data/lib/valkyrie/specs/shared_specs/resource.rb +71 -0
  91. data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +44 -0
  92. data/lib/valkyrie/storage.rb +8 -0
  93. data/lib/valkyrie/storage/disk.rb +55 -0
  94. data/lib/valkyrie/storage/fedora.rb +71 -0
  95. data/lib/valkyrie/storage/memory.rb +31 -0
  96. data/lib/valkyrie/storage_adapter.rb +100 -0
  97. data/lib/valkyrie/types.rb +34 -0
  98. data/lib/valkyrie/value_mapper.rb +67 -0
  99. data/lib/valkyrie/version.rb +2 -1
  100. data/lib/valkyrie/vocab/pcdm_use.rb +73 -0
  101. data/valkyrie.gemspec +33 -7
  102. metadata +462 -7
  103. data/.travis.yml +0 -5
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr::Queries
3
+ class FindReferencesQuery
4
+ attr_reader :resource, :property, :connection, :resource_factory
5
+ def initialize(resource:, property:, connection:, resource_factory:)
6
+ @resource = resource
7
+ @property = property
8
+ @connection = connection
9
+ @resource_factory = resource_factory
10
+ end
11
+
12
+ def run
13
+ enum_for(:each)
14
+ end
15
+
16
+ def each
17
+ docs = DefaultPaginator.new
18
+ while docs.has_next?
19
+ docs = connection.paginate(docs.next_page, docs.per_page, "select", params: { q: query })["response"]["docs"]
20
+ docs.each do |doc|
21
+ yield resource_factory.to_resource(object: doc)
22
+ end
23
+ end
24
+ end
25
+
26
+ def query
27
+ "{!join from=#{property}_ssim to=id}id:#{id}"
28
+ end
29
+
30
+ def id
31
+ "id-#{resource.id}"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ require 'valkyrie/persistence/solr/queries'
4
+ class QueryService
5
+ attr_reader :connection, :resource_factory
6
+ # @param connection [RSolr::Client]
7
+ # @param resource_factory [Valkyrie::Persistence::Solr::ResourceFactory]
8
+ def initialize(connection:, resource_factory:)
9
+ @connection = connection
10
+ @resource_factory = resource_factory
11
+ end
12
+
13
+ # (see Valkyrie::Persistence::Memory::QueryService#find_by)
14
+ def find_by(id:)
15
+ Valkyrie::Persistence::Solr::Queries::FindByIdQuery.new(id, connection: connection, resource_factory: resource_factory).run
16
+ end
17
+
18
+ # (see Valkyrie::Persistence::Memory::QueryService#find_all)
19
+ def find_all
20
+ Valkyrie::Persistence::Solr::Queries::FindAllQuery.new(connection: connection, resource_factory: resource_factory).run
21
+ end
22
+
23
+ # (see Valkyrie::Persistence::Memory::QueryService#find_all_of_model)
24
+ def find_all_of_model(model:)
25
+ Valkyrie::Persistence::Solr::Queries::FindAllQuery.new(connection: connection, resource_factory: resource_factory, model: model).run
26
+ end
27
+
28
+ # (see Valkyrie::Persistence::Memory::QueryService#find_parents)
29
+ def find_parents(resource:)
30
+ find_inverse_references_by(resource: resource, property: :member_ids)
31
+ end
32
+
33
+ # (see Valkyrie::Persistence::Memory::QueryService#find_members)
34
+ def find_members(resource:)
35
+ Valkyrie::Persistence::Solr::Queries::FindMembersQuery.new(resource: resource, connection: connection, resource_factory: resource_factory).run
36
+ end
37
+
38
+ # (see Valkyrie::Persistence::Memory::QueryService#find_references_by)
39
+ def find_references_by(resource:, property:)
40
+ Valkyrie::Persistence::Solr::Queries::FindReferencesQuery.new(resource: resource, property: property, connection: connection, resource_factory: resource_factory).run
41
+ end
42
+
43
+ # (see Valkyrie::Persistence::Memory::QueryService#find_inverse_references_by)
44
+ def find_inverse_references_by(resource:, property:)
45
+ Valkyrie::Persistence::Solr::Queries::FindInverseReferencesQuery.new(resource: resource, property: property, connection: connection, resource_factory: resource_factory).run
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ class Repository
4
+ attr_reader :resources, :connection, :resource_factory
5
+ def initialize(resources:, connection:, resource_factory:)
6
+ @resources = resources
7
+ @connection = connection
8
+ @resource_factory = resource_factory
9
+ end
10
+
11
+ def persist
12
+ documents = resources.map do |resource|
13
+ generate_id(resource) if resource.id.blank?
14
+ solr_document(resource)
15
+ end
16
+ connection.add documents, params: { softCommit: true }
17
+ documents.map do |document|
18
+ resource_factory.to_resource(object: document.stringify_keys)
19
+ end
20
+ end
21
+
22
+ def delete
23
+ connection.delete_by_id resources.map { |resource| "id-#{resource.id}" }, params: { softCommit: true }
24
+ resources
25
+ end
26
+
27
+ def solr_document(resource)
28
+ resource_factory.from_resource(resource: resource).to_h
29
+ end
30
+
31
+ def generate_id(resource)
32
+ Valkyrie.logger.warn "The Solr adapter is not meant to persist new resources, but is now generating an ID."
33
+ resource.id = SecureRandom.uuid
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ class ResourceFactory
4
+ require 'valkyrie/persistence/solr/orm_converter'
5
+ require 'valkyrie/persistence/solr/model_converter'
6
+ attr_reader :resource_indexer
7
+ def initialize(resource_indexer:)
8
+ @resource_indexer = resource_indexer
9
+ end
10
+
11
+ # @param solr_document [Hash] The solr document in a hash to convert to a
12
+ # resource.
13
+ # @return [Valkyrie::Resource]
14
+ def to_resource(object:)
15
+ ORMConverter.new(object).convert!
16
+ end
17
+
18
+ # @param resource [Valkyrie::Resource] The resource to convert to a solr hash.
19
+ # @return [Hash] The solr document represented as a hash.
20
+ def from_resource(resource:)
21
+ Valkyrie::Persistence::Solr::ModelConverter.new(resource, resource_factory: self).convert!
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ ##
3
+ # These patches are necessary for the postgres adapter to build JSON-LD versions
4
+ # of RDF objects when `to_json` is called on them - that way they're stored in
5
+ # the database as a standard format.
6
+ module RDF
7
+ class Literal
8
+ def as_json(*_args)
9
+ JSON::LD::API.fromRdf([RDF::Statement.new(RDF::URI(""), RDF::URI(""), self)])[0][""][0]
10
+ end
11
+ end
12
+ class URI
13
+ def as_json(*_args)
14
+ JSON::LD::API.fromRdf([RDF::Statement.new(RDF::URI(""), RDF::URI(""), self)])[0][""][0]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie
3
+ ##
4
+ # The base resource class for all Valkyrie metadata objects.
5
+ # @example Define a resource
6
+ # class Book < Valkyrie::Resource
7
+ # attribute :id, Valkyrie::Types::ID.optional
8
+ # attribute :member_ids, Valkyrie::Types::Array
9
+ # attribute :author
10
+ # end
11
+ class Resource < Dry::Struct
12
+ include Draper::Decoratable
13
+ constructor_type :schema
14
+
15
+ # Overridden to provide default attributes.
16
+ # @note The current theory is that we should use this sparingly.
17
+ def self.inherited(subclass)
18
+ ::Dry::Struct.inherited(subclass)
19
+ subclass.constructor_type :schema
20
+ subclass.attribute :internal_resource, Valkyrie::Types::Any.default(subclass.to_s)
21
+ subclass.attribute :created_at, Valkyrie::Types::DateTime.optional
22
+ subclass.attribute :updated_at, Valkyrie::Types::DateTime.optional
23
+ end
24
+
25
+ # @return [Array<Symbol>] Array of fields defined for this class.
26
+ def self.fields
27
+ schema.keys
28
+ end
29
+
30
+ # Define an attribute.
31
+ # @param name [Symbol]
32
+ # @param type [Dry::Types::Type]
33
+ # @note Overridden from {Dry::Struct} to make the default type
34
+ # {Valkyrie::Types::Set}
35
+ def self.attribute(name, type = Valkyrie::Types::Set.optional)
36
+ define_method("#{name}=") do |value|
37
+ instance_variable_set("@#{name}", self.class.schema[name].call(value))
38
+ end
39
+ super
40
+ end
41
+
42
+ # @return [ActiveModel::Name]
43
+ # @note Added for ActiveModel compatibility.
44
+ def self.model_name
45
+ @model_name ||= ::ActiveModel::Name.new(self)
46
+ end
47
+
48
+ delegate :model_name, to: :class
49
+
50
+ def self.human_readable_type
51
+ @_human_readable_type ||= name.demodulize.titleize
52
+ end
53
+
54
+ def self.human_readable_type=(val)
55
+ @_human_readable_type = val
56
+ end
57
+
58
+ # @return [Hash] Hash of attributes
59
+ def attributes
60
+ to_h
61
+ end
62
+
63
+ # @param name [Symbol] Attribute name
64
+ # @return [Boolean]
65
+ def has_attribute?(name)
66
+ respond_to?(name)
67
+ end
68
+
69
+ # @param name [Symbol]
70
+ # @return [Symbol]
71
+ # @note Added for ActiveModel compatibility.
72
+ def column_for_attribute(name)
73
+ name
74
+ end
75
+
76
+ # @return [Boolean]
77
+ def persisted?
78
+ to_param.present?
79
+ end
80
+
81
+ def to_key
82
+ [id]
83
+ end
84
+
85
+ def to_param
86
+ id
87
+ end
88
+
89
+ # @note Added for ActiveModel compatibility
90
+ def to_model
91
+ self
92
+ end
93
+
94
+ # @return [String]
95
+ def to_s
96
+ "#{self.class}: #{id}"
97
+ end
98
+
99
+ ##
100
+ # Provide a human readable name for the resource
101
+ # @return [String]
102
+ def human_readable_type
103
+ self.class.human_readable_type
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie
3
+ class Resource
4
+ module AccessControls
5
+ def self.included(klass)
6
+ klass.attribute :read_groups, Valkyrie::Types::Set
7
+ klass.attribute :read_users, Valkyrie::Types::Set
8
+ klass.attribute :edit_users, Valkyrie::Types::Set
9
+ klass.attribute :edit_groups, Valkyrie::Types::Set
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require 'valkyrie/specs/shared_specs/persister.rb'
3
+ require 'valkyrie/specs/shared_specs/queries.rb'
4
+ require 'valkyrie/specs/shared_specs/metadata_adapter'
5
+ require 'valkyrie/specs/shared_specs/resource.rb'
6
+ require 'valkyrie/specs/shared_specs/storage_adapter.rb'
7
+ require 'valkyrie/specs/shared_specs/derivative_service.rb'
8
+ require 'valkyrie/specs/shared_specs/file_characterization_service.rb'
9
+ require 'valkyrie/specs/shared_specs/change_set_persister.rb'
10
+ require 'valkyrie/specs/shared_specs/file.rb'
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_examples 'a Valkyrie::ChangeSetPersister' do |*_flags|
3
+ before do
4
+ raise 'adapter must be set with `let(:change_set_persister)`' unless defined? change_set_persister
5
+ class CustomResource < Valkyrie::Resource
6
+ include Valkyrie::Resource::AccessControls
7
+ attribute :id, Valkyrie::Types::ID.optional
8
+ attribute :title
9
+ attribute :member_ids
10
+ attribute :nested_resource
11
+ end
12
+ class CustomChangeSet < Valkyrie::ChangeSet
13
+ self.fields = [:title]
14
+ end
15
+ end
16
+ after do
17
+ Object.send(:remove_const, :CustomResource)
18
+ Object.send(:remove_const, :CustomChangeSet)
19
+ end
20
+
21
+ subject { change_set_persister }
22
+ let(:resource_class) { CustomResource }
23
+ let(:resource) { resource_class.new }
24
+ let(:change_set) { CustomChangeSet.new(resource) }
25
+
26
+ it { is_expected.to respond_to(:save).with_keywords(:change_set) }
27
+ it { is_expected.to respond_to(:save_all).with_keywords(:change_sets) }
28
+ it { is_expected.to respond_to(:delete).with_keywords(:change_set) }
29
+ it { is_expected.to respond_to(:metadata_adapter) }
30
+ it { is_expected.to respond_to(:storage_adapter) }
31
+
32
+ describe "#save" do
33
+ it "saves a resource and returns it" do
34
+ output = subject.save(change_set: change_set)
35
+
36
+ expect(output).to be_kind_of CustomResource
37
+ expect(output).to be_persisted
38
+ end
39
+ end
40
+
41
+ describe "#delete" do
42
+ it "deletes a resource" do
43
+ output = subject.save(change_set: change_set)
44
+ subject.delete(change_set: CustomChangeSet.new(output))
45
+
46
+ expect do
47
+ subject.metadata_adapter.query_service.find_by(id: output.id)
48
+ end.to raise_error Valkyrie::Persistence::ObjectNotFoundError
49
+ end
50
+ end
51
+
52
+ describe "#save_all" do
53
+ it "saves multiple change_sets and returns them" do
54
+ change_set2 = CustomChangeSet.new(resource_class.new)
55
+ output = subject.save_all(change_sets: [change_set, change_set2])
56
+
57
+ expect(output.map(&:id).compact.length).to eq 2
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_examples 'a Valkyrie::DerivativeService' do
3
+ before do
4
+ raise 'valid_change_set must be set with `let(:valid_change_set)`' unless
5
+ defined? valid_change_set
6
+ raise 'derivative_service must be set with `let(:derivative_service)`' unless
7
+ defined? derivative_service
8
+ end
9
+
10
+ subject { derivative_service.new(valid_change_set) }
11
+
12
+ it { is_expected.to respond_to(:create_derivatives).with(0).arguments }
13
+
14
+ it { is_expected.to respond_to(:cleanup_derivatives).with(0).arguments }
15
+
16
+ it { is_expected.to respond_to(:change_set) }
17
+
18
+ it { is_expected.to respond_to(:mime_type) }
19
+
20
+ describe "#valid?" do
21
+ context "when given a resource it handles" do
22
+ it { is_expected.to be_valid }
23
+ end
24
+ end
25
+
26
+ it "takes a change_set as an argument" do
27
+ obj = derivative_service.new(valid_change_set)
28
+ expect(obj.change_set.resource).to eq valid_change_set.resource
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_examples 'a Valkyrie::StorageAdapter::File' do
3
+ before do
4
+ raise 'adapter must be set with `let(:file)`' unless defined? file
5
+ end
6
+
7
+ subject { file }
8
+
9
+ it { is_expected.to respond_to(:read) }
10
+ it { is_expected.to respond_to(:rewind) }
11
+ it { is_expected.to respond_to(:id) }
12
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'a Valkyrie::FileCharacterizationService' do
4
+ before do
5
+ raise 'valid_file_node must be set with `let(:valid_file_node)`' unless
6
+ defined? valid_file_node
7
+ raise 'persister must be set with `let(:persister)`' unless
8
+ defined? persister
9
+ raise 'file_characterization_service must be set with `let(:file_characterization_service)`' unless
10
+ defined? file_characterization_service
11
+ end
12
+
13
+ let(:file_node) { valid_file_node }
14
+ subject { file_characterization_service.new(file_node: file_node, persister: persister) }
15
+
16
+ it { is_expected.to respond_to(:characterize).with(0).arguments }
17
+ it 'returns a file node' do
18
+ expect(subject.characterize).to be_a(FileNode)
19
+ end
20
+
21
+ describe '#valid?' do
22
+ context 'when given a file_node it handles' do
23
+ let(:file_node) { valid_file_node }
24
+ it { is_expected.to be_valid }
25
+ end
26
+ end
27
+
28
+ it 'takes a file_node and a persister as arguments' do
29
+ obj = file_characterization_service.new(file_node: file_node, persister: persister)
30
+ expect(obj.file_node).to eq valid_file_node
31
+ expect(obj.persister).to eq persister
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_examples 'a Valkyrie::MetadataAdapter' do |passed_adapter|
3
+ before do
4
+ raise 'adapter must be set with `let(:adapter)`' unless
5
+ defined? adapter
6
+ end
7
+ subject { passed_adapter || adapter }
8
+ it { is_expected.to respond_to(:persister).with(0).arguments }
9
+ it { is_expected.to respond_to(:query_service).with(0).arguments }
10
+ end