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 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.1'
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.1
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-04 00:00:00 -04:00
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