up_and_at_them 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2a05a7454d62421c8d4029dbae49370ddbaf695
4
- data.tar.gz: ecdfc5d2c6d0831bb9c7486392635509a821b578
3
+ metadata.gz: 939048fd2ad08daec7378c1b4dd93c5fc2416e80
4
+ data.tar.gz: 5065388003473404532a5e72fe4951eae85c911a
5
5
  SHA512:
6
- metadata.gz: 26ed6944e975a43fbfebf3596d37ed82331e3b98907f30100ebdba42dd745f4f34921c2499ea2ec66b90e61e29de29de157833a79ffb272c84dbc12026c9cce1
7
- data.tar.gz: 82880cc5008cdb448964596eda8077bf8fafcdbe3f4093714eb28e2872bb6920479ec7e4d6465f25ecd72b87d2b2bc14521bdab62db687696788347d4fb6228c
6
+ metadata.gz: 21660a484924d390ab20a6f11b7e678f46efc69cd9cdd1a7380e965c5c22e449dc673e01e32971d629526be7e3e14e2ea8a90b47df2c1e6cff6b857b1eab15c9
7
+ data.tar.gz: 0bd1b751dece6ce750eb5fd0fdfd84ed4287a53f0be8c8c54fed976328fec46988272a8a60d39aed3e5c577976361f458b10adbfd036efcaf6f820e0ce15fbe7
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --color
data/README.md CHANGED
@@ -25,10 +25,16 @@ Or install it yourself as:
25
25
  Create a Transaction which contains all of your commits. Note that the Transaction will run as soon as it is
26
26
  initialized.
27
27
 
28
- UpAndAtThem::Transaction.new([
29
- UpAndAtThem::Commit.new { puts "do something!" }.on_rollback { "undo something!" },
30
- UpAndAtThem::Commit.new { puts "do something else!" }.on_rollback { "undo something else!" },
31
- ])
28
+ UpAndAtThem::Transaction[
29
+ UpAndAtThem::Commit.new { puts "do something!" }.on_rollback { "undo something!" },
30
+ UpAndAtThem::Commit.new { puts "do something else!" }.on_rollback { "undo something else!" }
31
+ ]
32
+
33
+ The `UpAndAtThem::Transaction` array can contain any classes that respond to `#call` and `#rollback`. The
34
+ `UpAndAtThem::Commit` class allows you to define those methods easily:
35
+
36
+ UpAndAtThem::Commit.new { "this block will execute on #call" }.on_rollback { "this block will execute on #rollback" }
37
+ UpAndAtThem::Commit.new { "calling on_rollback is not necessary" }
32
38
 
33
39
  See the tests for other example Commit actions within a Transaction.
34
40
 
@@ -0,0 +1,24 @@
1
+ module UpAndAtThem
2
+ class Commit
3
+
4
+ def initialize(&block)
5
+ raise LocalJumpError unless block_given?
6
+ @block = block
7
+ end
8
+
9
+ def on_rollback(&block)
10
+ raise LocalJumpError unless block_given?
11
+ @rollback = block
12
+ self
13
+ end
14
+
15
+ def call
16
+ @block.call
17
+ end
18
+
19
+ def rollback
20
+ @rollback.call if @rollback
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module UpAndAtThem
2
+ class Transaction
3
+
4
+ def self.[](*tasks)
5
+ new(tasks)
6
+ end
7
+
8
+ def initialize(tasks)
9
+ @tasks = Array(tasks)
10
+ run
11
+ end
12
+
13
+ def run
14
+ finished_tasks = []
15
+ @tasks.each do |task|
16
+ task.call
17
+ finished_tasks << task
18
+ end
19
+ rescue => err
20
+ finished_tasks.reverse_each(&:rollback)
21
+ raise err
22
+ end
23
+
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module UpAndAtThem
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -1,47 +1,3 @@
1
- require "up_and_at_them/version"
2
-
3
- module UpAndAtThem
4
- class Commit
5
- def initialize(&block)
6
- raise LocalJumpError unless block_given?
7
- @block = block
8
- end
9
- def on_rollback(&block)
10
- raise LocalJumpError unless block_given?
11
- @rollback = block
12
- self
13
- end
14
- def call
15
- @block.call
16
- end
17
- def rollback
18
- @rollback.call if @rollback
19
- end
20
- end
21
-
22
- class Transaction
23
- def initialize(tasks)
24
- tasks = Array(tasks)
25
- tasks.each do |t|
26
- Commit === t or raise TypeError
27
- end
28
- @tasks = tasks
29
- run
30
- end
31
-
32
- def run
33
- finished_tasks = []
34
- begin
35
- @tasks.each do |task|
36
- task.call
37
- finished_tasks << task
38
- end
39
- rescue => err
40
- finished_tasks.reverse_each do |task|
41
- task.rollback
42
- end
43
- raise err
44
- end
45
- end
46
- end
47
- end
1
+ require 'up_and_at_them/version'
2
+ require 'up_and_at_them/commit'
3
+ require 'up_and_at_them/transaction'
@@ -0,0 +1,9 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'up_and_at_them'
6
+
7
+ RSpec.configure do |config|
8
+ config.order = :random
9
+ end
@@ -0,0 +1,80 @@
1
+ describe UpAndAtThem::Transaction do
2
+
3
+ it 'rolls back past commits' do
4
+ flags = { 1 => :pending, 2 => :pending, 3 => :pending, 4 => :pending }
5
+ commits = (1...4).map do |i|
6
+ UpAndAtThem::Commit.new { flags[i] = :committed; if i==3 ; raise 'uh oh!'; end }.on_rollback { flags[i] = :rolled_back }
7
+ end
8
+ expect { UpAndAtThem::Transaction.new commits }.to raise_error(RuntimeError)
9
+ expect(flags[1]).to eq :rolled_back
10
+ expect(flags[4]).to eq :pending
11
+ expect(flags[3]).to eq :committed
12
+ expect(flags[2]).to eq :rolled_back
13
+ end
14
+
15
+ it 'rolls back in reverse commit order' do
16
+ flags = { 1 => -1, 2 => -1, 3 => -1, 4 => -1 }
17
+ commits = (1...4).map do |i|
18
+ UpAndAtThem::Commit.new { flags[i] = -1; if i==3 ; raise 'uh oh!'; end }.on_rollback { flags[i] = Time.now; sleep 1 }
19
+ end
20
+ expect { UpAndAtThem::Transaction.new commits }.to raise_error(RuntimeError)
21
+ expect(flags[4].to_f).to eq -1
22
+ expect(flags[3].to_f).to be < flags[2].to_f
23
+ expect(flags[2].to_f).to be < flags[1].to_f
24
+ end
25
+
26
+ it 'allows no-rollback commits' do
27
+ flags = {1 => :pending, 2 => :pending, 3 => :pending, 4 => :pending}
28
+ commits = (1...4).map do |i|
29
+ UpAndAtThem::Commit.new { flags[i] = :committed; if i==3 ; raise 'fail!'; end }
30
+ end
31
+ expect { UpAndAtThem::Transaction.new commits }.to raise_error(RuntimeError)
32
+ expect(flags[4]).to eq :pending
33
+ expect(flags[3]).to eq :committed
34
+ expect(flags[2]).to eq :committed
35
+ expect(flags[1]).to eq :committed
36
+ end
37
+
38
+ describe '.[]' do
39
+ it 'instantiates a new Transaction' do
40
+ commit = -> { raise 'fail!' }
41
+ expect { UpAndAtThem::Transaction[commit] }.to raise_error(RuntimeError)
42
+ end
43
+ end
44
+
45
+ describe 'duck typed Commits' do
46
+ class TestCommit
47
+ attr_reader :state
48
+
49
+ def initialize(fail = false)
50
+ @fail = fail
51
+ @state = :pending
52
+ end
53
+
54
+ def call
55
+ @state = :committed
56
+ raise if @fail
57
+ end
58
+
59
+ def rollback
60
+ @state = :rolled_back
61
+ end
62
+ end
63
+
64
+ it 'runs #call on each commit' do
65
+ commit = TestCommit.new
66
+ UpAndAtThem::Transaction[commit]
67
+ expect(commit.state).to eq :committed
68
+ end
69
+
70
+ it 'runs #rollback when the commit fails' do
71
+ commit1 = TestCommit.new
72
+ commit2 = TestCommit.new(true)
73
+ expect { UpAndAtThem::Transaction[commit1, commit2] }.to raise_error
74
+ expect(commit1.state).to eq :rolled_back
75
+ expect(commit2.state).to eq :committed
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -20,4 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.6"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+
23
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: up_and_at_them
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Lane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-07 00:00:00.000000000 Z
11
+ date: 2015-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: A library for simplifying atomic transactions with the option for rollback
42
56
  of each operation in the transaction.
43
57
  email:
@@ -47,13 +61,17 @@ extensions: []
47
61
  extra_rdoc_files: []
48
62
  files:
49
63
  - ".gitignore"
64
+ - ".rspec"
50
65
  - Gemfile
51
66
  - LICENSE.txt
52
67
  - README.md
53
68
  - Rakefile
54
69
  - lib/up_and_at_them.rb
70
+ - lib/up_and_at_them/commit.rb
71
+ - lib/up_and_at_them/transaction.rb
55
72
  - lib/up_and_at_them/version.rb
56
- - test/test_transaction.rb
73
+ - spec/spec_helper.rb
74
+ - spec/transaction_spec.rb
57
75
  - up_and_at_them.gemspec
58
76
  homepage: http://github.com/metova/up_and_at_them
59
77
  licenses:
@@ -75,9 +93,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
93
  version: '0'
76
94
  requirements: []
77
95
  rubyforge_project:
78
- rubygems_version: 2.2.0
96
+ rubygems_version: 2.2.2
79
97
  signing_key:
80
98
  specification_version: 4
81
99
  summary: A library for simplifying atomic transactions.
82
100
  test_files:
83
- - test/test_transaction.rb
101
+ - spec/spec_helper.rb
102
+ - spec/transaction_spec.rb
@@ -1,54 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'up_and_at_them'
3
-
4
- class TransactionTest < MiniTest::Test
5
- def test_rollback_past_commits
6
- flags = {1 => :pending, 2 => :pending, 3 => :pending, 4 => :pending}
7
-
8
- commits = Array.new
9
- (1...4).each do |i|
10
- commits << UpAndAtThem::Commit.new { flags[i] = :committed; if i==3 ; raise 'uh oh!'; end }.on_rollback { flags[i] = :rolled_back }
11
- end
12
-
13
- assert_raises RuntimeError do
14
- UpAndAtThem::Transaction.new commits
15
- end
16
- assert_equal :pending, flags[4]
17
- assert_equal :committed, flags[3]
18
- assert_equal :rolled_back, flags[2]
19
- assert_equal :rolled_back, flags[1]
20
- end
21
-
22
- def test_rollback_in_reverse_commit_order
23
- flags = {1 => -1, 2 => -1, 3 => -1, 4 => -1}
24
-
25
- commits = Array.new
26
- (1...4).each do |i|
27
- commits << UpAndAtThem::Commit.new { flags[i] = -1; if i==3 ; raise 'uh oh!'; end }.on_rollback { flags[i] = Time.now; sleep 1 }
28
- end
29
-
30
- assert_raises RuntimeError do
31
- UpAndAtThem::Transaction.new commits
32
- end
33
- assert_equal -1, flags[4]
34
- assert flags[3].to_f < flags[2].to_f
35
- assert flags[2].to_f < flags[1].to_f
36
- end
37
-
38
- def test_allow_no_rollback_blocks
39
- flags = {1 => :pending, 2 => :pending, 3 => :pending, 4 => :pending}
40
-
41
- commits = Array.new
42
- (1...4).each do |i|
43
- commits << UpAndAtThem::Commit.new { flags[i] = :committed; if i==3 ; raise 'fail!'; end }
44
- end
45
-
46
- assert_raises RuntimeError do
47
- UpAndAtThem::Transaction.new commits
48
- end
49
- assert_equal :pending, flags[4]
50
- assert_equal :committed, flags[3]
51
- assert_equal :committed, flags[2]
52
- assert_equal :committed, flags[1]
53
- end
54
- end