fedora_lens 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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