active-fedora 9.0.0.rc2 → 9.0.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/active-fedora.gemspec +2 -3
- data/lib/active_fedora/attributes.rb +8 -1
- data/lib/active_fedora/attributes/property_builder.rb +13 -5
- data/lib/active_fedora/fedora.rb +3 -0
- data/lib/active_fedora/file.rb +1 -1
- data/lib/active_fedora/fixity_service.rb +2 -5
- data/lib/active_fedora/indexing.rb +10 -8
- data/lib/active_fedora/nested_attributes.rb +12 -0
- data/lib/active_fedora/rdf/fcrepo4.rb +2 -0
- data/lib/active_fedora/version.rb +1 -1
- data/lib/tasks/active_fedora_dev.rake +0 -2
- data/spec/integration/datastream_rdf_nested_attributes_spec.rb +185 -0
- data/spec/integration/indexing_spec.rb +20 -7
- data/spec/integration/rdf_nested_attributes_spec.rb +38 -168
- data/spec/unit/active_fedora_spec.rb +18 -0
- data/spec/unit/base_spec.rb +2 -12
- data/spec/unit/property_predicate_spec.rb +40 -0
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a49c5a80114d75ddec80fc7ef09aa0e41f45331e
|
|
4
|
+
data.tar.gz: 3c7fd10c052aa997fd6d021140aeece4e9da5515
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a4843d2350b989d0785ec900fb722196339a989cf279ea619f7b470cae56d1210e922259d74d3146d60a72ba4e5df390164d0f9716cc43d6fa11b0b93db6cf5
|
|
7
|
+
data.tar.gz: 0bc39376a1dc54ea35bbf081b40106d88541c1e0282585f27fa5f8aaeb8d9960e090cf8d426d4bf2cb5b8864c10a8730a4b753fe762fa0bab8d7fff8a7e2fdfd
|
data/active-fedora.gemspec
CHANGED
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
s.add_dependency 'om', '~> 3.1'
|
|
19
19
|
s.add_dependency 'nom-xml', '>= 0.5.1'
|
|
20
20
|
s.add_dependency "activesupport", '>= 4.1.0'
|
|
21
|
-
s.add_dependency "active-triples", '~> 0.
|
|
21
|
+
s.add_dependency "active-triples", '~> 0.6.0'
|
|
22
22
|
s.add_dependency "rdf-rdfxml", '~> 1.1.0'
|
|
23
23
|
s.add_dependency "linkeddata"
|
|
24
24
|
s.add_dependency "deprecation"
|
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|
|
28
28
|
s.add_development_dependency "rdoc"
|
|
29
29
|
s.add_development_dependency "yard"
|
|
30
30
|
s.add_development_dependency "rake"
|
|
31
|
-
s.add_development_dependency "jettywrapper", ">=
|
|
31
|
+
s.add_development_dependency "jettywrapper", ">= 2.0.0"
|
|
32
32
|
s.add_development_dependency "rspec", "~> 3.0"
|
|
33
33
|
s.add_development_dependency "equivalent-xml"
|
|
34
34
|
s.add_development_dependency "simplecov", '~> 0.7.1'
|
|
@@ -43,4 +43,3 @@ Gem::Specification.new do |s|
|
|
|
43
43
|
s.require_paths = ["lib"]
|
|
44
44
|
|
|
45
45
|
end
|
|
46
|
-
|
|
@@ -171,16 +171,23 @@ module ActiveFedora
|
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
def property name, properties={}, &block
|
|
174
|
+
warn_duplicate_predicates name, properties
|
|
174
175
|
properties = { multiple: true }.merge(properties)
|
|
175
176
|
find_or_create_defined_attribute(name, nil, properties)
|
|
176
177
|
raise ArgumentError, "#{name} is a keyword and not an acceptable property name." if protected_property_name? name
|
|
177
178
|
reflection = ActiveFedora::Attributes::PropertyBuilder.build(self, name, properties, &block)
|
|
178
|
-
# reflection = ActiveTriple::PropertyBuilder.build(self, name, properties, &block)
|
|
179
179
|
ActiveTriples::Reflection.add_reflection self, name, reflection
|
|
180
180
|
end
|
|
181
181
|
|
|
182
182
|
private
|
|
183
183
|
|
|
184
|
+
def warn_duplicate_predicates new_name, new_properties
|
|
185
|
+
new_predicate = new_properties[:predicate]
|
|
186
|
+
self.properties.select{|k, existing| existing.predicate == new_predicate}.each do |key, value|
|
|
187
|
+
ActiveFedora::Base.logger.warn "Same predicate (#{new_predicate}) used for properties #{key} and #{new_name}"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
184
191
|
def find_or_create_defined_attribute(field, dsid, args)
|
|
185
192
|
delegated_attributes[field] ||= DelegatedAttribute.new(field, dsid, datastream_class_for_name(dsid), args)
|
|
186
193
|
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
module ActiveFedora::Attributes
|
|
2
2
|
class PropertyBuilder < ActiveTriples::PropertyBuilder #:nodoc:
|
|
3
3
|
|
|
4
|
-
def self.define_accessors(model, reflection)
|
|
5
|
-
mixin = model.generated_property_methods
|
|
6
|
-
name = reflection.term
|
|
4
|
+
def self.define_accessors(model, reflection, options={})
|
|
7
5
|
if reflection.multiple?
|
|
8
|
-
|
|
9
|
-
define_writers(mixin, name)
|
|
6
|
+
super
|
|
10
7
|
else
|
|
8
|
+
mixin = model.generated_property_methods
|
|
9
|
+
name = reflection.term
|
|
11
10
|
define_singular_readers(mixin, name)
|
|
11
|
+
define_singular_id_reader(mixin, name) unless options[:cast] == false
|
|
12
12
|
define_singular_writers(mixin, name)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -34,6 +34,14 @@ module ActiveFedora::Attributes
|
|
|
34
34
|
CODE
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
def self.define_singular_id_reader(mixin, name)
|
|
38
|
+
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
|
39
|
+
def #{name}_id(*args)
|
|
40
|
+
get_values(:#{name}, :cast => false)
|
|
41
|
+
end
|
|
42
|
+
CODE
|
|
43
|
+
end
|
|
44
|
+
|
|
37
45
|
def self.define_singular_writers(mixin, name)
|
|
38
46
|
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
|
39
47
|
def #{name}=(value)
|
data/lib/active_fedora/fedora.rb
CHANGED
|
@@ -26,6 +26,9 @@ module ActiveFedora
|
|
|
26
26
|
ActiveFedora::Base.logger.info "Attempted to init base path `#{root_resource_path}`, but it already exists" if ActiveFedora::Base.logger
|
|
27
27
|
return false
|
|
28
28
|
rescue Ldp::NotFound
|
|
29
|
+
if !host.downcase.end_with?("/rest")
|
|
30
|
+
ActiveFedora::Base.logger.warn "Fedora URL (#{host}) does not end with /rest. This could be a problem. Check your fedora.yml config"
|
|
31
|
+
end
|
|
29
32
|
connection.put(root_resource_path, BLANK).success?
|
|
30
33
|
end
|
|
31
34
|
|
data/lib/active_fedora/file.rb
CHANGED
|
@@ -118,7 +118,7 @@ module ActiveFedora
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def digest
|
|
121
|
-
response = metadata.ldp_source.graph.query(:
|
|
121
|
+
response = metadata.ldp_source.graph.query(predicate: ActiveFedora::RDF::Fcrepo4.digest)
|
|
122
122
|
response.map(&:object)
|
|
123
123
|
end
|
|
124
124
|
|
|
@@ -18,7 +18,7 @@ module ActiveFedora
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def status
|
|
21
|
-
fixity_graph.query(predicate:
|
|
21
|
+
fixity_graph.query(predicate: ActiveFedora::RDF::Fcrepo4.status).map(&:object).first.to_s
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
private
|
|
@@ -32,10 +32,7 @@ module ActiveFedora
|
|
|
32
32
|
::RDF::Graph.new << ::RDF::Reader.for(:ttl).new(response.body)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
::RDF::URI("http://fedora.info/definitions/v4/repository#status")
|
|
37
|
-
end
|
|
38
|
-
|
|
35
|
+
# See https://jira.duraspace.org/browse/FCREPO-1247
|
|
39
36
|
def encoded_url uri
|
|
40
37
|
if uri.match("fcr:versions")
|
|
41
38
|
uri.gsub(/fcr:versions/,"fcr%3aversions")
|
|
@@ -56,9 +56,11 @@ module ActiveFedora
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def reindex_everything
|
|
59
|
-
|
|
59
|
+
descendants = descendant_uris(ActiveFedora::Base.id_to_uri(''))
|
|
60
|
+
descendants.shift # Discard the root uri
|
|
61
|
+
descendants.each do |uri|
|
|
60
62
|
logger.debug "Re-index everything ... #{uri}"
|
|
61
|
-
ActiveFedora::Base.find(
|
|
63
|
+
ActiveFedora::Base.find(ActiveFedora::Base.uri_to_id(uri)).update_index
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
|
|
@@ -77,17 +79,17 @@ module ActiveFedora
|
|
|
77
79
|
SolrInstanceLoader.new(self, id, solr_doc).object
|
|
78
80
|
end
|
|
79
81
|
|
|
80
|
-
def
|
|
82
|
+
def descendant_uris(uri)
|
|
81
83
|
resource = Ldp::Resource::RdfSource.new(ActiveFedora.fedora.connection, uri)
|
|
82
84
|
# GET could be slow if it's a big resource, we're using HEAD to avoid this problem,
|
|
83
85
|
# but this causes more requests to Fedora.
|
|
84
86
|
return [] unless Ldp::Response.rdf_source?(resource.head)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
immediate_descendant_uris = resource.graph.query(predicate: ::RDF::LDP.contains).map { |descendant| descendant.object.to_s }
|
|
88
|
+
all_descendants_uris = [uri]
|
|
89
|
+
immediate_descendant_uris.each do |descendant_uri|
|
|
90
|
+
all_descendants_uris += descendant_uris(descendant_uri)
|
|
89
91
|
end
|
|
90
|
-
|
|
92
|
+
all_descendants_uris
|
|
91
93
|
end
|
|
92
94
|
|
|
93
95
|
end
|
|
@@ -83,6 +83,18 @@ module ActiveFedora
|
|
|
83
83
|
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
|
|
84
84
|
end
|
|
85
85
|
eoruby
|
|
86
|
+
elsif reflection = reflect_on_property(association_name)
|
|
87
|
+
resource_class.accepts_nested_attributes_for(association_name, options)
|
|
88
|
+
|
|
89
|
+
# Delegate the setter to the resource.
|
|
90
|
+
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
|
91
|
+
remove_possible_method(:#{association_name}_attributes=)
|
|
92
|
+
|
|
93
|
+
def #{association_name}_attributes=(attributes)
|
|
94
|
+
attribute_will_change!(:#{association_name})
|
|
95
|
+
resource.#{association_name}_attributes=(attributes)
|
|
96
|
+
end
|
|
97
|
+
eoruby
|
|
86
98
|
else
|
|
87
99
|
raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
|
|
88
100
|
end
|
|
@@ -2,8 +2,10 @@ require 'rdf'
|
|
|
2
2
|
module ActiveFedora::RDF
|
|
3
3
|
class Fcrepo4 < RDF::StrictVocabulary("http://fedora.info/definitions/v4/repository#")
|
|
4
4
|
property :created
|
|
5
|
+
property :digest
|
|
5
6
|
property :hasVersion
|
|
6
7
|
property :hasVersionLabel
|
|
7
8
|
property :lastModified
|
|
9
|
+
property :status
|
|
8
10
|
end
|
|
9
11
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
APP_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../")
|
|
2
2
|
|
|
3
3
|
require 'jettywrapper'
|
|
4
|
-
Jettywrapper.hydra_jetty_version = "v8.1.1"
|
|
5
4
|
|
|
6
5
|
namespace :active_fedora do
|
|
7
6
|
# Use yard to build docs
|
|
@@ -40,7 +39,6 @@ namespace :active_fedora do
|
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
|
|
44
42
|
desc "CI build"
|
|
45
43
|
task :ci do
|
|
46
44
|
ENV['environment'] = "test"
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Nesting attribute behavior of RDFDatastream" do
|
|
4
|
+
describe ".attributes=" do
|
|
5
|
+
|
|
6
|
+
context "complex properties in a datastream" do
|
|
7
|
+
before do
|
|
8
|
+
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
|
9
|
+
# TODO this test is order dependent. It expects to use the object created in the previous test
|
|
10
|
+
# componentList and Types of components
|
|
11
|
+
property :componentList
|
|
12
|
+
property :Topic
|
|
13
|
+
property :Temporal
|
|
14
|
+
property :PersonalName
|
|
15
|
+
property :CorporateName
|
|
16
|
+
property :ComplexSubject
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# elementList and elementList values
|
|
20
|
+
property :elementList
|
|
21
|
+
property :elementValue
|
|
22
|
+
property :TopicElement
|
|
23
|
+
property :TemporalElement
|
|
24
|
+
property :NameElement
|
|
25
|
+
property :FullNameElement
|
|
26
|
+
property :DateNameElement
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class ComplexRDFDatastream < ActiveFedora::NtriplesRDFDatastream
|
|
30
|
+
property :topic, predicate: DummyMADS.Topic, class_name: "Topic"
|
|
31
|
+
property :personalName, predicate: DummyMADS.PersonalName, class_name: "PersonalName"
|
|
32
|
+
property :title, predicate: ::RDF::DC.title
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
accepts_nested_attributes_for :topic, :personalName
|
|
36
|
+
|
|
37
|
+
class Topic < ActiveTriples::Resource
|
|
38
|
+
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
|
39
|
+
accepts_nested_attributes_for :elementList
|
|
40
|
+
end
|
|
41
|
+
class PersonalName < ActiveTriples::Resource
|
|
42
|
+
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
|
43
|
+
property :extraProperty, predicate: DummyMADS.elementValue, class_name: "ComplexRDFDatastream::Topic"
|
|
44
|
+
accepts_nested_attributes_for :elementList, :extraProperty
|
|
45
|
+
end
|
|
46
|
+
class ElementList < ActiveTriples::List
|
|
47
|
+
configure type: DummyMADS.elementList
|
|
48
|
+
property :topicElement, predicate: DummyMADS.TopicElement, class_name: "ComplexRDFDatastream::MadsTopicElement"
|
|
49
|
+
property :temporalElement, predicate: DummyMADS.TemporalElement
|
|
50
|
+
property :fullNameElement, predicate: DummyMADS.FullNameElement
|
|
51
|
+
property :dateNameElement, predicate: DummyMADS.DateNameElement
|
|
52
|
+
property :nameElement, predicate: DummyMADS.NameElement
|
|
53
|
+
property :elementValue, predicate: DummyMADS.elementValue
|
|
54
|
+
accepts_nested_attributes_for :topicElement
|
|
55
|
+
end
|
|
56
|
+
class MadsTopicElement < ActiveTriples::Resource
|
|
57
|
+
configure :type => DummyMADS.TopicElement
|
|
58
|
+
property :elementValue, predicate: DummyMADS.elementValue
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
after do
|
|
63
|
+
Object.send(:remove_const, :ComplexRDFDatastream)
|
|
64
|
+
Object.send(:remove_const, :DummyMADS)
|
|
65
|
+
end
|
|
66
|
+
subject { ComplexRDFDatastream.new }
|
|
67
|
+
let(:params) do
|
|
68
|
+
{ myResource:
|
|
69
|
+
{
|
|
70
|
+
topic_attributes: {
|
|
71
|
+
'0' =>
|
|
72
|
+
{
|
|
73
|
+
elementList_attributes: [{
|
|
74
|
+
topicElement_attributes: [{
|
|
75
|
+
id: 'http://library.ucsd.edu/ark:/20775/bb3333333x',
|
|
76
|
+
elementValue:"Cosmology"
|
|
77
|
+
}]
|
|
78
|
+
}]
|
|
79
|
+
},
|
|
80
|
+
'1' =>
|
|
81
|
+
{
|
|
82
|
+
elementList_attributes: [{
|
|
83
|
+
topicElement_attributes: {'0' => {elementValue:"Quantum Behavior"}}
|
|
84
|
+
}]
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
personalName_attributes: [
|
|
88
|
+
{
|
|
89
|
+
id: 'http://library.ucsd.edu/ark:20775/jefferson',
|
|
90
|
+
elementList_attributes: [{
|
|
91
|
+
fullNameElement: "Jefferson, Thomas",
|
|
92
|
+
dateNameElement: "1743-1826"
|
|
93
|
+
}]
|
|
94
|
+
}
|
|
95
|
+
#, "Hemings, Sally"
|
|
96
|
+
],
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe "on lists" do
|
|
102
|
+
subject { ComplexRDFDatastream::PersonalName.new(RDF::Graph.new) }
|
|
103
|
+
it "should accept a hash" do
|
|
104
|
+
subject.elementList_attributes = [{ topicElement_attributes: {'0' => { elementValue:"Quantum Behavior" }, '1' => { elementValue:"Wave Function" }}}]
|
|
105
|
+
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
|
106
|
+
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
it "should accept an array" do
|
|
110
|
+
subject.elementList_attributes = [{ topicElement_attributes: [{ elementValue:"Quantum Behavior" }, { elementValue:"Wave Function" }]}]
|
|
111
|
+
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
|
112
|
+
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "from nested objects" do
|
|
117
|
+
before do
|
|
118
|
+
# Replace the graph's contents with the Hash
|
|
119
|
+
subject.attributes = params[:myResource]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'should have attributes' do
|
|
123
|
+
expect(subject.topic[0].elementList.first[0].elementValue).to eq ["Cosmology"]
|
|
124
|
+
expect(subject.topic[1].elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
|
125
|
+
expect(subject.personalName.first.elementList.first.fullNameElement).to eq ["Jefferson, Thomas"]
|
|
126
|
+
expect(subject.personalName.first.elementList.first.dateNameElement).to eq ["1743-1826"]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'should build nodes with ids' do
|
|
130
|
+
expect(subject.topic[0].elementList.first[0].rdf_subject).to eq 'http://library.ucsd.edu/ark:/20775/bb3333333x'
|
|
131
|
+
expect(subject.personalName.first.rdf_subject).to eq 'http://library.ucsd.edu/ark:20775/jefferson'
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'should fail when writing to a non-predicate' do
|
|
135
|
+
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ fake_predicate:"Cosmology" }] }]}}}
|
|
136
|
+
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'should fail when writing to a non-predicate with a setter method' do
|
|
140
|
+
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ name:"Cosmology" }] }]}}}
|
|
141
|
+
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
describe "with an existing object" do
|
|
147
|
+
before(:each) do
|
|
148
|
+
class SpecDatastream < ActiveFedora::NtriplesRDFDatastream
|
|
149
|
+
property :parts, predicate: ::RDF::DC.hasPart, :class_name=>'Component'
|
|
150
|
+
accepts_nested_attributes_for :parts, allow_destroy: true
|
|
151
|
+
|
|
152
|
+
class Component < ActiveTriples::Resource
|
|
153
|
+
property :label, predicate: ::RDF::DC.title
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
after(:each) do
|
|
160
|
+
Object.send(:remove_const, :SpecDatastream)
|
|
161
|
+
end
|
|
162
|
+
subject { SpecDatastream.new }
|
|
163
|
+
before do
|
|
164
|
+
subject.attributes = { parts_attributes: [
|
|
165
|
+
{label: 'Alternator'},
|
|
166
|
+
{label: 'Distributor'},
|
|
167
|
+
{label: 'Transmission'},
|
|
168
|
+
{label: 'Fuel Filter'}]}
|
|
169
|
+
end
|
|
170
|
+
let (:replace_object_id) { subject.parts[1].rdf_subject.to_s }
|
|
171
|
+
let (:remove_object_id) { subject.parts[3].rdf_subject.to_s }
|
|
172
|
+
|
|
173
|
+
it "should update nested objects" do
|
|
174
|
+
subject.parts_attributes= [{id: replace_object_id, label: "Universal Joint"}, {label:"Oil Pump"}, {id: remove_object_id, _destroy: '1', label: "bar1 uno"}]
|
|
175
|
+
|
|
176
|
+
expect(subject.parts.map{|p| p.label.first}).to eq ['Alternator', 'Universal Joint', 'Transmission', 'Oil Pump']
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
it "create a new object when the id is provided" do
|
|
180
|
+
subject.parts_attributes= [{id: 'http://example.com/part#1', label: "Universal Joint"}]
|
|
181
|
+
expect(subject.parts.last.rdf_subject).to eq RDF::URI('http://example.com/part#1')
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
|
2
2
|
@@last_id = 0
|
|
3
3
|
|
|
4
4
|
describe ActiveFedora::Base do
|
|
5
|
-
describe "
|
|
5
|
+
describe "descendant_uris" do
|
|
6
6
|
|
|
7
7
|
before :each do
|
|
8
8
|
ids.each do |id|
|
|
@@ -14,21 +14,21 @@ describe ActiveFedora::Base do
|
|
|
14
14
|
ActiveFedora::Base.id_to_uri(ids.first)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
context 'when there there are no
|
|
17
|
+
context 'when there there are no descendants' do
|
|
18
18
|
|
|
19
19
|
let(:ids) { ['foo'] }
|
|
20
20
|
|
|
21
21
|
it 'returns an array containing only the URI passed to it' do
|
|
22
|
-
expect(ActiveFedora::Base.
|
|
22
|
+
expect(ActiveFedora::Base.descendant_uris(root_uri(ids))).to eq ids.map {|id| ActiveFedora::Base.id_to_uri(id) }
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
context 'when there are > 1
|
|
26
|
+
context 'when there are > 1 descendants' do
|
|
27
27
|
|
|
28
28
|
let(:ids) { ['foo', 'foo/bar', 'foo/bar/chu'] }
|
|
29
29
|
|
|
30
|
-
it 'returns an array containing the URI passed to it, as well as all
|
|
31
|
-
expect(ActiveFedora::Base.
|
|
30
|
+
it 'returns an array containing the URI passed to it, as well as all descendant URIs' do
|
|
31
|
+
expect(ActiveFedora::Base.descendant_uris(root_uri(ids))).to eq ids.map {|id| ActiveFedora::Base.id_to_uri(id) }
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -42,7 +42,20 @@ describe ActiveFedora::Base do
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it "should not put the datastream in the decendants list" do
|
|
45
|
-
expect(ActiveFedora::Base.
|
|
45
|
+
expect(ActiveFedora::Base.descendant_uris(root_uri(ids))).not_to include datastream.uri
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe "reindex_everything" do
|
|
50
|
+
let(:ids) { ['foo', 'bar'] }
|
|
51
|
+
let(:solr) { ActiveFedora::SolrService.instance.conn }
|
|
52
|
+
before do
|
|
53
|
+
solr.delete_by_query('*:*', params: {'softCommit' => true})
|
|
54
|
+
end
|
|
55
|
+
it "should call update_index on every object represented in the sitemap" do
|
|
56
|
+
expect {
|
|
57
|
+
ActiveFedora::Base.reindex_everything
|
|
58
|
+
}.to change { ActiveFedora::SolrService.query('id:foo').size }.from(0).to(1)
|
|
46
59
|
end
|
|
47
60
|
end
|
|
48
61
|
end
|
|
@@ -1,185 +1,55 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe "Nesting attribute behavior of
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
|
9
|
-
# TODO this test is order dependent. It expects to use the object created in the previous test
|
|
10
|
-
# componentList and Types of components
|
|
11
|
-
property :componentList
|
|
12
|
-
property :Topic
|
|
13
|
-
property :Temporal
|
|
14
|
-
property :PersonalName
|
|
15
|
-
property :CorporateName
|
|
16
|
-
property :ComplexSubject
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# elementList and elementList values
|
|
20
|
-
property :elementList
|
|
21
|
-
property :elementValue
|
|
22
|
-
property :TopicElement
|
|
23
|
-
property :TemporalElement
|
|
24
|
-
property :NameElement
|
|
25
|
-
property :FullNameElement
|
|
26
|
-
property :DateNameElement
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
class ComplexRDFDatastream < ActiveFedora::NtriplesRDFDatastream
|
|
30
|
-
property :topic, predicate: DummyMADS.Topic, class_name: "Topic"
|
|
31
|
-
property :personalName, predicate: DummyMADS.PersonalName, class_name: "PersonalName"
|
|
32
|
-
property :title, predicate: ::RDF::DC.title
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
accepts_nested_attributes_for :topic, :personalName
|
|
36
|
-
|
|
37
|
-
class Topic < ActiveTriples::Resource
|
|
38
|
-
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
|
39
|
-
accepts_nested_attributes_for :elementList
|
|
40
|
-
end
|
|
41
|
-
class PersonalName < ActiveTriples::Resource
|
|
42
|
-
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
|
43
|
-
property :extraProperty, predicate: DummyMADS.elementValue, class_name: "ComplexRDFDatastream::Topic"
|
|
44
|
-
accepts_nested_attributes_for :elementList, :extraProperty
|
|
45
|
-
end
|
|
46
|
-
class ElementList < ActiveTriples::List
|
|
47
|
-
configure type: DummyMADS.elementList
|
|
48
|
-
property :topicElement, predicate: DummyMADS.TopicElement, class_name: "ComplexRDFDatastream::MadsTopicElement"
|
|
49
|
-
property :temporalElement, predicate: DummyMADS.TemporalElement
|
|
50
|
-
property :fullNameElement, predicate: DummyMADS.FullNameElement
|
|
51
|
-
property :dateNameElement, predicate: DummyMADS.DateNameElement
|
|
52
|
-
property :nameElement, predicate: DummyMADS.NameElement
|
|
53
|
-
property :elementValue, predicate: DummyMADS.elementValue
|
|
54
|
-
accepts_nested_attributes_for :topicElement
|
|
55
|
-
end
|
|
56
|
-
class MadsTopicElement < ActiveTriples::Resource
|
|
57
|
-
configure :type => DummyMADS.TopicElement
|
|
58
|
-
property :elementValue, predicate: DummyMADS.elementValue
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
after do
|
|
63
|
-
Object.send(:remove_const, :ComplexRDFDatastream)
|
|
64
|
-
Object.send(:remove_const, :DummyMADS)
|
|
65
|
-
end
|
|
66
|
-
subject { ComplexRDFDatastream.new }
|
|
67
|
-
let(:params) do
|
|
68
|
-
{ myResource:
|
|
69
|
-
{
|
|
70
|
-
topic_attributes: {
|
|
71
|
-
'0' =>
|
|
72
|
-
{
|
|
73
|
-
elementList_attributes: [{
|
|
74
|
-
topicElement_attributes: [{
|
|
75
|
-
id: 'http://library.ucsd.edu/ark:/20775/bb3333333x',
|
|
76
|
-
elementValue:"Cosmology"
|
|
77
|
-
}]
|
|
78
|
-
}]
|
|
79
|
-
},
|
|
80
|
-
'1' =>
|
|
81
|
-
{
|
|
82
|
-
elementList_attributes: [{
|
|
83
|
-
topicElement_attributes: {'0' => {elementValue:"Quantum Behavior"}}
|
|
84
|
-
}]
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
personalName_attributes: [
|
|
88
|
-
{
|
|
89
|
-
id: 'http://library.ucsd.edu/ark:20775/jefferson',
|
|
90
|
-
elementList_attributes: [{
|
|
91
|
-
fullNameElement: "Jefferson, Thomas",
|
|
92
|
-
dateNameElement: "1743-1826"
|
|
93
|
-
}]
|
|
94
|
-
}
|
|
95
|
-
#, "Hemings, Sally"
|
|
96
|
-
],
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
end
|
|
3
|
+
describe "Nesting attribute behavior of RDF resources" do
|
|
4
|
+
before do
|
|
5
|
+
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
|
6
|
+
property :Topic
|
|
7
|
+
end
|
|
100
8
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
it "should accept a hash" do
|
|
104
|
-
subject.elementList_attributes = [{ topicElement_attributes: {'0' => { elementValue:"Quantum Behavior" }, '1' => { elementValue:"Wave Function" }}}]
|
|
105
|
-
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
|
106
|
-
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
|
9
|
+
class ComplexResource < ActiveFedora::Base
|
|
10
|
+
property :topic, predicate: DummyMADS.Topic, class_name: "Topic"
|
|
107
11
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
subject.elementList_attributes = [{ topicElement_attributes: [{ elementValue:"Quantum Behavior" }, { elementValue:"Wave Function" }]}]
|
|
111
|
-
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
|
112
|
-
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
|
113
|
-
end
|
|
12
|
+
class Topic < ActiveTriples::Resource
|
|
13
|
+
property :subject, predicate: ::RDF::DC.subject
|
|
114
14
|
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
115
17
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
it 'should have attributes' do
|
|
123
|
-
expect(subject.topic[0].elementList.first[0].elementValue).to eq ["Cosmology"]
|
|
124
|
-
expect(subject.topic[1].elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
|
125
|
-
expect(subject.personalName.first.elementList.first.fullNameElement).to eq ["Jefferson, Thomas"]
|
|
126
|
-
expect(subject.personalName.first.elementList.first.dateNameElement).to eq ["1743-1826"]
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
it 'should build nodes with ids' do
|
|
130
|
-
expect(subject.topic[0].elementList.first[0].rdf_subject).to eq 'http://library.ucsd.edu/ark:/20775/bb3333333x'
|
|
131
|
-
expect(subject.personalName.first.rdf_subject).to eq 'http://library.ucsd.edu/ark:20775/jefferson'
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
it 'should fail when writing to a non-predicate' do
|
|
135
|
-
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ fake_predicate:"Cosmology" }] }]}}}
|
|
136
|
-
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
|
137
|
-
end
|
|
18
|
+
after do
|
|
19
|
+
Object.send(:remove_const, :ComplexResource)
|
|
20
|
+
Object.send(:remove_const, :DummyMADS)
|
|
21
|
+
end
|
|
138
22
|
|
|
139
|
-
|
|
140
|
-
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ name:"Cosmology" }] }]}}}
|
|
141
|
-
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
end
|
|
23
|
+
subject { ComplexResource.new }
|
|
145
24
|
|
|
146
|
-
|
|
147
|
-
before(:each) do
|
|
148
|
-
class SpecDatastream < ActiveFedora::NtriplesRDFDatastream
|
|
149
|
-
property :parts, predicate: ::RDF::DC.hasPart, :class_name=>'Component'
|
|
150
|
-
accepts_nested_attributes_for :parts, allow_destroy: true
|
|
25
|
+
let(:params) { [{ subject: 'Foo' }, { subject: 'Bar' }] }
|
|
151
26
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
27
|
+
before do
|
|
28
|
+
ComplexResource.accepts_nested_attributes_for *args
|
|
29
|
+
subject.topic_attributes = params
|
|
30
|
+
end
|
|
156
31
|
|
|
157
|
-
|
|
32
|
+
context "when no options are set" do
|
|
33
|
+
let(:args) { [:topic] }
|
|
158
34
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
before do
|
|
164
|
-
subject.attributes = { parts_attributes: [
|
|
165
|
-
{label: 'Alternator'},
|
|
166
|
-
{label: 'Distributor'},
|
|
167
|
-
{label: 'Transmission'},
|
|
168
|
-
{label: 'Fuel Filter'}]}
|
|
169
|
-
end
|
|
170
|
-
let (:replace_object_id) { subject.parts[1].rdf_subject.to_s }
|
|
171
|
-
let (:remove_object_id) { subject.parts[3].rdf_subject.to_s }
|
|
35
|
+
it "should set the attributes" do
|
|
36
|
+
expect(subject.topic.size).to eq 2
|
|
37
|
+
expect(subject.topic.map(&:subject)).to eq [['Foo'], ['Bar']]
|
|
38
|
+
end
|
|
172
39
|
|
|
173
|
-
|
|
174
|
-
|
|
40
|
+
it "should mark the attributes as changed" do
|
|
41
|
+
expect(subject.changed_attributes).to eq('topic' => [])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
175
44
|
|
|
176
|
-
|
|
45
|
+
context "when reject_if is set" do
|
|
46
|
+
let(:args) { [:topic, reject_if: reject_proc] }
|
|
47
|
+
let(:reject_proc) { lambda { |attributes| attributes[:subject] == 'Bar' } }
|
|
48
|
+
let(:params) { [{ subject: 'Foo' }, { subject: 'Bar' }] }
|
|
177
49
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
subject.parts_attributes= [{id: 'http://example.com/part#1', label: "Universal Joint"}]
|
|
181
|
-
expect(subject.parts.last.rdf_subject).to eq RDF::URI('http://example.com/part#1')
|
|
182
|
-
end
|
|
50
|
+
it "should not add terms for which the proc is true" do
|
|
51
|
+
expect(subject.topic.map(&:subject)).to eq [['Foo']]
|
|
183
52
|
end
|
|
184
53
|
end
|
|
54
|
+
|
|
185
55
|
end
|
|
@@ -15,6 +15,24 @@ describe ActiveFedora do
|
|
|
15
15
|
restore_spec_configuration
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
describe "validate Fedora URL" do
|
|
19
|
+
|
|
20
|
+
let(:good_url) { ActiveFedora.fedora_config.credentials[:url] }
|
|
21
|
+
let(:bad_url) { good_url.gsub('/rest', '/') }
|
|
22
|
+
|
|
23
|
+
it "should connect OK" do
|
|
24
|
+
expect(ActiveFedora::Base.logger).to_not receive(:warn)
|
|
25
|
+
ActiveFedora::Fedora.new(url: good_url, base_path: '/test')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should not connect and warn" do
|
|
29
|
+
expect(ActiveFedora::Base.logger).to receive(:warn)
|
|
30
|
+
expect {
|
|
31
|
+
ActiveFedora::Fedora.new(url: bad_url, base_path: '/test')
|
|
32
|
+
}.to raise_error Ldp::HttpError
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
18
36
|
describe "initialization methods" do
|
|
19
37
|
describe "environment" do
|
|
20
38
|
it "should use config_options[:environment] if set" do
|
data/spec/unit/base_spec.rb
CHANGED
|
@@ -10,18 +10,8 @@ describe ActiveFedora::Base do
|
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
describe "reindex_everything" do
|
|
14
|
-
it "should call update_index on every object represented in the sitemap" do
|
|
15
|
-
allow(ActiveFedora::Base).to receive(:descendent_uris) { ['http://localhost/test/XXX', 'http://localhost/test/YYY', 'http://localhost/test/ZZZ'] }
|
|
16
|
-
mock_update = double(:mock_obj)
|
|
17
|
-
expect(mock_update).to receive(:update_index).exactly(3).times
|
|
18
|
-
expect(ActiveFedora::Base).to receive(:find).with(instance_of ActiveFedora::LdpResource ).and_return(mock_update).exactly(3).times
|
|
19
|
-
ActiveFedora::Base.reindex_everything
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
13
|
describe "With a test class" do
|
|
24
|
-
before
|
|
14
|
+
before do
|
|
25
15
|
class FooHistory < ActiveFedora::Base
|
|
26
16
|
has_metadata 'someData', type: ActiveFedora::SimpleDatastream, autocreate: true do |m|
|
|
27
17
|
m.field "fubar", :string
|
|
@@ -46,7 +36,7 @@ describe ActiveFedora::Base do
|
|
|
46
36
|
end
|
|
47
37
|
end
|
|
48
38
|
|
|
49
|
-
after
|
|
39
|
+
after do
|
|
50
40
|
Object.send(:remove_const, :FooHistory)
|
|
51
41
|
Object.send(:remove_const, :FooAdaptation)
|
|
52
42
|
Object.send(:remove_const, :FooInherited)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Properties with the same predicate' do
|
|
4
|
+
|
|
5
|
+
let(:warningMsg) {"Same predicate (http://purl.org/dc/terms/title) used for properties title1 and title2"}
|
|
6
|
+
|
|
7
|
+
it "should warn" do
|
|
8
|
+
|
|
9
|
+
# Note that the expect test must be before the class is parsed.
|
|
10
|
+
expect(ActiveFedora::Base.logger).to receive(:warn).with(warningMsg)
|
|
11
|
+
|
|
12
|
+
module TestModel1
|
|
13
|
+
class Book < ActiveFedora::Base
|
|
14
|
+
property :title1, predicate: ::RDF::DC.title
|
|
15
|
+
property :title2, predicate: ::RDF::DC.title
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
describe 'Properties with different predicate' do
|
|
25
|
+
|
|
26
|
+
it "should not warn" do
|
|
27
|
+
|
|
28
|
+
# Note that the expect test must be before the class is parsed.
|
|
29
|
+
expect(ActiveFedora::Base.logger).to_not receive(:warn)
|
|
30
|
+
|
|
31
|
+
module TestModel2
|
|
32
|
+
class Book < ActiveFedora::Base
|
|
33
|
+
property :title1, predicate: ::RDF::DC.title
|
|
34
|
+
property :title2, predicate: ::RDF::DC.creator
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active-fedora
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.0.0.
|
|
4
|
+
version: 9.0.0.rc3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matt Zumwalt
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2015-01-
|
|
13
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rsolr
|
|
@@ -74,14 +74,14 @@ dependencies:
|
|
|
74
74
|
requirements:
|
|
75
75
|
- - "~>"
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
|
-
version: 0.
|
|
77
|
+
version: 0.6.0
|
|
78
78
|
type: :runtime
|
|
79
79
|
prerelease: false
|
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
|
81
81
|
requirements:
|
|
82
82
|
- - "~>"
|
|
83
83
|
- !ruby/object:Gem::Version
|
|
84
|
-
version: 0.
|
|
84
|
+
version: 0.6.0
|
|
85
85
|
- !ruby/object:Gem::Dependency
|
|
86
86
|
name: rdf-rdfxml
|
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -200,14 +200,14 @@ dependencies:
|
|
|
200
200
|
requirements:
|
|
201
201
|
- - ">="
|
|
202
202
|
- !ruby/object:Gem::Version
|
|
203
|
-
version:
|
|
203
|
+
version: 2.0.0
|
|
204
204
|
type: :development
|
|
205
205
|
prerelease: false
|
|
206
206
|
version_requirements: !ruby/object:Gem::Requirement
|
|
207
207
|
requirements:
|
|
208
208
|
- - ">="
|
|
209
209
|
- !ruby/object:Gem::Version
|
|
210
|
-
version:
|
|
210
|
+
version: 2.0.0
|
|
211
211
|
- !ruby/object:Gem::Dependency
|
|
212
212
|
name: rspec
|
|
213
213
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -438,6 +438,7 @@ files:
|
|
|
438
438
|
- spec/integration/bug_spec.rb
|
|
439
439
|
- spec/integration/collection_association_spec.rb
|
|
440
440
|
- spec/integration/complex_rdf_datastream_spec.rb
|
|
441
|
+
- spec/integration/datastream_rdf_nested_attributes_spec.rb
|
|
441
442
|
- spec/integration/delete_all_spec.rb
|
|
442
443
|
- spec/integration/eradicate_spec.rb
|
|
443
444
|
- spec/integration/fedora_solr_sync_spec.rb
|
|
@@ -513,6 +514,7 @@ files:
|
|
|
513
514
|
- spec/unit/om_datastream_spec.rb
|
|
514
515
|
- spec/unit/persistence_spec.rb
|
|
515
516
|
- spec/unit/predicates_spec.rb
|
|
517
|
+
- spec/unit/property_predicate_spec.rb
|
|
516
518
|
- spec/unit/property_spec.rb
|
|
517
519
|
- spec/unit/qualified_dublin_core_datastream_spec.rb
|
|
518
520
|
- spec/unit/query_result_builder_spec.rb
|