safety_pin 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.
- data/lib/safety_pin/node.rb +86 -32
- data/lib/safety_pin/node_blueprint.rb +18 -0
- data/lib/safety_pin/version.rb +1 -1
- data/lib/safety_pin.rb +1 -0
- data/spec/node_blueprint_spec.rb +35 -0
- data/spec/node_spec.rb +145 -93
- metadata +5 -2
data/lib/safety_pin/node.rb
CHANGED
@@ -15,8 +15,9 @@ module SafetyPin
|
|
15
15
|
nil
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.find_or_create(path)
|
19
|
-
|
18
|
+
def self.find_or_create(path, primary_type = nil)
|
19
|
+
node_blueprint = NodeBlueprint.new(:path => path.to_s, :primary_type => primary_type)
|
20
|
+
find(path) || create(node_blueprint)
|
20
21
|
end
|
21
22
|
|
22
23
|
def self.exists?(path)
|
@@ -27,31 +28,31 @@ module SafetyPin
|
|
27
28
|
JCR.session
|
28
29
|
end
|
29
30
|
|
30
|
-
def self.build(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
rel_path = nil
|
35
|
-
if path.start_with?("/")
|
36
|
-
rel_path = path.sub("/","")
|
37
|
-
else
|
38
|
-
raise ArgumentError.new("Given path not absolute: #{path}")
|
39
|
-
end
|
31
|
+
def self.build(node_blueprint)
|
32
|
+
raise NodeError.new("NodeBlueprint is nil") if node_blueprint.nil?
|
33
|
+
raise NodeError.new("NodeBlueprint has non-absolute path") unless node_blueprint.path.to_s.start_with?("/")
|
34
|
+
raise NodeError.new("Node already exists at path: #{node_blueprint.path}") if Node.exists?(node_blueprint.path)
|
40
35
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
node = self.new(session.root_node.add_node(rel_path, node_type))
|
45
|
-
node.properties = properties
|
36
|
+
rel_path_to_root_node = node_blueprint.path.to_s[1..-1]
|
37
|
+
node = self.new(session.root_node.add_node(rel_path_to_root_node, node_blueprint.primary_type))
|
38
|
+
node.properties = node_blueprint.properties
|
46
39
|
|
47
|
-
|
48
|
-
end
|
40
|
+
node
|
49
41
|
rescue javax.jcr.PathNotFoundException => e
|
50
|
-
raise NodeError.new("Cannot add a new node to a non-existing parent at #{path}")
|
42
|
+
raise NodeError.new("Cannot add a new node to a non-existing parent at #{node_blueprint.path}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.update(node_blueprint)
|
46
|
+
node = find(node_blueprint.path)
|
47
|
+
# raise NodeError.new("Cannot retrieve node for update -- might not exist") if node.nil?
|
48
|
+
node.properties = node_blueprint.properties
|
49
|
+
node.primary_type = node_blueprint.primary_type
|
50
|
+
node.save
|
51
|
+
node
|
51
52
|
end
|
52
53
|
|
53
|
-
def self.create(
|
54
|
-
node = self.build(
|
54
|
+
def self.create(node_blueprint)
|
55
|
+
node = self.build(node_blueprint)
|
55
56
|
node.save
|
56
57
|
node
|
57
58
|
end
|
@@ -66,7 +67,7 @@ module SafetyPin
|
|
66
67
|
end
|
67
68
|
|
68
69
|
results = intermediate_paths.reverse.map do |intermediate_path|
|
69
|
-
create(intermediate_path) unless exists?(intermediate_path)
|
70
|
+
create(NodeBlueprint.new(:path => intermediate_path.to_s)) unless exists?(intermediate_path)
|
70
71
|
end
|
71
72
|
|
72
73
|
session.save
|
@@ -74,6 +75,17 @@ module SafetyPin
|
|
74
75
|
results
|
75
76
|
end
|
76
77
|
|
78
|
+
def self.create_or_update(node_blueprint_or_node_blueprints)
|
79
|
+
node_blueprints = Array(node_blueprint_or_node_blueprints)
|
80
|
+
node_blueprints.map do |node_blueprint|
|
81
|
+
if exists?(node_blueprint.path)
|
82
|
+
update(node_blueprint)
|
83
|
+
else
|
84
|
+
create(node_blueprint)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
77
89
|
def initialize(j_node)
|
78
90
|
@j_node = j_node
|
79
91
|
end
|
@@ -242,13 +254,41 @@ module SafetyPin
|
|
242
254
|
def properties=(new_props)
|
243
255
|
property_names = (properties.keys + new_props.keys).uniq
|
244
256
|
property_names.each do |name|
|
245
|
-
|
246
|
-
|
257
|
+
# REFACTOR ME PLZ
|
258
|
+
child_path = Pathname(path.to_s) + name.to_s
|
259
|
+
if new_props[name].is_a? Hash
|
260
|
+
new_props[name] = convert_hash_to_node_blueprint(new_props[name])
|
261
|
+
end
|
262
|
+
|
263
|
+
if new_props[name].respond_to?(:node_blueprint?) and new_props[name].node_blueprint?
|
264
|
+
# Handle node blue prints
|
265
|
+
node_blueprint = NodeBlueprint.new(:properties => new_props[name].properties,
|
266
|
+
:path => child_path.to_s,
|
267
|
+
:primary_type => new_props[name].primary_type)
|
268
|
+
if Node.exists?(child_path)
|
269
|
+
Node.update(node_blueprint)
|
270
|
+
else
|
271
|
+
Node.build(node_blueprint)
|
272
|
+
end
|
247
273
|
else
|
274
|
+
# handle everything else
|
248
275
|
self[name] = new_props[name]
|
249
276
|
end
|
250
277
|
end
|
251
278
|
end
|
279
|
+
|
280
|
+
# Convert a hash (and it's values recursively) to NodeBlueprints. This is a
|
281
|
+
# helper method, allowing a hash to be passed in to Node#properties= when
|
282
|
+
# only properties need to be set. One caveat: all node types will default
|
283
|
+
# to nt:unstructured.
|
284
|
+
def convert_hash_to_node_blueprint(hash)
|
285
|
+
hash.keys.each do |key|
|
286
|
+
if hash[key].is_a? Hash
|
287
|
+
hash[key] = convert_hash_to_node_blueprint(hash[key])
|
288
|
+
end
|
289
|
+
end
|
290
|
+
NodeBlueprint.new(:path => :no_path, :properties => hash)
|
291
|
+
end
|
252
292
|
|
253
293
|
def value_factory
|
254
294
|
session.value_factory
|
@@ -279,20 +319,34 @@ module SafetyPin
|
|
279
319
|
def primary_type
|
280
320
|
self["jcr:primaryType"]
|
281
321
|
end
|
322
|
+
|
323
|
+
def primary_type=(primary_type)
|
324
|
+
j_node.set_primary_type(primary_type)
|
325
|
+
end
|
282
326
|
|
283
|
-
def find_or_create(name,
|
284
|
-
|
327
|
+
def find_or_create(name, primary_type = nil)
|
328
|
+
path = Pathname(self.path) + name
|
329
|
+
self.class.find_or_create(path.to_s, primary_type)
|
285
330
|
end
|
286
331
|
|
287
332
|
# Create and return a child node with a given name
|
288
|
-
def create(name,
|
289
|
-
|
290
|
-
|
333
|
+
def create(name, node_blueprint = nil)
|
334
|
+
Node.create(node_blueprint_for(name, node_blueprint))
|
335
|
+
end
|
336
|
+
|
337
|
+
def build(name, node_blueprint = nil)
|
338
|
+
Node.build(node_blueprint_for(name, node_blueprint))
|
291
339
|
end
|
292
340
|
|
293
|
-
def
|
341
|
+
def node_blueprint_for(name, node_blueprint = nil)
|
294
342
|
path = Pathname(self.path) + name.to_s
|
295
|
-
|
343
|
+
|
344
|
+
unless node_blueprint.nil?
|
345
|
+
properties = node_blueprint.properties
|
346
|
+
primary_type = node_blueprint.primary_type
|
347
|
+
end
|
348
|
+
|
349
|
+
NodeBlueprint.new(:path => path.to_s, :properties => properties, :primary_type => primary_type)
|
296
350
|
end
|
297
351
|
end
|
298
352
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SafetyPin
|
2
|
+
class NodeBlueprint
|
3
|
+
attr_accessor :path, :primary_type, :properties
|
4
|
+
|
5
|
+
def initialize(opts)
|
6
|
+
raise NodeBlueprintError.new("No path specified") unless opts[:path]
|
7
|
+
@path = opts[:path]
|
8
|
+
@primary_type = opts[:primary_type] || "nt:unstructured"
|
9
|
+
@properties = opts[:properties] || {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def node_blueprint?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class NodeBlueprintError < Exception; end
|
18
|
+
end
|
data/lib/safety_pin/version.rb
CHANGED
data/lib/safety_pin.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SafetyPin::NodeBlueprint do
|
4
|
+
let(:node_blueprint) { SafetyPin::NodeBlueprint.new(:path => "/content/foo/bar", :primary_type => "nt:folder", :properties => {"foo" => "bar"}) }
|
5
|
+
|
6
|
+
describe "#primary_type" do
|
7
|
+
it "has a primary type" do
|
8
|
+
node_blueprint.primary_type.should == "nt:folder"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a default primary type" do
|
12
|
+
SafetyPin::NodeBlueprint.new(:path => "/something").primary_type.should == "nt:unstructured"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#properties" do
|
17
|
+
it "has properties" do
|
18
|
+
node_blueprint.properties.should == {"foo" => "bar"}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "defaults to an empty hash" do
|
22
|
+
SafetyPin::NodeBlueprint.new(:path => "/something").properties.should == {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#path" do
|
27
|
+
it "requires a path" do
|
28
|
+
lambda { SafetyPin::NodeBlueprint.new({}).path }.should raise_error(NodeBlueprintError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "has a path" do
|
32
|
+
node_blueprint.path.should == "/content/foo/bar"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/node_spec.rb
CHANGED
@@ -24,22 +24,22 @@ describe SafetyPin::Node do
|
|
24
24
|
describe ".find_or_create" do
|
25
25
|
context "given a node path that exists" do
|
26
26
|
it "should return the node at that path" do
|
27
|
-
SafetyPin::Node.create("/content/foo")
|
27
|
+
SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
28
28
|
SafetyPin::Node.find_or_create("/content/foo").path.should eql "/content/foo"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
context "
|
33
|
-
it "
|
32
|
+
context "when node doesn't exist" do
|
33
|
+
it "returns node created at path" do
|
34
34
|
SafetyPin::Node.find("/content/foo").should be_nil
|
35
|
-
SafetyPin::Node.find_or_create("/content/foo").path.should
|
35
|
+
SafetyPin::Node.find_or_create("/content/foo").path.should == "/content/foo"
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
describe ".exists?" do
|
41
41
|
it "returns true if node exists at path" do
|
42
|
-
SafetyPin::Node.create("/content/foo")
|
42
|
+
SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
43
43
|
SafetyPin::Node.exists?("/content/foo").should be_true
|
44
44
|
end
|
45
45
|
|
@@ -82,7 +82,7 @@ describe SafetyPin::Node do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it "should return a grandchild node given a relative path" do
|
85
|
-
SafetyPin::Node.create("/content/foo")
|
85
|
+
SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
86
86
|
node.child("content/foo").name.should eql("foo")
|
87
87
|
end
|
88
88
|
end
|
@@ -98,9 +98,35 @@ describe SafetyPin::Node do
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
101
|
+
|
102
|
+
describe ".create_or_update", :focus => true do
|
103
|
+
let(:node_blueprint) { SafetyPin::NodeBlueprint.new(:path => "/content/foo") }
|
104
|
+
|
105
|
+
it "calls Node.create with arg when nothing exists at path" do
|
106
|
+
SafetyPin::Node.should_receive(:create).with(node_blueprint)
|
107
|
+
SafetyPin::Node.create_or_update(node_blueprint)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "calls Node.update with arg when node exists at path" do
|
111
|
+
SafetyPin::Node.create(node_blueprint)
|
112
|
+
SafetyPin::Node.should_receive(:update).with(node_blueprint)
|
113
|
+
SafetyPin::Node.create_or_update(node_blueprint)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "takes a node blueprint" do
|
117
|
+
SafetyPin::Node.create_or_update(node_blueprint)
|
118
|
+
SafetyPin::Node.exists?(node_blueprint.path).should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "takes an array of node blueprints" do
|
122
|
+
node_blueprints = [node_blueprint, SafetyPin::NodeBlueprint.new(:path => "/content/foo/bar")]
|
123
|
+
SafetyPin::Node.create_or_update(node_blueprints)
|
124
|
+
node_blueprints.each {|node_blueprint| SafetyPin::Node.exists?(node_blueprint.path).should be_true }
|
125
|
+
end
|
126
|
+
end
|
101
127
|
|
102
128
|
describe "#find_or_create_child" do
|
103
|
-
let(:parent) { SafetyPin::Node.create("/content/foo") }
|
129
|
+
let(:parent) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
104
130
|
|
105
131
|
context "an existing node path" do
|
106
132
|
it "should return the child node" do
|
@@ -125,7 +151,7 @@ describe SafetyPin::Node do
|
|
125
151
|
describe "#save" do
|
126
152
|
context "on an existing node with changes" do
|
127
153
|
before do
|
128
|
-
@node = SafetyPin::Node.create("/content/foo")
|
154
|
+
@node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
129
155
|
@node["bar"] = "baz"
|
130
156
|
end
|
131
157
|
|
@@ -143,13 +169,13 @@ describe SafetyPin::Node do
|
|
143
169
|
|
144
170
|
context "on a new node" do
|
145
171
|
it "should save the node" do
|
146
|
-
node = SafetyPin::Node.build("/content/foo")
|
172
|
+
node = SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
147
173
|
node.save.should be_true
|
148
174
|
end
|
149
175
|
|
150
176
|
it "should save changes in parent node" do
|
151
|
-
parent_node = SafetyPin::Node.create("/content/foo")
|
152
|
-
node = SafetyPin::Node.build("/content/foo/bar")
|
177
|
+
parent_node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
178
|
+
node = SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "/content/foo/bar"))
|
153
179
|
parent_node["baz"] = "qux"
|
154
180
|
parent_node.should be_changed
|
155
181
|
node.save
|
@@ -160,7 +186,7 @@ describe SafetyPin::Node do
|
|
160
186
|
|
161
187
|
describe "#read_attribute" do
|
162
188
|
context "on an existing node" do
|
163
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
189
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
164
190
|
|
165
191
|
it "should return the string value of a string property" do
|
166
192
|
node["foo"] = "bar"
|
@@ -208,12 +234,12 @@ describe SafetyPin::Node do
|
|
208
234
|
end
|
209
235
|
|
210
236
|
it "should throw an exception when accessing a non-existent (nil) property" do
|
211
|
-
lambda { SafetyPin::Node.build("/content/foo").read_attribute("foo-bar-baz") }.should raise_error(SafetyPin::NilPropertyError)
|
237
|
+
lambda { SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "/content/foo")).read_attribute("foo-bar-baz") }.should raise_error(SafetyPin::NilPropertyError)
|
212
238
|
end
|
213
239
|
end
|
214
240
|
|
215
241
|
context "#write_attribute" do
|
216
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
242
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
217
243
|
|
218
244
|
context "given a single value" do
|
219
245
|
it "should set a string property value" do
|
@@ -302,7 +328,7 @@ describe SafetyPin::Node do
|
|
302
328
|
end
|
303
329
|
|
304
330
|
context "#reload" do
|
305
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
331
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
306
332
|
|
307
333
|
it "should discard pending changes" do
|
308
334
|
node["foo"] = "bar"
|
@@ -322,7 +348,7 @@ describe SafetyPin::Node do
|
|
322
348
|
|
323
349
|
describe "#[]" do
|
324
350
|
it "should return the value of a given property name" do
|
325
|
-
node = SafetyPin::Node.create("/content/foo")
|
351
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
326
352
|
node.write_attribute("bar","baz")
|
327
353
|
node.save
|
328
354
|
node["bar"].should eql("baz")
|
@@ -331,7 +357,7 @@ describe SafetyPin::Node do
|
|
331
357
|
|
332
358
|
describe "#[]=" do
|
333
359
|
it "should set the value of a given property name" do
|
334
|
-
node = SafetyPin::Node.create("/content/foo")
|
360
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
335
361
|
node.write_attribute("bar","baz")
|
336
362
|
node["bar"] = "qux"
|
337
363
|
node["bar"].should eql("qux")
|
@@ -354,7 +380,7 @@ describe SafetyPin::Node do
|
|
354
380
|
|
355
381
|
context "#new?" do
|
356
382
|
it "should return true if node has never been saved to JCR" do
|
357
|
-
SafetyPin::Node.build("/content/foo").should be_new
|
383
|
+
SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "/content/foo")).should be_new
|
358
384
|
end
|
359
385
|
|
360
386
|
it "should return false if node has been saved to JCR" do
|
@@ -369,7 +395,7 @@ describe SafetyPin::Node do
|
|
369
395
|
end
|
370
396
|
|
371
397
|
describe "#properties=" do
|
372
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
398
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
373
399
|
|
374
400
|
it "should set the properties of a node" do
|
375
401
|
node.properties = {"foo" => "bar"}
|
@@ -382,9 +408,25 @@ describe SafetyPin::Node do
|
|
382
408
|
node.properties.should eql({"baz" => "qux"})
|
383
409
|
end
|
384
410
|
|
385
|
-
it "
|
386
|
-
|
387
|
-
|
411
|
+
it "creates child nodes for node blueprints" do
|
412
|
+
node_blueprint = SafetyPin::NodeBlueprint.new(:path => "/this/path/gets/thrown/away",
|
413
|
+
:primary_type => "sling:OrderedFolder",
|
414
|
+
:properties => {"bar" => "baz"})
|
415
|
+
node.properties = {"foo" => node_blueprint}
|
416
|
+
node.child("foo").properties.should == {"bar" => "baz"}
|
417
|
+
node.child("foo").primary_type.should == "sling:OrderedFolder"
|
418
|
+
end
|
419
|
+
|
420
|
+
xit "updates child nodes when they already exist" do
|
421
|
+
# Create /content/foo/bar and /content/foo/bar/baz
|
422
|
+
node.create(:bar, "nt:unstructured", {"bar" => "baz"})
|
423
|
+
node.child(:bar).create(:baz)
|
424
|
+
node.child(:bar).child(:baz).path.should == "/content/foo/bar/baz"
|
425
|
+
# Update /content/foo/bar by updating /content/foo properties
|
426
|
+
node.properties = {bar: SafetyPin::NodeBlueprint.new(:path => "/this/path/gets/thrown/away", :primary_type => "sling:OrderedFolder", :properties => {"updated" => "props"})}
|
427
|
+
node.child(:bar).properties.should == {"updated" => "props"}
|
428
|
+
node.child(:bar).primary_type.should == "sling:OrderedFolder"
|
429
|
+
node.child(:bar).child(:baz).path.should == "/content/foo/bar/baz"
|
388
430
|
end
|
389
431
|
end
|
390
432
|
|
@@ -396,7 +438,7 @@ describe SafetyPin::Node do
|
|
396
438
|
|
397
439
|
describe "#mixin_types" do
|
398
440
|
it "should return the mixin types of a node" do
|
399
|
-
node = SafetyPin::Node.create("/content/foo")
|
441
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
400
442
|
node.j_node.add_mixin("mix:created")
|
401
443
|
node.save
|
402
444
|
node.mixin_types.should eql(["mix:created"])
|
@@ -404,7 +446,7 @@ describe SafetyPin::Node do
|
|
404
446
|
end
|
405
447
|
|
406
448
|
describe "#add_mixin" do
|
407
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
449
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
408
450
|
|
409
451
|
it "should add a mixin type to node" do
|
410
452
|
node.add_mixin("mix:created")
|
@@ -420,7 +462,7 @@ describe SafetyPin::Node do
|
|
420
462
|
|
421
463
|
describe "#remove_mixin" do
|
422
464
|
let(:node) do
|
423
|
-
node = SafetyPin::Node.create("/content/foo")
|
465
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
424
466
|
node.add_mixin("mix:created")
|
425
467
|
node.save
|
426
468
|
node
|
@@ -440,78 +482,88 @@ describe SafetyPin::Node do
|
|
440
482
|
end
|
441
483
|
end
|
442
484
|
|
443
|
-
describe ".
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
end
|
485
|
+
describe ".update" do
|
486
|
+
let(:node) do
|
487
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
488
|
+
node.save
|
489
|
+
node
|
490
|
+
end
|
450
491
|
|
492
|
+
it "updates a nodes properties" do
|
493
|
+
SafetyPin::Node.update(SafetyPin::NodeBlueprint.new(:path => node.path, :properties => {"foo" => "barbazbuzzzzz"}))
|
494
|
+
SafetyPin::Node.find(node.path).properties.should == {"foo" => "barbazbuzzzzz"}
|
495
|
+
end
|
451
496
|
|
497
|
+
it "preserves node children" do
|
498
|
+
node.create(:bar)
|
499
|
+
SafetyPin::Node.update(SafetyPin::NodeBlueprint.new(:path => node.path, :primary_type => "sling:OrderedFolder", :properties => {"foo" => "bar"}))
|
500
|
+
SafetyPin::Node.exists?("/content/foo/bar").should be_true
|
501
|
+
end
|
452
502
|
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
end
|
459
|
-
|
460
|
-
context "and a node type string" do
|
461
|
-
it "should create an unsaved node of the given type" do
|
462
|
-
node = SafetyPin::Node.build("/content/foo", "nt:folder")
|
463
|
-
node.should be_new
|
464
|
-
node["jcr:primaryType"].should eql("nt:folder")
|
465
|
-
end
|
466
|
-
end
|
503
|
+
it "modifies the primary type" do
|
504
|
+
SafetyPin::Node.update(SafetyPin::NodeBlueprint.new(:path => node.path, :primary_type => "sling:OrderedFolder"))
|
505
|
+
SafetyPin::Node.find(node.path).primary_type.should == "sling:OrderedFolder"
|
506
|
+
end
|
507
|
+
end
|
467
508
|
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
it "should coerce path to a string" do
|
475
|
-
node = SafetyPin::Node.build(Pathname("/content/foo"))
|
476
|
-
node.should be_new
|
477
|
-
node.properties.should eql({})
|
478
|
-
end
|
509
|
+
describe "#primary_type=" do
|
510
|
+
let(:node) do
|
511
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
512
|
+
node.save
|
513
|
+
node
|
479
514
|
end
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
515
|
+
|
516
|
+
it "sets the primary type" do
|
517
|
+
node.primary_type.should == "nt:unstructured"
|
518
|
+
node.primary_type = "sling:OrderedFolder"
|
519
|
+
node.save
|
520
|
+
SafetyPin::Node.find(node.path).primary_type.should == "sling:OrderedFolder"
|
485
521
|
end
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
522
|
+
end
|
523
|
+
|
524
|
+
describe ".build" do
|
525
|
+
it "returns an unsaved node at path of a specified type with properties set" do
|
526
|
+
node = SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "/content/foo", :primary_type => "sling:OrderedFolder", :properties => {"foo" => "bar"}))
|
527
|
+
node.should be_new
|
528
|
+
node.primary_type.should == "sling:OrderedFolder"
|
529
|
+
node.properties.should == {"foo" => "bar"}
|
530
|
+
end
|
531
|
+
|
532
|
+
it "complains when the nodes already exists" do
|
533
|
+
node_blueprint = SafetyPin::NodeBlueprint.new(:path => "/content/foo")
|
534
|
+
SafetyPin::Node.create(node_blueprint)
|
535
|
+
lambda { SafetyPin::Node.build(node_blueprint) }.should raise_error(SafetyPin::NodeError)
|
536
|
+
end
|
537
|
+
|
538
|
+
it "complains when given a path with missing parents" do
|
539
|
+
lambda { SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "/content/foo/bar/baz/doesnt/exist")) }.should raise_error(SafetyPin::NodeError)
|
540
|
+
end
|
541
|
+
|
542
|
+
it "complains when given a relative path" do
|
543
|
+
lambda { SafetyPin::Node.build(SafetyPin::NodeBlueprint.new(:path => "foo/not/absolute")) }.should raise_error(SafetyPin::NodeError)
|
544
|
+
end
|
545
|
+
|
546
|
+
it "complains when given nil" do
|
547
|
+
lambda { SafetyPin::Node.build(nil) }.should raise_error(SafetyPin::NodeError)
|
491
548
|
end
|
492
549
|
end
|
493
550
|
|
494
551
|
describe ".create" do
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
node.should be_a(SafetyPin::Node)
|
499
|
-
node.destroy
|
500
|
-
end
|
552
|
+
it "creates a node" do
|
553
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
554
|
+
node.should be_a(SafetyPin::Node)
|
501
555
|
end
|
502
556
|
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
SafetyPin::Node.find("/content/foo").should_not be_nil
|
507
|
-
end
|
557
|
+
it "creates a node of a specific type" do
|
558
|
+
SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo", :primary_type => "sling:OrderedFolder"))
|
559
|
+
SafetyPin::Node.find("/content/foo").primary_type.should == "sling:OrderedFolder"
|
508
560
|
end
|
509
561
|
end
|
510
562
|
|
511
563
|
describe ".create_parents" do
|
512
564
|
it "creates parent nodes if they do not exist" do
|
513
565
|
SafetyPin::Node.create_parents("/content/foo/bar/baz")
|
514
|
-
SafetyPin::Node.create("/content/foo/bar/baz").should_not be_nil
|
566
|
+
SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo/bar/baz")).should_not be_nil
|
515
567
|
end
|
516
568
|
end
|
517
569
|
|
@@ -523,7 +575,7 @@ describe SafetyPin::Node do
|
|
523
575
|
|
524
576
|
describe "#property_is_multi_valued" do
|
525
577
|
it "should return true if property is multi-valued" do
|
526
|
-
node = SafetyPin::Node.create("/content/foo")
|
578
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
527
579
|
node["bar"] = ["baz", "qux"]
|
528
580
|
node.save
|
529
581
|
property = node.j_node.get_property("bar")
|
@@ -531,7 +583,7 @@ describe SafetyPin::Node do
|
|
531
583
|
end
|
532
584
|
|
533
585
|
it "should return false if property is not multi-valued" do
|
534
|
-
node = SafetyPin::Node.create("/content/foo")
|
586
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
535
587
|
node["bar"] = "baz"
|
536
588
|
node.save
|
537
589
|
property = node.j_node.get_property("bar")
|
@@ -542,14 +594,14 @@ describe SafetyPin::Node do
|
|
542
594
|
describe "#destroy" do
|
543
595
|
it "should remove node from JCR" do
|
544
596
|
path = "/content/foo"
|
545
|
-
node = SafetyPin::Node.create(path)
|
597
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => path))
|
546
598
|
node.destroy
|
547
599
|
SafetyPin::Node.find(path).should be_nil
|
548
600
|
end
|
549
601
|
|
550
602
|
it "should save changes in parent node" do
|
551
|
-
parent_node = SafetyPin::Node.create("/content/foo")
|
552
|
-
node = SafetyPin::Node.create("/content/foo/bar")
|
603
|
+
parent_node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
604
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo/bar"))
|
553
605
|
parent_node["baz"] = "qux"
|
554
606
|
parent_node.should be_changed
|
555
607
|
node.destroy
|
@@ -558,7 +610,7 @@ describe SafetyPin::Node do
|
|
558
610
|
|
559
611
|
context "when it fails" do
|
560
612
|
it "should raise an error" do
|
561
|
-
node = SafetyPin::Node.create("/content/foo")
|
613
|
+
node = SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo"))
|
562
614
|
node.add_mixin("mix:created")
|
563
615
|
node.save
|
564
616
|
node.remove_mixin("mix:created") # make node unremoveable
|
@@ -568,7 +620,7 @@ describe SafetyPin::Node do
|
|
568
620
|
end
|
569
621
|
|
570
622
|
describe "#primary_type" do
|
571
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
623
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
572
624
|
|
573
625
|
it "should return the primary type of the node" do
|
574
626
|
node.primary_type.should eql("nt:unstructured")
|
@@ -576,25 +628,25 @@ describe SafetyPin::Node do
|
|
576
628
|
end
|
577
629
|
|
578
630
|
describe "#build" do
|
579
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
631
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
580
632
|
|
581
633
|
it "should create a child node with a given name" do
|
582
634
|
node.build("bar").path.should == "/content/foo/bar"
|
583
635
|
end
|
584
636
|
|
585
637
|
it "should create a child node with a given name and node type" do
|
586
|
-
child_node = node.build("bar", "nt:folder")
|
638
|
+
child_node = node.build("bar", SafetyPin::NodeBlueprint.new(:primary_type => "nt:folder", :path => :no_path))
|
587
639
|
child_node.should be_a(SafetyPin::Node)
|
588
|
-
child_node.primary_type.should
|
640
|
+
child_node.primary_type.should == "nt:folder"
|
589
641
|
end
|
590
642
|
|
591
643
|
it "should create a child node with a name, node type, and properties" do
|
592
|
-
node.build("bar",
|
644
|
+
node.build("bar", SafetyPin::NodeBlueprint.new(:path => :no_path, :properties => {foo: "bar"})).properties.should == {"foo" => "bar"}
|
593
645
|
end
|
594
646
|
end
|
595
647
|
|
596
648
|
describe "#create" do
|
597
|
-
let(:node) { SafetyPin::Node.create("/content/foo") }
|
649
|
+
let(:node) { SafetyPin::Node.create(SafetyPin::NodeBlueprint.new(:path => "/content/foo")) }
|
598
650
|
|
599
651
|
it "should create a child node with a given name" do
|
600
652
|
child_node = node.create("bar")
|
@@ -603,13 +655,13 @@ describe SafetyPin::Node do
|
|
603
655
|
end
|
604
656
|
|
605
657
|
it "should create a child node with a given name and node type" do
|
606
|
-
child_node = node.create("bar", "nt:folder")
|
658
|
+
child_node = node.create("bar", SafetyPin::NodeBlueprint.new(:path => :no_path, :primary_type => "nt:folder"))
|
607
659
|
child_node.should_not be_new
|
608
660
|
child_node.primary_type.should eql("nt:folder")
|
609
661
|
end
|
610
662
|
|
611
663
|
it "should create a child node with a name, node type, and properties" do
|
612
|
-
child_node = node.create("bar",
|
664
|
+
child_node = node.create("bar", SafetyPin::NodeBlueprint.new(:path => :no_path, :properties => {foo: "bar"}))
|
613
665
|
child_node.should_not be_new
|
614
666
|
child_node.properties.should == {"foo" => "bar"}
|
615
667
|
end
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: safety_pin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jordan Raine
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-15 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: An easy-to-use JCR connector for JRuby
|
15
15
|
email:
|
@@ -31,12 +31,14 @@ files:
|
|
31
31
|
- lib/safety_pin.rb
|
32
32
|
- lib/safety_pin/jcr.rb
|
33
33
|
- lib/safety_pin/node.rb
|
34
|
+
- lib/safety_pin/node_blueprint.rb
|
34
35
|
- lib/safety_pin/query.rb
|
35
36
|
- lib/safety_pin/query/where_condition.rb
|
36
37
|
- lib/safety_pin/version.rb
|
37
38
|
- safety_pin.gemspec
|
38
39
|
- spec/jcr_spec.rb
|
39
40
|
- spec/jcr_sql2_spec.rb
|
41
|
+
- spec/node_blueprint_spec.rb
|
40
42
|
- spec/node_spec.rb
|
41
43
|
- spec/query_spec.rb
|
42
44
|
- spec/spec_helper.rb
|
@@ -68,6 +70,7 @@ summary: JCR connector for JRuby
|
|
68
70
|
test_files:
|
69
71
|
- spec/jcr_spec.rb
|
70
72
|
- spec/jcr_sql2_spec.rb
|
73
|
+
- spec/node_blueprint_spec.rb
|
71
74
|
- spec/node_spec.rb
|
72
75
|
- spec/query_spec.rb
|
73
76
|
- spec/spec_helper.rb
|