obsidian 0.0.1 → 0.0.2
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/Manifest.txt +7 -1
- data/lib/obsidian.rb +2 -2
- data/lib/obsidian/spec.rb +32 -0
- data/lib/obsidian/spec/map_spec_helper.rb +48 -0
- data/lib/obsidian/spec/set_spec_helper.rb +40 -0
- data/test/units/obsidian/rails/model_update_tracker_test.rb +126 -0
- data/test/units/obsidian/spec/map_spec_helper_test.rb +47 -0
- data/test/units/obsidian/spec/set_spec_helper_test.rb +46 -0
- data/test/units/obsidian/spec_test.rb +52 -0
- metadata +9 -3
- data/test/obsidian/rails/model_update_tracker_test.rb +0 -50
data/Manifest.txt
CHANGED
@@ -4,6 +4,12 @@ README.txt
|
|
4
4
|
Rakefile
|
5
5
|
lib/obsidian.rb
|
6
6
|
lib/obsidian/rails/model_update_tracker.rb
|
7
|
+
lib/obsidian/spec.rb
|
8
|
+
lib/obsidian/spec/map_spec_helper.rb
|
9
|
+
lib/obsidian/spec/set_spec_helper.rb
|
7
10
|
test/obsidian_test.rb
|
8
11
|
test/test_helper.rb
|
9
|
-
test/obsidian/rails/model_update_tracker_test.rb
|
12
|
+
test/units/obsidian/rails/model_update_tracker_test.rb
|
13
|
+
test/units/obsidian/spec_test.rb
|
14
|
+
test/units/obsidian/spec/map_spec_helper_test.rb
|
15
|
+
test/units/obsidian/spec/set_spec_helper_test.rb
|
data/lib/obsidian.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Obsidian
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
2
|
+
VERSION = '0.0.2'
|
3
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
|
3
|
+
module Obsidian
|
4
|
+
module Spec
|
5
|
+
include Test::Unit::Assertions
|
6
|
+
def args_to_set(*args)
|
7
|
+
if args.size == 1
|
8
|
+
args.first.respond_to?(:to_set) ? args.first.to_set : Set.new([args.first])
|
9
|
+
else
|
10
|
+
args.to_set
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# find the line in a stack trace above the one from method_name
|
15
|
+
def find_calling_line(trace, method_name)
|
16
|
+
trace.each_cons(2) do |line, next_line|
|
17
|
+
if /(.*):(\d+):in .(.*)'/ =~ line &&
|
18
|
+
$3 == method_name &&
|
19
|
+
/(.*):(\d+):in .(.*)'/ =~ next_line
|
20
|
+
return [$1,$2]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def read_calling_line(trace, method_name)
|
27
|
+
file, line_number = find_calling_line(trace, method_name)
|
28
|
+
File.readlines(file)[Integer(line_number) - 1].chop.strip if file
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'obsidian/spec'
|
2
|
+
|
3
|
+
module Obsidian
|
4
|
+
module Spec
|
5
|
+
class MappingMatcher
|
6
|
+
include Obsidian::Spec
|
7
|
+
def initialize(object)
|
8
|
+
@object = object.to_set
|
9
|
+
end
|
10
|
+
def map
|
11
|
+
self
|
12
|
+
end
|
13
|
+
def to(*args, &blk)
|
14
|
+
case args.size
|
15
|
+
when 0 then self
|
16
|
+
when 1 then test("to", args.first, &blk)
|
17
|
+
else raise ArgumentError, "wrong number of arguments (#{args.size} for 0-1)"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
# for map.to.values.in
|
21
|
+
def values
|
22
|
+
self
|
23
|
+
end
|
24
|
+
def in(*other, &blk)
|
25
|
+
test("in", *other, &blk)
|
26
|
+
end
|
27
|
+
def test(method, *other, &blk)
|
28
|
+
other = args_to_set(*other)
|
29
|
+
@object.each do |obj|
|
30
|
+
assert(other.include?(blk.call(obj)),
|
31
|
+
"Expected #{obj} to map to #{error_message(other)} at\n\t#{read_calling_line(caller,method)}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def error_message(set)
|
35
|
+
(set.size == 1 ? set.to_a.first : set).inspect
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Test::Spec::Should
|
42
|
+
def all
|
43
|
+
Obsidian::Spec::MappingMatcher.new(@object)
|
44
|
+
end
|
45
|
+
def map
|
46
|
+
Obsidian::Spec::MappingMatcher.new(@object)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'obsidian/spec'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
def Set(*args)
|
5
|
+
Set.new(args)
|
6
|
+
end
|
7
|
+
|
8
|
+
module Obsidian
|
9
|
+
module Spec
|
10
|
+
class SubsetMatcher
|
11
|
+
include Obsidian::Spec
|
12
|
+
def initialize(object)
|
13
|
+
@object = object.to_set
|
14
|
+
end
|
15
|
+
def of(*other)
|
16
|
+
other = args_to_set(*other)
|
17
|
+
assert(@object.proper_subset?(other) || @object==other, "Expected #{@object.inspect} to be a subset of #{other.inspect}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class SupersetMatcher
|
21
|
+
include Obsidian::Spec
|
22
|
+
def initialize(object)
|
23
|
+
@object = object.to_set
|
24
|
+
end
|
25
|
+
def of(*other)
|
26
|
+
other = args_to_set(*other)
|
27
|
+
assert(@object.proper_superset?(other) || @object==other, "Expected #{@object.inspect} to be a superset of #{other.inspect}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Test::Spec::Should
|
34
|
+
def subset
|
35
|
+
Obsidian::Spec::SubsetMatcher.new(@object)
|
36
|
+
end
|
37
|
+
def superset
|
38
|
+
Obsidian::Spec::SupersetMatcher.new(@object)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../../..", "test_helper.rb")
|
2
|
+
require 'obsidian/rails/model_update_tracker'
|
3
|
+
include Obsidian::Rails::ModelUpdateTracker
|
4
|
+
|
5
|
+
describe "ModelUpdateTracker" do
|
6
|
+
describe "Delta" do
|
7
|
+
it "adds uncommitted objects with <<" do
|
8
|
+
delta = Delta.new
|
9
|
+
delta << "Foo"
|
10
|
+
delta.uncommitted.should == ["Foo"]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "moves uncommitted objects to committed on commit" do
|
14
|
+
delta = Delta.new
|
15
|
+
delta << "Foo"
|
16
|
+
delta.transaction_committed
|
17
|
+
delta << "Bar"
|
18
|
+
delta.transaction_committed
|
19
|
+
delta << "Quux"
|
20
|
+
delta.committed.should == ["Foo", "Bar"]
|
21
|
+
delta.uncommitted.should == ["Quux"]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "moves uncommitted objects to committed on rollback" do
|
25
|
+
delta = Delta.new
|
26
|
+
delta << "Foo"
|
27
|
+
delta.transaction_rolled_back
|
28
|
+
delta.committed.should == []
|
29
|
+
delta.uncommitted.should == []
|
30
|
+
end
|
31
|
+
|
32
|
+
it "gathers both committed and uncommitted changes into instances" do
|
33
|
+
delta = Delta.new
|
34
|
+
delta.committed = ["Foo"]
|
35
|
+
delta.uncommitted = ["Bar"]
|
36
|
+
delta.instances.should == ["Foo", "Bar"]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "gathers the class names of modified instances" do
|
40
|
+
delta = Delta.new
|
41
|
+
delta.committed = ["String"]
|
42
|
+
delta.uncommitted = [10]
|
43
|
+
delta.class_names.should == Set.new(["Fixnum", "String"])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
@tracker = Obsidian::Rails::ModelUpdateTracker
|
49
|
+
@tracker.reset
|
50
|
+
end
|
51
|
+
|
52
|
+
it "reset clears all the deltas" do
|
53
|
+
@tracker.after_create("Foo")
|
54
|
+
@tracker.after_update("Bar")
|
55
|
+
@tracker.after_destroy("Quux")
|
56
|
+
@tracker.reset
|
57
|
+
@tracker.created_delta.instances.should == []
|
58
|
+
@tracker.updated_delta.instances.should == []
|
59
|
+
@tracker.destroyed_delta.instances.should == []
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "Data access callbacks" do
|
63
|
+
before do
|
64
|
+
@tracker = Obsidian::Rails::ModelUpdateTracker
|
65
|
+
@tracker.reset
|
66
|
+
end
|
67
|
+
|
68
|
+
it "after_create bumps the created_delta" do
|
69
|
+
@tracker.after_create("Foo")
|
70
|
+
@tracker.created_delta.instances.should == ["Foo"]
|
71
|
+
@tracker.updated_delta.instances.should == []
|
72
|
+
@tracker.destroyed_delta.instances.should == []
|
73
|
+
end
|
74
|
+
|
75
|
+
it "after_update bumps the updated_delta" do
|
76
|
+
@tracker.after_update("Foo")
|
77
|
+
@tracker.created_delta.instances.should == []
|
78
|
+
@tracker.updated_delta.instances.should == ["Foo"]
|
79
|
+
@tracker.destroyed_delta.instances.should == []
|
80
|
+
end
|
81
|
+
|
82
|
+
it "after_destroyed bumps the destroyed_delta" do
|
83
|
+
@tracker.after_destroy("Foo")
|
84
|
+
@tracker.created_delta.instances.should == []
|
85
|
+
@tracker.updated_delta.instances.should == []
|
86
|
+
@tracker.destroyed_delta.instances.should == ["Foo"]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "Transaction callbacks" do
|
91
|
+
before do
|
92
|
+
@tracker = Obsidian::Rails::ModelUpdateTracker
|
93
|
+
@tracker.reset
|
94
|
+
end
|
95
|
+
|
96
|
+
it "after_transaction_commit commits all the deltas" do
|
97
|
+
@tracker.after_create("Foo")
|
98
|
+
@tracker.after_update("Bar")
|
99
|
+
@tracker.after_destroy("Quux")
|
100
|
+
@tracker.after_transaction_commit
|
101
|
+
@tracker.created_delta.committed.should == ["Foo"]
|
102
|
+
@tracker.updated_delta.committed.should == ["Bar"]
|
103
|
+
@tracker.destroyed_delta.committed.should == ["Quux"]
|
104
|
+
end
|
105
|
+
|
106
|
+
it "after_transaction_rollback rolls back all the deltas" do
|
107
|
+
@tracker.after_create("Foo")
|
108
|
+
@tracker.after_update("Bar")
|
109
|
+
@tracker.after_destroy("Quux")
|
110
|
+
@tracker.after_transaction_rollback
|
111
|
+
@tracker.created_delta.instances.should == []
|
112
|
+
@tracker.updated_delta.instances.should == []
|
113
|
+
@tracker.destroyed_delta.instances.should == []
|
114
|
+
end
|
115
|
+
|
116
|
+
it "after_transaction_exception rolls back all the deltas" do
|
117
|
+
@tracker.after_create("Foo")
|
118
|
+
@tracker.after_update("Bar")
|
119
|
+
@tracker.after_destroy("Quux")
|
120
|
+
@tracker.after_transaction_exception
|
121
|
+
@tracker.created_delta.instances.should == []
|
122
|
+
@tracker.updated_delta.instances.should == []
|
123
|
+
@tracker.destroyed_delta.instances.should == []
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../../..", "test_helper.rb")
|
2
|
+
require 'obsidian/spec/map_spec_helper'
|
3
|
+
|
4
|
+
describe "to" do
|
5
|
+
it "should reject wrong number of arguments" do
|
6
|
+
m = Obsidian::Spec::MappingMatcher.new([1])
|
7
|
+
lambda{m.to(1,2)}.should.raise(ArgumentError)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "should.map.to" do
|
12
|
+
|
13
|
+
it "should be able to check agains single values" do
|
14
|
+
[1,2,3].should.all.map.to(true) {|item| item < 10}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should give a great error message" do
|
18
|
+
err = lambda{[1,12,3].should.all.map.to(true) {|item| item < 10}}.should.raise(Test::Unit::AssertionFailedError)
|
19
|
+
err.message.should == <<-END.chop
|
20
|
+
Expected 12 to map to true at
|
21
|
+
\terr = lambda{[1,12,3].should.all.map.to(true) {|item| item < 10}}.should.raise(Test::Unit::AssertionFailedError).
|
22
|
+
<false> is not true.
|
23
|
+
END
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "should.be.in" do
|
29
|
+
|
30
|
+
it "should be able check against multiple values" do
|
31
|
+
[1,2,3].should.map.to.values.in(2,4,6) {|item| item * 2}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not care about order" do
|
35
|
+
[1,2,3].should.map.to.values.in(6,4,2) {|item| item * 2}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should give a great error message" do
|
39
|
+
err = lambda{[1,2,3].should.map.to.values.in(2,4) {|item| item * 2}}.should.raise(Test::Unit::AssertionFailedError)
|
40
|
+
err.message.should == <<-END.chop
|
41
|
+
Expected 3 to map to #<Set: {2, 4}> at
|
42
|
+
\terr = lambda{[1,2,3].should.map.to.values.in(2,4) {|item| item * 2}}.should.raise(Test::Unit::AssertionFailedError).
|
43
|
+
<false> is not true.
|
44
|
+
END
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../../..", "test_helper.rb")
|
2
|
+
require 'obsidian/spec/set_spec_helper'
|
3
|
+
|
4
|
+
describe "Set extensions for spec" do
|
5
|
+
it "Set acts as a constructor function to approximate a literal syntax for sets" do
|
6
|
+
Set(1,2,3).should == Set.new([1,2,3])
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "should.be.subset.of" do
|
11
|
+
it "succeeds for subset" do
|
12
|
+
[1,2].should.be.subset.of([1,2,3])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "succeeds for equal set" do
|
16
|
+
(1..3).should.be.subset.of([1,2,3])
|
17
|
+
end
|
18
|
+
|
19
|
+
it "will splat args for convenience" do
|
20
|
+
(1..3).should.be.subset.of(1,2,3)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "fails for non-subset" do
|
24
|
+
err = lambda{Set(0,5).should.be.subset.of([1,2,3])}.should.raise(Test::Unit::AssertionFailedError)
|
25
|
+
err.message.should == "Expected #<Set: {5, 0}> to be a subset of #<Set: {1, 2, 3}>.\n<false> is not true."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "should.be.superset.of" do
|
30
|
+
it "succeeds for superset" do
|
31
|
+
[1,2,3].should.be.superset.of([1,2])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "succeeds for equal set" do
|
35
|
+
(1..3).should.be.superset.of([1,2,3])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "will splat args for convenience" do
|
39
|
+
(1..3).should.be.superset.of(1,2,3)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "fails for non-superset" do
|
43
|
+
err = lambda {Set(1,2).should.be.superset.of([1,2,3])}.should.raise(Test::Unit::AssertionFailedError)
|
44
|
+
err.message.should == "Expected #<Set: {1, 2}> to be a superset of #<Set: {1, 2, 3}>.\n<false> is not true."
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../..", "test_helper.rb")
|
2
|
+
require 'obsidian/spec'
|
3
|
+
include Obsidian::Spec
|
4
|
+
|
5
|
+
describe "Obsidian::Spec args_to_set" do
|
6
|
+
it "can convert a single scalar to a set" do
|
7
|
+
args_to_set(:scalar).should == Set.new([:scalar])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can convert a single collection to a set" do
|
11
|
+
args_to_set([:a, :b]).should == Set.new([:a, :b])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can convert multiple scalars to a set" do
|
15
|
+
args_to_set(:a, :b).should == Set.new([:a, :b])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Obsidian::Spec find_calling_line" do
|
20
|
+
def nest_2(name)
|
21
|
+
find_calling_line(caller, name)
|
22
|
+
end
|
23
|
+
def nest_1(name)
|
24
|
+
nest_2(name)
|
25
|
+
end
|
26
|
+
it "can parse a stack trace to find the caller of a method" do
|
27
|
+
file, line_no = nest_1("nest_1")
|
28
|
+
file.should.match %r{spec_test.rb$}
|
29
|
+
line_no.should.match /^\d+$/
|
30
|
+
end
|
31
|
+
it "returns nil if a method does not exist" do
|
32
|
+
file, line_no = nest_1("not_a_real_method_name")
|
33
|
+
file.should.be nil
|
34
|
+
line_no.should.be nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "Obsidian::Spec read_calling_line" do
|
39
|
+
def nest_2(name)
|
40
|
+
read_calling_line(caller, name)
|
41
|
+
end
|
42
|
+
def nest_1(name)
|
43
|
+
nest_2(name)
|
44
|
+
end
|
45
|
+
it "can parse a stack trace to find the caller of a method" do
|
46
|
+
nest_1("nest_1").should.match /nest_1\("nest_1"\)/
|
47
|
+
end
|
48
|
+
it "returns nil if a method does not exist" do
|
49
|
+
nest_1("not_a_real_method_name").should.be nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: obsidian
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Relevance
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-04-
|
12
|
+
date: 2008-04-07 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -38,9 +38,15 @@ files:
|
|
38
38
|
- Rakefile
|
39
39
|
- lib/obsidian.rb
|
40
40
|
- lib/obsidian/rails/model_update_tracker.rb
|
41
|
+
- lib/obsidian/spec.rb
|
42
|
+
- lib/obsidian/spec/map_spec_helper.rb
|
43
|
+
- lib/obsidian/spec/set_spec_helper.rb
|
41
44
|
- test/obsidian_test.rb
|
42
45
|
- test/test_helper.rb
|
43
|
-
- test/obsidian/rails/model_update_tracker_test.rb
|
46
|
+
- test/units/obsidian/rails/model_update_tracker_test.rb
|
47
|
+
- test/units/obsidian/spec_test.rb
|
48
|
+
- test/units/obsidian/spec/map_spec_helper_test.rb
|
49
|
+
- test/units/obsidian/spec/set_spec_helper_test.rb
|
44
50
|
has_rdoc: true
|
45
51
|
homepage: http://opensource.thinkrelevance.com
|
46
52
|
post_install_message:
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "../..", "test_helper.rb")
|
2
|
-
require 'obsidian/rails/model_update_tracker'
|
3
|
-
include Obsidian::Rails::ModelUpdateTracker
|
4
|
-
|
5
|
-
describe "ModelUpdateTracker" do
|
6
|
-
describe "Runtime" do
|
7
|
-
xit "Raises an error if anything but test environment is running"
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "Delta" do
|
11
|
-
it "adds uncommitted objects with <<" do
|
12
|
-
delta = Delta.new
|
13
|
-
delta << "Foo"
|
14
|
-
delta.uncommitted.should == ["Foo"]
|
15
|
-
end
|
16
|
-
|
17
|
-
it "moves uncommitted objects to committed on commit" do
|
18
|
-
delta = Delta.new
|
19
|
-
delta << "Foo"
|
20
|
-
delta.transaction_committed
|
21
|
-
delta << "Bar"
|
22
|
-
delta.transaction_committed
|
23
|
-
delta << "Quux"
|
24
|
-
delta.committed.should == ["Foo", "Bar"]
|
25
|
-
delta.uncommitted.should == ["Quux"]
|
26
|
-
end
|
27
|
-
|
28
|
-
it "moves uncommitted objects to committed on rollback" do
|
29
|
-
delta = Delta.new
|
30
|
-
delta << "Foo"
|
31
|
-
delta.transaction_rolled_back
|
32
|
-
delta.committed.should == []
|
33
|
-
delta.uncommitted.should == []
|
34
|
-
end
|
35
|
-
|
36
|
-
it "gathers both committed and uncommitted changes into instances" do
|
37
|
-
delta = Delta.new
|
38
|
-
delta.committed = ["Foo"]
|
39
|
-
delta.uncommitted = ["Bar"]
|
40
|
-
delta.instances.should == ["Foo", "Bar"]
|
41
|
-
end
|
42
|
-
|
43
|
-
it "gathers the class names of modified instances" do
|
44
|
-
delta = Delta.new
|
45
|
-
delta.committed = ["String"]
|
46
|
-
delta.uncommitted = [10]
|
47
|
-
delta.class_names.should == Set.new(["Fixnum", "String"])
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|