nsync 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/LICENSE +21 -0
- data/README.md +204 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/jeweler_monkey_patch.rb +59 -0
- data/lib/nsync/active_record/consumer/methods.rb +47 -0
- data/lib/nsync/active_record/methods.rb +23 -0
- data/lib/nsync/active_record/producer/methods.rb +21 -0
- data/lib/nsync/class_methods.rb +17 -0
- data/lib/nsync/config.rb +96 -0
- data/lib/nsync/consumer.rb +293 -0
- data/lib/nsync/git_version_manager.rb +29 -0
- data/lib/nsync/producer/methods.rb +23 -0
- data/lib/nsync/producer.rb +129 -0
- data/lib/nsync.rb +30 -0
- data/nsync.gemspec +80 -0
- data/test/active_record_test.rb +153 -0
- data/test/classes.rb +22 -0
- data/test/helper.rb +12 -0
- data/test/nsync_config_test.rb +142 -0
- data/test/nsync_consumer_test.rb +260 -0
- data/test/nsync_producer_test.rb +261 -0
- data/test/repo.rb +64 -0
- metadata +165 -0
@@ -0,0 +1,153 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helper")
|
2
|
+
|
3
|
+
gem "activerecord", "~> 2.3.5"
|
4
|
+
require 'active_record'
|
5
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
6
|
+
ActiveRecord::Base.send(:extend, Nsync::ActiveRecord::ClassMethods)
|
7
|
+
|
8
|
+
class TestFoo < ActiveRecord::Base
|
9
|
+
nsync_producer :if => lambda{|o| o.should_save }
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestBar < ActiveRecord::Base
|
13
|
+
nsync_consumer
|
14
|
+
|
15
|
+
def should_save=(val)
|
16
|
+
val
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestVersion < ActiveRecord::Base
|
21
|
+
def self.version
|
22
|
+
scoped(:order => "id DESC").first.try(:commit_id) || "0"*40
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.version=(commit_id)
|
26
|
+
create(:commit_id => commit_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.previous_version
|
30
|
+
previous_versions_raw.first.commit_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.previous_versions
|
34
|
+
previous_versions_raw.map(&:commit_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.previous_versions_raw
|
38
|
+
scoped(:order => "id DESC", :offset => 1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
class ActiveRecordTest < Test::Unit::TestCase
|
44
|
+
class MyConsumer < Nsync::Consumer
|
45
|
+
def self.config
|
46
|
+
@config ||= Nsync::Config.new
|
47
|
+
end
|
48
|
+
def config
|
49
|
+
self.class.config
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class MyProducer < Nsync::Producer
|
54
|
+
def self.config
|
55
|
+
@config ||= Nsync::Config.new
|
56
|
+
end
|
57
|
+
def config
|
58
|
+
self.class.config
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def setup
|
63
|
+
#Grit.debug = true
|
64
|
+
ActiveRecord::Base.connection.create_table :test_versions, :force => true do |t|
|
65
|
+
t.string :commit_id
|
66
|
+
t.timestamps
|
67
|
+
end
|
68
|
+
ActiveRecord::Base.connection.create_table :test_foos, :force => true do |t|
|
69
|
+
t.string :val
|
70
|
+
t.boolean :should_save
|
71
|
+
t.timestamps
|
72
|
+
end
|
73
|
+
|
74
|
+
ActiveRecord::Base.connection.create_table :test_bars, :force => true do |t|
|
75
|
+
t.integer :source_id
|
76
|
+
t.string :val
|
77
|
+
t.timestamps
|
78
|
+
end
|
79
|
+
|
80
|
+
FileUtils.rm_rf TestRepo.repo_path
|
81
|
+
MyProducer.config.repo_path = TestRepo.repo_path
|
82
|
+
FileUtils.rm_rf TestRepo.repo_push_path
|
83
|
+
Grit::Repo.init_bare(TestRepo.repo_push_path)
|
84
|
+
MyProducer.config.repo_push_url = TestRepo.repo_push_path
|
85
|
+
MyProducer.config.version_manager = Nsync::GitVersionManager.new(TestRepo.repo_path)
|
86
|
+
|
87
|
+
MyConsumer.config.repo_url = MyProducer.config.repo_push_url
|
88
|
+
FileUtils.rm_rf TestRepo.bare_consumer_repo_path
|
89
|
+
MyConsumer.config.repo_path = TestRepo.bare_consumer_repo_path
|
90
|
+
MyConsumer.config.version_manager = TestVersion
|
91
|
+
MyConsumer.config.map_class "TestFoo", "TestBar"
|
92
|
+
|
93
|
+
FileUtils.rm(MyProducer.config.lock_file, :force => true)
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_integration
|
98
|
+
@producer = MyProducer.new
|
99
|
+
#dirty, dirty, dirty hack
|
100
|
+
Nsync.config.producer_instance = @producer
|
101
|
+
@consumer = MyConsumer.new
|
102
|
+
|
103
|
+
first_foo = TestFoo.create(:val => "This should be consumed", :should_save => true)
|
104
|
+
unsaved_foo = TestFoo.create(:val => "This should not be", :should_save => false)
|
105
|
+
|
106
|
+
assert File.exists?(File.join(MyProducer.config.repo_path, first_foo.nsync_filename))
|
107
|
+
assert !File.exists?(File.join(MyProducer.config.repo_path, unsaved_foo.nsync_filename))
|
108
|
+
|
109
|
+
@producer.commit("First objects")
|
110
|
+
|
111
|
+
@consumer.update
|
112
|
+
|
113
|
+
assert_equal 1, TestBar.count
|
114
|
+
assert_equal "This should be consumed", TestBar.nsync_find(first_foo.id).first.val
|
115
|
+
|
116
|
+
unsaved_foo.update_attributes(:should_save => true, :val => "consumption time")
|
117
|
+
|
118
|
+
assert File.exists?(File.join(MyProducer.config.repo_path, unsaved_foo.nsync_filename))
|
119
|
+
|
120
|
+
@producer.commit("oh yeah")
|
121
|
+
|
122
|
+
@consumer.update
|
123
|
+
|
124
|
+
assert_equal 2, TestBar.count
|
125
|
+
|
126
|
+
first_foo.update_attributes(:should_save => false, :val => "this is now gone")
|
127
|
+
|
128
|
+
assert !File.exists?(File.join(MyProducer.config.repo_path, first_foo.nsync_filename))
|
129
|
+
|
130
|
+
@producer.commit("we got rid of one")
|
131
|
+
|
132
|
+
@consumer.update
|
133
|
+
|
134
|
+
assert_equal 1, TestBar.count
|
135
|
+
assert_equal unsaved_foo.id, TestBar.first.source_id
|
136
|
+
|
137
|
+
@producer.rollback
|
138
|
+
|
139
|
+
assert File.exists?(File.join(MyProducer.config.repo_path, first_foo.nsync_filename))
|
140
|
+
|
141
|
+
@consumer.update
|
142
|
+
|
143
|
+
assert_equal 2, TestBar.count
|
144
|
+
|
145
|
+
@consumer.rollback
|
146
|
+
|
147
|
+
assert_equal 1, TestBar.count
|
148
|
+
|
149
|
+
@consumer.update
|
150
|
+
|
151
|
+
assert_equal 2, TestBar.count
|
152
|
+
end
|
153
|
+
end
|
data/test/classes.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class NsyncTestFoo; end
|
2
|
+
class NsyncTestBar; end
|
3
|
+
|
4
|
+
class NsyncTestVersion
|
5
|
+
class << self
|
6
|
+
def version
|
7
|
+
puts "version: #{@version}"
|
8
|
+
@version
|
9
|
+
end
|
10
|
+
|
11
|
+
def previous_version
|
12
|
+
@previous_version
|
13
|
+
end
|
14
|
+
|
15
|
+
def version=(id)
|
16
|
+
puts "updated version: #{id}"
|
17
|
+
@previous_version = @version
|
18
|
+
@version = id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "lib", "nsync")
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'mocha'
|
6
|
+
require 'shoulda'
|
7
|
+
require 'redgreen'
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), "repo")
|
10
|
+
require File.join(File.dirname(__FILE__), "classes")
|
11
|
+
|
12
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helper")
|
2
|
+
|
3
|
+
class NsyncConfigTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Nsync.reset_config
|
6
|
+
@repo_path = "/foo/bar"
|
7
|
+
@repo_url = "http://example.com/foo/bar.git"
|
8
|
+
end
|
9
|
+
|
10
|
+
context "Basic Configuration" do
|
11
|
+
context "for local configuration" do
|
12
|
+
setup do
|
13
|
+
Nsync::Config.run do |config|
|
14
|
+
config.repo_path = @repo_path
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
should "set repo_path" do
|
19
|
+
assert_equal @repo_path, Nsync.config.repo_path
|
20
|
+
end
|
21
|
+
|
22
|
+
should "set local?" do
|
23
|
+
assert_equal true, Nsync.config.local?
|
24
|
+
end
|
25
|
+
|
26
|
+
should "set remote?" do
|
27
|
+
assert_equal false, Nsync.config.remote?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "for remote configuration" do
|
32
|
+
setup do
|
33
|
+
Nsync::Config.run do |config|
|
34
|
+
config.repo_path = @repo_path
|
35
|
+
config.repo_url = @repo_url
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
should "set repo_path" do
|
40
|
+
assert_equal @repo_path, Nsync.config.repo_path
|
41
|
+
end
|
42
|
+
|
43
|
+
should "set repo_url" do
|
44
|
+
assert_equal @repo_url, Nsync.config.repo_url
|
45
|
+
end
|
46
|
+
|
47
|
+
should "set local?" do
|
48
|
+
assert_equal false, Nsync.config.local?
|
49
|
+
end
|
50
|
+
|
51
|
+
should "set remote?" do
|
52
|
+
assert_equal true, Nsync.config.remote?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "Class Mapping" do
|
58
|
+
setup do
|
59
|
+
Nsync.config.map_class "NsyncTestFoo", "NsyncTestBar"
|
60
|
+
Nsync.config.map_class "NsyncTestFoo", "NsyncTestFoo"
|
61
|
+
Nsync.config.map_class "NsyncTestBar", "NsyncTestBar"
|
62
|
+
end
|
63
|
+
|
64
|
+
should "map classes according to the defined mapping in order" do
|
65
|
+
assert_equal [NsyncTestBar, NsyncTestFoo], Nsync.config.consumer_classes_for("NsyncTestFoo")
|
66
|
+
assert_equal [NsyncTestBar], Nsync.config.consumer_classes_for("NsyncTestBar")
|
67
|
+
end
|
68
|
+
|
69
|
+
should "return empty list for undefined mapping" do
|
70
|
+
assert_equal [], Nsync.config.consumer_classes_for("NsyncTestBaz")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "Lock" do
|
75
|
+
setup do
|
76
|
+
@lock_file = "/private/tmp/nsync_test_#{Process.pid}.lock"
|
77
|
+
FileUtils.rm @lock_file, :force => true
|
78
|
+
Nsync.config.lock_file = @lock_file
|
79
|
+
end
|
80
|
+
|
81
|
+
context "unlocked" do
|
82
|
+
should "return the value of the block" do
|
83
|
+
ret = Nsync.config.lock do
|
84
|
+
"Success"
|
85
|
+
end
|
86
|
+
assert_equal "Success", ret
|
87
|
+
end
|
88
|
+
|
89
|
+
should "remove the lock file" do
|
90
|
+
assert(Nsync.config.lock do
|
91
|
+
true
|
92
|
+
end)
|
93
|
+
assert !File.exists?(@lock_file)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "locked" do
|
98
|
+
setup do
|
99
|
+
FileUtils.touch @lock_file
|
100
|
+
#silence warnings
|
101
|
+
Nsync.config.log = ::Logger.new("/dev/null")
|
102
|
+
end
|
103
|
+
|
104
|
+
should "return false" do
|
105
|
+
ret = Nsync.config.lock do
|
106
|
+
true
|
107
|
+
end
|
108
|
+
assert_equal false, ret
|
109
|
+
end
|
110
|
+
|
111
|
+
should "not remove the lock file" do
|
112
|
+
assert(!Nsync.config.lock do
|
113
|
+
true
|
114
|
+
end)
|
115
|
+
assert File.exists? @lock_file
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "Version Manager" do
|
121
|
+
context "when unassigned" do
|
122
|
+
setup do
|
123
|
+
Nsync.config.version_manager = nil
|
124
|
+
end
|
125
|
+
should "raise an error" do
|
126
|
+
assert_raise RuntimeError do
|
127
|
+
Nsync.config.version_manager
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when assigned" do
|
133
|
+
setup do
|
134
|
+
Nsync.config.version_manager = true
|
135
|
+
end
|
136
|
+
|
137
|
+
should "return it" do
|
138
|
+
assert Nsync.config.version_manager
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "helper")
|
2
|
+
|
3
|
+
class NsyncConsumerTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Nsync.reset_config
|
6
|
+
#Grit.debug = true
|
7
|
+
@lock_file = "/private/tmp/nsync_test_#{Process.pid}.lock"
|
8
|
+
FileUtils.rm @lock_file, :force => true
|
9
|
+
Nsync.config.lock_file = @lock_file
|
10
|
+
|
11
|
+
Nsync.config.version_manager = stub(:version => "foo", :previous_version => "bar")
|
12
|
+
Nsync.config.version_manager.stubs(:version=).with(is_a(String))
|
13
|
+
|
14
|
+
# I think mocha is doing something evil and redefing clone
|
15
|
+
if Grit::Git.instance_methods.include?("clone")
|
16
|
+
Grit::Git.send(:undef_method, :clone)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Initializing Consumer" do
|
21
|
+
context "when the repo already exists" do
|
22
|
+
setup do
|
23
|
+
@repo = TestRepo.new
|
24
|
+
FileUtils.rm_rf @repo.bare_consumer_repo_path
|
25
|
+
|
26
|
+
Nsync.config.repo_url = @repo.repo_path
|
27
|
+
Nsync.config.repo_path = @repo.bare_consumer_repo_path
|
28
|
+
|
29
|
+
@consumer = Nsync::Consumer.new
|
30
|
+
end
|
31
|
+
|
32
|
+
should "not reclone it" do
|
33
|
+
Grit::Git.any_instance.expects(:clone).never
|
34
|
+
@consumer = Nsync::Consumer.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "for a local repo" do
|
39
|
+
setup do
|
40
|
+
Nsync.config.repo_url = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
context "that doesn't exist" do
|
44
|
+
setup do
|
45
|
+
@repo_path = "/private/tmp/nsync_non_existent_test_repo"
|
46
|
+
FileUtils.rm_rf @repo_path
|
47
|
+
|
48
|
+
Nsync.config.repo_path = @repo_path
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise a NoSuchPath error" do
|
52
|
+
assert_raise Grit::NoSuchPathError do
|
53
|
+
Nsync::Consumer.new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "that does exist" do
|
59
|
+
setup do
|
60
|
+
@repo = TestRepo.new
|
61
|
+
Nsync.config.repo_path = @repo.repo_path
|
62
|
+
@consumer = Nsync::Consumer.new
|
63
|
+
end
|
64
|
+
|
65
|
+
should "assign it to repo" do
|
66
|
+
assert @consumer.repo.is_a? Grit::Repo
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "for a remote repo" do
|
72
|
+
context "where the origin does not exist" do
|
73
|
+
setup do
|
74
|
+
@repo_url = "/private/tmp/nsync_non_existent_test_repo"
|
75
|
+
@repo_path = "/private/tmp/nsync_non_existent_test_repo_consumer.git"
|
76
|
+
FileUtils.rm_rf @repo_url
|
77
|
+
FileUtils.rm_rf @repo_path
|
78
|
+
|
79
|
+
Nsync.config.repo_url = @repo_url
|
80
|
+
Nsync.config.repo_path = @repo_path
|
81
|
+
end
|
82
|
+
|
83
|
+
should "raise a NoSuchPath error" do
|
84
|
+
assert_raise Grit::NoSuchPathError do
|
85
|
+
Nsync::Consumer.new
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "where the origin does exist" do
|
91
|
+
setup do
|
92
|
+
@repo = TestRepo.new
|
93
|
+
FileUtils.rm_rf @repo.bare_consumer_repo_path
|
94
|
+
|
95
|
+
Nsync.config.repo_url = @repo.repo_path
|
96
|
+
Nsync.config.repo_path = @repo.bare_consumer_repo_path
|
97
|
+
|
98
|
+
@consumer = Nsync::Consumer.new
|
99
|
+
end
|
100
|
+
|
101
|
+
should "assign repo to a new bare repo" do
|
102
|
+
assert @consumer.repo.is_a? Grit::Repo
|
103
|
+
assert @consumer.repo.bare
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "Updating the Consumer side" do
|
110
|
+
setup do
|
111
|
+
@repo = TestRepo.new
|
112
|
+
Nsync.config.version_manager.stubs(:version => "HEAD^1")
|
113
|
+
FileUtils.rm_rf @repo.bare_consumer_repo_path
|
114
|
+
end
|
115
|
+
|
116
|
+
context "when local" do
|
117
|
+
setup do
|
118
|
+
Nsync.config.repo_url = nil
|
119
|
+
Nsync.config.repo_path = @repo.repo_path
|
120
|
+
|
121
|
+
@consumer = Nsync::Consumer.new
|
122
|
+
@consumer.expects(:apply_changes).once
|
123
|
+
end
|
124
|
+
|
125
|
+
should "not try to fetch in changes" do
|
126
|
+
@consumer.repo.expects(:remote_fetch).never
|
127
|
+
Grit::Git.any_instance.expects(:reset).never
|
128
|
+
@consumer.update
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when remote" do
|
133
|
+
setup do
|
134
|
+
Nsync.config.repo_url = @repo.repo_path
|
135
|
+
Nsync.config.repo_path = @repo.bare_consumer_repo_path
|
136
|
+
|
137
|
+
@consumer = Nsync::Consumer.new
|
138
|
+
end
|
139
|
+
|
140
|
+
context "when updating the repo" do
|
141
|
+
should "fetch from origin" do
|
142
|
+
@consumer.expects(:apply_changes).once
|
143
|
+
@consumer.repo.expects(:remote_fetch).once
|
144
|
+
Grit::Git.any_instance.expects(:reset).once
|
145
|
+
@consumer.update
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "with ordering" do
|
150
|
+
setup do
|
151
|
+
changeset = {NsyncTestFoo => ["changes"], NsyncTestBar => ["changes"]}
|
152
|
+
|
153
|
+
order = states('order').starts_as('bar')
|
154
|
+
|
155
|
+
Nsync.config.ordering = ["NsyncTestBar", "NsyncTestFoo"]
|
156
|
+
@consumer.repo.expects(:diff).returns(:diffs).once
|
157
|
+
@consumer.expects(:changeset_from_diffs).with(:diffs).returns(changeset).once
|
158
|
+
|
159
|
+
@consumer.expects(:apply_changes_for_class).when(order.is('bar')).with(NsyncTestBar, ["changes"]).then(order.is('foo')).once
|
160
|
+
@consumer.expects(:apply_changes_for_class).when(order.is('foo')).with(NsyncTestFoo, ["changes"]).then(order.is('final')).once
|
161
|
+
end
|
162
|
+
|
163
|
+
should "execute in specified order" do
|
164
|
+
@consumer.update
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "with callbacks" do
|
169
|
+
setup do
|
170
|
+
Nsync.config.clear_class_mappings
|
171
|
+
Nsync.config.map_class "Foo", "NsyncTestFoo"
|
172
|
+
Nsync.config.map_class "Bar", "NsyncTestBar"
|
173
|
+
Nsync.config.version_manager = NsyncTestVersion
|
174
|
+
NsyncTestVersion.version = @repo.repo.head.commit.id
|
175
|
+
|
176
|
+
Nsync.config.ordering = ["NsyncTestBar", "NsyncTestFoo"]
|
177
|
+
@consumer.send(:clear_queues)
|
178
|
+
@consumer.expects(:clear_queues).twice
|
179
|
+
end
|
180
|
+
|
181
|
+
should "work" do
|
182
|
+
@repo.add_file("foo/1.json", {:id => 1, :val => "Party"})
|
183
|
+
NsyncTestFoo.expects(:nsync_find).with('1').returns([]).once
|
184
|
+
NsyncTestFoo.expects(:nsync_add_data).once.with(@consumer, :added, is_a(String), has_entry("val", "Party"))
|
185
|
+
@repo.add_file("bar/2.json", {:id => 2, :val => "Hardy"})
|
186
|
+
@repo.commit("Added some objects")
|
187
|
+
NsyncTestFoo.expects(:nsync_find).never
|
188
|
+
mock_bar = mock
|
189
|
+
mock_bar.expects(:nsync_update).once.with(@consumer, :added, is_a(String), has_entry("val", "Hardy"))
|
190
|
+
NsyncTestBar.expects(:nsync_find).with('2').returns([mock_bar]).once
|
191
|
+
|
192
|
+
|
193
|
+
order = states('order').starts_as('bar')
|
194
|
+
|
195
|
+
NsyncTestFoo.expects(:from_callback).once.when(order.is('foo')).then(order.is('final'))
|
196
|
+
mock_bar.expects(:from_callback).once.when(order.is('bar')).then(order.is('foo'))
|
197
|
+
|
198
|
+
mock_final = mock
|
199
|
+
mock_final.expects(:from_callback).once.when(order.is('final'))
|
200
|
+
|
201
|
+
@consumer.after_class_finished(NsyncTestFoo, lambda { NsyncTestFoo.from_callback })
|
202
|
+
@consumer.after_class_finished(NsyncTestBar, lambda { mock_bar.from_callback })
|
203
|
+
|
204
|
+
@consumer.after_finished(lambda { mock_final.from_callback })
|
205
|
+
|
206
|
+
@consumer.update
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "basic flow" do
|
211
|
+
setup do
|
212
|
+
Nsync.config.clear_class_mappings
|
213
|
+
Nsync.config.map_class "Foo", "NsyncTestFoo"
|
214
|
+
Nsync.config.map_class "Bar", "NsyncTestBar"
|
215
|
+
Nsync.config.version_manager = NsyncTestVersion
|
216
|
+
NsyncTestVersion.version = @repo.repo.head.commit.id
|
217
|
+
end
|
218
|
+
|
219
|
+
should "work" do
|
220
|
+
@repo.add_file("foo/1.json", {:id => 1, :val => "Party"})
|
221
|
+
@repo.commit("Added one object")
|
222
|
+
NsyncTestFoo.expects(:nsync_find).with('1').returns([]).once
|
223
|
+
NsyncTestFoo.expects(:nsync_add_data).once.with(@consumer, :added, is_a(String), has_entry("val", "Party"))
|
224
|
+
@consumer.update
|
225
|
+
|
226
|
+
@repo.add_file("bar/2.json", {:id => 2, :val => "Hardy"})
|
227
|
+
@repo.commit("And now for the bar")
|
228
|
+
NsyncTestFoo.expects(:nsync_find).never
|
229
|
+
mock_bar = mock
|
230
|
+
mock_bar.expects(:nsync_update).once.with(@consumer, :added, is_a(String), has_entry("val", "Hardy"))
|
231
|
+
NsyncTestBar.expects(:nsync_find).with('2').returns([mock_bar]).once
|
232
|
+
@consumer.update
|
233
|
+
|
234
|
+
@repo.add_file("foo/1.json", {:id => 1, :val => "Party Hardest"})
|
235
|
+
@repo.add_file("bar/3.json", {:id => 3, :val => "Moooooo"})
|
236
|
+
@repo.commit("I changed the foo and added a bar")
|
237
|
+
mock_foo = mock
|
238
|
+
mock_foo.expects(:nsync_update).once.with(@consumer, :modified, is_a(String), has_entry("val", "Party Hardest"))
|
239
|
+
NsyncTestFoo.expects(:nsync_find).with('1').returns([mock_foo]).once
|
240
|
+
NsyncTestBar.expects(:nsync_find).with('3').returns([]).once
|
241
|
+
NsyncTestBar.expects(:nsync_add_data).with(@consumer, :added, is_a(String), has_entry("val", "Moooooo")).once
|
242
|
+
@consumer.update
|
243
|
+
|
244
|
+
@repo.remove_file("foo/1.json")
|
245
|
+
@repo.commit("No more party")
|
246
|
+
mock_foo2 = mock
|
247
|
+
mock_foo2.expects(:nsync_update).with(@consumer, :deleted, is_a(String), {}).once
|
248
|
+
NsyncTestFoo.expects(:nsync_find).with('1').returns([mock_foo2]).once
|
249
|
+
@consumer.update
|
250
|
+
|
251
|
+
NsyncTestFoo.expects(:nsync_find).with('1').returns([]).once
|
252
|
+
NsyncTestFoo.expects(:nsync_add_data).once.with(@consumer, :added, is_a(String), has_entry("val", "Party Hardest"))
|
253
|
+
|
254
|
+
#bring the party back
|
255
|
+
@consumer.rollback
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|