fedora_lens 0.0.5 → 0.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59868cf695e91e962aacef17bd8ca68be6fd43f4
4
- data.tar.gz: b521e38a55129333c18b9f29e4d2e48246632e46
3
+ metadata.gz: 65cadbc75268a27e1ca476cd033f2fb7df5d9dd0
4
+ data.tar.gz: 5eac3438dced3e625013d9b635e3a8c9b4915f2e
5
5
  SHA512:
6
- metadata.gz: 12bb8eebff4fbfb97d88e482e6ada5e0fd5a23b433ed5a748441210cc4ddea23d7069ad5ad07df63039148ab7083432f528df3df4f2497c7a5671be21cfb6e48
7
- data.tar.gz: 67531804cf5e3ea11544ff2191ccc1710006a2a83c6358a68b86b5ff18645823e4b216b0587a402673bb3c06a2e2aa41d0046739f1c920a11cc018ef0ef8400b
6
+ metadata.gz: fe8c4ba5b7af3b15a77a447d402aee0b4021fda668068d5a228a88dcb2cecfd13bf2947998d7f8da68bddcce2969f3dbea66158c1d077806c9deb16021e9eefe
7
+ data.tar.gz: 9d68f7494ed6e9c609d255d7113439a93f8cef35bdd67111a6735048f7d190b05cda5d11ea35e1ae0f32f081e6845a0d910502a7548403600c44a6cc788f93a5
data/Gemfile CHANGED
@@ -2,7 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem "ldp", github: 'cbeer/ldp'
6
5
  gem 'jettywrapper'
7
6
 
8
7
  group :development, :test do
data/fedora_lens.gemspec CHANGED
@@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'rdf-turtle', '~> 1.1.2'
27
27
  spec.add_dependency 'activemodel', '>= 4.0.2', "< 5.0"
28
28
  spec.add_dependency 'nokogiri', '~> 1.6.1'
29
- spec.add_dependency 'ldp'
29
+ spec.add_dependency 'ldp', '0.0.3'
30
30
  end
@@ -0,0 +1,40 @@
1
+ module FedoraLens
2
+ module AttributeMethods
3
+ module Declarations
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_attribute :attributes_as_lenses
8
+ self.attributes_as_lenses = {}.with_indifferent_access
9
+ class << self
10
+ def inherited_with_lenses(kls) #:nodoc:
11
+ ## Do some inheritance logic that doesn't override Base.inherited
12
+ inherited_without_lenses kls
13
+ # each subclass should get a copy of the parent's attributes_as_lenses table,
14
+ # it should not add to the parent's definition table.
15
+ kls.attributes_as_lenses = kls.attributes_as_lenses.dup
16
+ end
17
+ alias_method_chain :inherited, :lenses
18
+ end
19
+ end
20
+
21
+ module ClassMethods
22
+ def attribute(name, path)
23
+ raise AttributeNotSupportedException if name.to_sym == :id
24
+ attributes_as_lenses[name] = path.map{|s| coerce_to_lens(s)}
25
+ generate_method(name)
26
+ orm_to_hash = nil # force us to rebuild the aggregate_lens in case it was already built.
27
+ end
28
+
29
+ private
30
+ def coerce_to_lens(path_segment)
31
+ if path_segment.is_a? RDF::URI
32
+ Lenses.get_predicate(path_segment)
33
+ else
34
+ path_segment
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -37,21 +37,7 @@ module FedoraLens
37
37
 
38
38
 
39
39
  included do
40
- class_attribute :attributes_as_lenses
41
- self.attributes_as_lenses = {}.with_indifferent_access
42
- class << self
43
- def inherited_with_lenses(kls) #:nodoc:
44
- ## Do some inheritance logic that doesn't override Base.inherited
45
- inherited_without_lenses kls
46
- # each subclass should get a copy of the parent's attributes_as_lenses table,
47
- # it should not add to the parent's definition table.
48
- kls.attributes_as_lenses = kls.attributes_as_lenses.dup
49
- end
50
- alias_method_chain :inherited, :lenses
51
- end
52
-
53
-
54
-
40
+ include Declarations
55
41
  initialize_generated_modules
56
42
  include Read
57
43
  include Write
@@ -127,23 +113,7 @@ module FedoraLens
127
113
  @generated_attribute_methods = Module.new { extend Mutex_m }
128
114
  include @generated_attribute_methods
129
115
  end
130
-
131
- def attribute(name, path, options={})
132
- raise AttributeNotSupportedException if name.to_sym == :id
133
- attributes_as_lenses[name] = path.map{|s| coerce_to_lens(s)}
134
- generate_method(name)
135
- orm_to_hash = nil # force us to rebuild the aggregate_lens in case it was already built.
136
- end
137
-
138
116
  private
139
- def coerce_to_lens(path_segment)
140
- if path_segment.is_a? RDF::URI
141
- Lenses.get_predicate(path_segment)
142
- else
143
- path_segment
144
- end
145
- end
146
-
147
117
  # @param name [Symbol] name of the attribute to generate
148
118
  def generate_method(name)
149
119
  generated_attribute_methods.synchronize do
@@ -70,14 +70,12 @@ module FedoraLens
70
70
  def orm_to_hash(name_to_lens)
71
71
  Lens[
72
72
  get: lambda do |orm|
73
- name_to_lens.reduce({}) do |hash, pair|
74
- key, lens = pair
73
+ name_to_lens.inject({}) do |hash, (key, lens)|
75
74
  hash.merge(key => lens.get(orm))
76
75
  end
77
76
  end,
78
77
  put: lambda do |orm, hash|
79
- name_to_lens.each do |pair|
80
- key, lens = pair
78
+ name_to_lens.each do |(key, lens)|
81
79
  lens.put(orm, hash[key])
82
80
  end
83
81
  orm
@@ -103,13 +101,38 @@ module FedoraLens
103
101
  ]
104
102
  end
105
103
 
106
- def get_predicate(predicate)
104
+ def empty_property(graph, rdf_subject, predicate, should_delete)
105
+ if should_delete
106
+ graph.query([rdf_subject, predicate, nil]).each_statement do |statement|
107
+ if should_delete.call(statement.object)
108
+ graph.delete(statement)
109
+ end
110
+ end
111
+ else
112
+ graph.delete([rdf_subject, predicate, nil])
113
+ end
114
+ end
115
+
116
+ # @param [RDF::URI] predicate
117
+ # @param [Hash] opts
118
+ # @option opts [Proc] :select a proc that takes the object and returns
119
+ # true if it should be included in this subset
120
+ # of the predicates. Used for storing
121
+ # different classes of objects under different
122
+ # attribute names even though they all use the
123
+ # same predicate.
124
+ def get_predicate(predicate, opts = {})
107
125
  Lens[
108
126
  get: lambda do |orm|
109
- orm.value(predicate)
127
+ values = orm.value(predicate)
128
+ if opts[:select]
129
+ values.select { |val| opts[:select].call(val) }
130
+ else
131
+ values
132
+ end
110
133
  end,
111
134
  put: lambda do |orm, values|
112
- orm.graph.delete([orm.resource.subject_uri, predicate, nil])
135
+ empty_property(orm.graph, orm.resource.subject_uri, predicate, opts[:select])
113
136
  Array(values).each do |value|
114
137
  orm.graph.insert([orm.resource.subject_uri, predicate, value])
115
138
  end
@@ -1,3 +1,3 @@
1
1
  module FedoraLens
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
data/lib/fedora_lens.rb CHANGED
@@ -20,6 +20,7 @@ module FedoraLens
20
20
  extend ActiveSupport::Autoload
21
21
 
22
22
  eager_autoload do
23
+ autoload :Declarations
23
24
  autoload :Read
24
25
  autoload :Write
25
26
  end
@@ -85,7 +86,7 @@ module FedoraLens
85
86
  end
86
87
 
87
88
  def id
88
- URI.parse(uri).to_s.sub(HOST + PATH, '') if uri.present?
89
+ self.class.uri_to_id(URI.parse(uri)) if uri.present?
89
90
  end
90
91
 
91
92
  protected
@@ -148,6 +149,10 @@ module FedoraLens
148
149
  "#{HOST}#{PATH}#{id}"
149
150
  end
150
151
 
152
+ def uri_to_id(uri)
153
+ uri.to_s.sub(HOST + PATH, '')
154
+ end
155
+
151
156
  def create(data)
152
157
  model = self.new(data)
153
158
  model.save
@@ -156,9 +161,8 @@ module FedoraLens
156
161
 
157
162
  def orm_to_hash
158
163
  if @orm_to_hash.nil?
159
- aggregate_lens = attributes_as_lenses.reduce({}) do |acc, pair|
160
- name, path = pair
161
- lens = path.reduce {|outer, inner| Lenses.compose(outer, inner)}
164
+ aggregate_lens = attributes_as_lenses.inject({}) do |acc, (name, path)|
165
+ lens = path.inject {|outer, inner| Lenses.compose(outer, inner)}
162
166
  acc.merge(name => lens)
163
167
  end
164
168
  @orm_to_hash = Lenses.orm_to_hash(aggregate_lens)
@@ -3,19 +3,11 @@ require 'spec_helper'
3
3
  describe FedoraLens do
4
4
  include ActiveModel::Lint::Tests
5
5
 
6
- class TestClass
7
- include FedoraLens
8
- attribute :title, [RDF::DC11.title, Lenses.single, Lenses.literal_to_string]
9
- attribute :size, [RDF::DC11.subject, Lenses.single, Lenses.literal_to_string]
10
- # attribute :xml_title, [RDF::DC11.title, Lenses.single]
11
- end
12
-
13
6
  # for ActiveModel::Lint::Tests
14
7
  def setup
15
8
  @model = TestClass.new
16
9
  end
17
10
 
18
- subject { TestClass.new }
19
11
 
20
12
  # before do
21
13
  # require 'logger'
@@ -24,133 +16,216 @@ describe FedoraLens do
24
16
  # end
25
17
  # end
26
18
 
27
- describe ".find" do
28
- context "when the object doesn't exist" do
29
- it "should raise an error" do
30
- expect{ TestClass.find('bahvejlavawwv') }.to raise_error Ldp::NotFound
19
+
20
+ describe "context with a simple class" do
21
+ before do
22
+ class TestClass
23
+ include FedoraLens
24
+ attribute :title, [RDF::DC11.title, Lenses.single, Lenses.literal_to_string]
31
25
  end
32
26
  end
33
27
 
34
- context "when the object exists" do
35
- let(:existing) { TestClass.create(title: "created resource") }
36
- subject { TestClass.find(existing.id) }
37
- it { should be_kind_of TestClass }
38
- its(:id) { should eq existing.id }
28
+ after do
29
+ Object.send(:remove_const, :TestClass)
39
30
  end
40
- end
41
31
 
42
- describe ".delete" do
43
- subject { TestClass.create(title: "created resource") }
44
-
45
- it "should be deleted" do
46
- subject.delete
47
- expect{ TestClass.find(subject.id) }.to raise_error Ldp::NotFound
48
- end
49
- end
32
+ subject { TestClass.new }
50
33
 
51
- describe ".create" do
52
- subject { TestClass.create(attributes) }
34
+ describe ".find" do
35
+ context "when the object doesn't exist" do
36
+ it "should raise an error" do
37
+ expect{ TestClass.find('bahvejlavawwv') }.to raise_error Ldp::NotFound
38
+ end
39
+ end
53
40
 
54
- context "with a hash" do
55
- let(:attributes) { { title: "created resource" } }
56
- it "creates a resource" do
57
- expect(TestClass.find(subject.id).title).to eq "created resource"
41
+ context "when the object exists" do
42
+ let(:existing) { TestClass.create(title: "created resource") }
43
+ subject { TestClass.find(existing.id) }
44
+ it { should be_kind_of TestClass }
45
+ its(:id) { should eq existing.id }
58
46
  end
59
47
  end
60
48
 
61
- context "with nil" do
62
- let(:attributes) { nil }
63
- it "creates a resource" do
64
- expect(TestClass.find(subject.id)).to be_kind_of TestClass
49
+ describe ".delete" do
50
+ subject { TestClass.create(title: "created resource") }
51
+
52
+ it "should be deleted" do
53
+ subject.delete
54
+ expect{ TestClass.find(subject.id) }.to raise_error Ldp::NotFound
65
55
  end
66
56
  end
67
- end
68
57
 
69
- describe "#id" do
70
- it "should not have 'fedora' in the id" do
71
- m = TestClass.new('http://localhost:8983/fedora/rest/41/0d/6b/47/410d6b47-ce9c-4fa0-91e2-d62765667c52')
72
- expect(m.id).to eq '/41/0d/6b/47/410d6b47-ce9c-4fa0-91e2-d62765667c52'
73
- end
74
- end
58
+ describe ".create" do
59
+ subject { TestClass.create(attributes) }
75
60
 
61
+ context "with a hash" do
62
+ let(:attributes) { { title: "created resource" } }
63
+ it "creates a resource" do
64
+ expect(TestClass.find(subject.id).title).to eq "created resource"
65
+ end
66
+ end
76
67
 
77
- describe ".save" do
78
- it "saves a new resource" do
79
- m = TestClass.new(title: "created resource")
80
- m.save
81
- TestClass.find(m.id).title.should eq "created resource"
68
+ context "with nil" do
69
+ let(:attributes) { nil }
70
+ it "creates a resource" do
71
+ expect(TestClass.find(subject.id)).to be_kind_of TestClass
72
+ end
73
+ end
82
74
  end
83
75
 
84
- it "saves an updated resource" do
85
- m = TestClass.create(title: "created resource")
86
- m.reload
87
- m.title = "changed title"
88
- m.save
89
- TestClass.find(m.id).title.should eq "changed title"
76
+ describe "#id" do
77
+ it "should not have 'fedora' in the id" do
78
+ m = TestClass.new('http://localhost:8983/fedora/rest/41/0d/6b/47/410d6b47-ce9c-4fa0-91e2-d62765667c52')
79
+ expect(m.id).to eq '/41/0d/6b/47/410d6b47-ce9c-4fa0-91e2-d62765667c52'
80
+ end
90
81
  end
91
82
 
92
- context "with a supplied id" do
93
- subject { TestClass.new(TestClass.id_to_uri('foobar')) }
94
83
 
95
- it "saves with that id" do
96
- expect(subject.new_record?).to be_true
97
- expect(subject.save).to be_true
98
- expect(subject.new_record?).to be_false
84
+ describe ".save" do
85
+ it "saves a new resource" do
86
+ m = TestClass.new(title: "created resource")
87
+ m.save
88
+ TestClass.find(m.id).title.should eq "created resource"
99
89
  end
100
90
 
101
- end
91
+ it "saves an updated resource" do
92
+ m = TestClass.create(title: "created resource")
93
+ m.reload
94
+ m.title = "changed title"
95
+ m.save
96
+ TestClass.find(m.id).title.should eq "changed title"
97
+ end
102
98
 
103
- end
99
+ context "with a supplied id" do
100
+ subject { TestClass.new(TestClass.id_to_uri('foobar')) }
104
101
 
105
- describe ".attribute" do
106
- it "makes a setter/getter" do
107
- subject.title = "foo"
108
- subject.size = "bar"
109
- expect(subject.title).to eq "foo"
110
- expect(subject.size).to eq "bar"
111
- end
102
+ it "saves with that id" do
103
+ expect(subject.new_record?).to be_true
104
+ expect(subject.save).to be_true
105
+ expect(subject.new_record?).to be_false
106
+ end
112
107
 
113
- it "should return nil if it hasn't been set" do
114
- expect(subject.title).to be_nil
108
+ end
115
109
  end
110
+ end
116
111
 
117
- it "has a [] setter/getter" do
118
- subject[:title] = 'foo'
119
- expect(subject[:title]).to eq 'foo'
112
+ context "with a class that has many attributes" do
113
+ before do
114
+ class TestClass
115
+ include FedoraLens
116
+ attribute :title, [RDF::DC11.title, Lenses.single, Lenses.literal_to_string]
117
+ attribute :subject, [RDF::DC11.subject, Lenses.single, Lenses.literal_to_string]
118
+ end
120
119
  end
121
120
 
122
- it "loads from rdf" do
121
+ after do
122
+ Object.send(:remove_const, :TestClass)
123
123
  end
124
124
 
125
- it "mixes rdf and xml" do
126
- end
125
+ subject { TestClass.new }
126
+
127
+ describe ".attribute" do
128
+ it "makes a setter/getter" do
129
+ subject.title = "foo"
130
+ subject.subject = "bar"
131
+ expect(subject.title).to eq "foo"
132
+ expect(subject.subject).to eq "bar"
133
+ end
134
+
127
135
 
128
- context "that are inherited" do
129
- class TestSubclass < TestClass
130
- attribute :description, [RDF::DC11.description, Lenses.single, Lenses.literal_to_string]
136
+ it "should return nil if it hasn't been set" do
137
+ expect(subject.title).to be_nil
131
138
  end
132
139
 
133
- subject { TestSubclass.new }
140
+ it "has a [] setter/getter" do
141
+ subject[:title] = 'foo'
142
+ expect(subject[:title]).to eq 'foo'
143
+ end
134
144
 
135
- it "should have accessor methods defined by the parent" do
136
- subject.title = "foo"
137
- subject.description = "bar"
138
- expect(subject.title).to eq "foo"
139
- expect(subject.description).to eq "bar"
145
+ it "loads from rdf" do
146
+ end
147
+
148
+ it "mixes rdf and xml" do
149
+ end
150
+
151
+ context "that are inherited" do
152
+ before do
153
+ class TestClass2
154
+ include FedoraLens
155
+
156
+ class << self
157
+ def only_foos
158
+ lambda { |obj| obj == 'foo' }
159
+ end
160
+
161
+ def only_bars
162
+ lambda { |obj| obj == 'bar' }
163
+ end
164
+ end
165
+
166
+ attribute :subject, [Lenses.get_predicate(RDF::DC11.subject, select: only_foos), Lenses.literals_to_strings]
167
+ attribute :subject2, [Lenses.get_predicate(RDF::DC11.subject, select: only_bars), Lenses.literals_to_strings]
168
+ end
169
+ end
170
+ after do
171
+ Object.send(:remove_const, :TestClass2)
172
+ end
173
+
174
+ let(:original_values) { { 'subject' => ['foo'], 'subject2' => ['bar'] } }
175
+
176
+ subject { TestClass2.new(original_values) }
177
+ before { subject.send(:push_attributes_to_orm) }
178
+
179
+
180
+ it "should multiplex the separate attributes into one predicate" do
181
+ expect(subject.orm.graph.dump(:ttl)).to eq(
182
+ "\n<> <http://purl.org/dc/elements/1.1/subject> \"foo\",\n" +
183
+ " \"bar\" .\n")
184
+ end
185
+
186
+ it "should demultiplex the predicate into separate attributes into one predicat" do
187
+ expect(subject.send(:get_attributes_from_orm, subject.orm)).to eq original_values
188
+ end
140
189
  end
141
190
 
142
- context "a sibling class" do
143
- class TestAnotherSubclass < TestClass
191
+ context "that are inherited" do
192
+ before do
193
+ class TestSubclass < TestClass
194
+ attribute :description, [RDF::DC11.description, Lenses.single, Lenses.literal_to_string]
195
+ end
196
+ end
197
+ after do
198
+ Object.send(:remove_const, :TestSubclass)
144
199
  end
145
200
 
146
- subject { TestAnotherSubclass }
201
+ subject { TestSubclass.new }
147
202
 
148
- it "instances should not have accessor methods defined by the other sibling" do
149
- expect { subject.new.description }.to raise_error NoMethodError
203
+ it "should have accessor methods defined by the parent" do
204
+ subject.title = "foo"
205
+ subject.description = "bar"
206
+ expect(subject.title).to eq "foo"
207
+ expect(subject.description).to eq "bar"
150
208
  end
151
209
 
152
- it "should not have attribute lenses defined by the other sibling" do
153
- expect(TestAnotherSubclass.attributes_as_lenses.keys).to_not include "description"
210
+ context "a sibling class" do
211
+ before do
212
+ class TestAnotherSubclass < TestClass
213
+ end
214
+ end
215
+
216
+ after do
217
+ Object.send(:remove_const, :TestAnotherSubclass)
218
+ end
219
+
220
+ subject { TestAnotherSubclass }
221
+
222
+ it "instances should not have accessor methods defined by the other sibling" do
223
+ expect { subject.new.description }.to raise_error NoMethodError
224
+ end
225
+
226
+ it "should not have attribute lenses defined by the other sibling" do
227
+ expect(TestAnotherSubclass.attributes_as_lenses.keys).to_not include "description"
228
+ end
154
229
  end
155
230
  end
156
231
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fedora_lens
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-16 00:00:00.000000000 Z
12
+ date: 2014-04-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -119,16 +119,16 @@ dependencies:
119
119
  name: ldp
120
120
  requirement: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: '0'
124
+ version: 0.0.3
125
125
  type: :runtime
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - '>='
129
+ - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: '0'
131
+ version: 0.0.3
132
132
  description: ''
133
133
  email:
134
134
  - justin@curationexperts.com
@@ -149,6 +149,7 @@ files:
149
149
  - fedora_lens.gemspec
150
150
  - lib/fedora_lens.rb
151
151
  - lib/fedora_lens/attribute_methods.rb
152
+ - lib/fedora_lens/attribute_methods/declarations.rb
152
153
  - lib/fedora_lens/attribute_methods/read.rb
153
154
  - lib/fedora_lens/attribute_methods/write.rb
154
155
  - lib/fedora_lens/errors.rb