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.
@@ -15,8 +15,9 @@ module SafetyPin
15
15
  nil
16
16
  end
17
17
 
18
- def self.find_or_create(path)
19
- find(path) || create(path)
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(path, node_type = nil, properties = nil)
31
- path = path.to_s
32
- node_type ||= "nt:unstructured"
33
- properties ||= {}
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
- if session.root_node.has_node(rel_path)
42
- raise NodeError.new("Node already exists at path: #{path}")
43
- else
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
- node
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(path, node_type = nil, properties = nil)
54
- node = self.build(path, node_type, properties)
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
- if new_props[name].is_a?(Hash)
246
- build(name, nil, new_props[name])
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, type = nil)
284
- child(name) || create(name, type)
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, type = nil, properties = nil)
289
- path = Pathname(self.path) + name.to_s
290
- Node.create(path, type, properties)
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 build(name, type = nil, properties = nil)
341
+ def node_blueprint_for(name, node_blueprint = nil)
294
342
  path = Pathname(self.path) + name.to_s
295
- Node.build(path, type, properties)
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
@@ -1,3 +1,3 @@
1
1
  module SafetyPin
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/safety_pin.rb CHANGED
@@ -3,6 +3,7 @@ $: << File.dirname(__FILE__)
3
3
  require 'java'
4
4
  require 'safety_pin/jcr'
5
5
  require 'safety_pin/node'
6
+ require 'safety_pin/node_blueprint'
6
7
  require 'safety_pin/query'
7
8
  require 'safety_pin/query/where_condition'
8
9
 
@@ -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 "give a node path that doesn't exist" do
33
- it "should create a node at the path and return it" do
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 eql "/content/foo"
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 "should create child nodes for hash values" do
386
- node.properties = {foo: {bar: "baz"}}
387
- node.child(:foo).properties.should == {"bar" => "baz"}
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 ".build" do
444
- context "given an absolute path" do
445
- it "should build and return a property-less, unsaved nt:unstructured child node" do
446
- node = SafetyPin::Node.build("/content/foo")
447
- node.should be_new
448
- node.properties.should eql({})
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
- context "given properties" do
454
- it "should build a node with properties" do
455
- node = SafetyPin::Node.build("/content/foo", nil, {foo: "bar"})
456
- node.properties.should == {"foo" => "bar"}
457
- end
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
- context "that already exists" do
469
- it "should raise an error" do
470
- lambda { SafetyPin::Node.build("/content") }.should raise_error(SafetyPin::NodeError)
471
- end
472
- end
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
- context "given an absolute path with a non-existent parent node" do
482
- it "should raise an error" do
483
- lambda { SafetyPin::Node.build("/content/foo/bar/baz") }.should raise_error(SafetyPin::NodeError)
484
- end
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
- context "given a relative path" do
488
- it "should raise an error" do
489
- lambda { SafetyPin::Node.build("content/foo") }.should raise_error(ArgumentError)
490
- end
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
- context "given a path" do
496
- it "should build and save a node" do
497
- node = SafetyPin::Node.create("/content/foo")
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
- context "given a path and a node type" do
504
- it "should build and save a node of the specified type" do
505
- node = SafetyPin::Node.create("/content/foo", "nt:folder")
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 eql("nt:folder")
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", nil, {foo: "bar"}).properties.should == {"foo" => "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", nil, {foo: "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
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-08-23 00:00:00.000000000 Z
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