up_and_at_them 0.0.2 → 0.0.3

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.
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