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