ellington 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/Gemfile +14 -2
- data/Gemfile.lock +40 -0
- data/README.md +66 -17
- data/lib/ellington.rb +6 -4
- data/lib/ellington/attendant.rb +21 -0
- data/lib/ellington/conductor.rb +59 -0
- data/lib/ellington/connection.rb +11 -0
- data/lib/ellington/connection_list.rb +29 -0
- data/lib/ellington/errros.rb +22 -0
- data/lib/ellington/has_targets.rb +29 -0
- data/lib/ellington/line.rb +95 -0
- data/lib/ellington/line_info.rb +34 -0
- data/lib/ellington/line_list.rb +24 -0
- data/lib/ellington/logger.rb +11 -0
- data/lib/ellington/passenger.rb +67 -0
- data/lib/ellington/route.rb +114 -0
- data/lib/ellington/route_info.rb +25 -0
- data/lib/ellington/station.rb +88 -0
- data/lib/ellington/station_info.rb +11 -0
- data/lib/ellington/station_list.rb +24 -0
- data/lib/ellington/target.rb +25 -0
- data/lib/ellington/ticket.rb +22 -0
- data/lib/ellington/transition_info.rb +4 -0
- data/lib/ellington/unique_type_array.rb +39 -0
- data/lib/ellington/version.rb +1 -1
- data/test/attendant_test.rb +42 -0
- data/test/conductor_test.rb +32 -0
- data/test/example.rb +212 -0
- data/test/line_test.rb +95 -0
- data/test/passenger_test.rb +73 -0
- data/test/route_test.rb +51 -0
- data/test/station_test.rb +115 -0
- data/test/target_test.rb +54 -0
- data/test/test_helper.rb +6 -0
- data/test/ticket_test.rb +39 -0
- metadata +92 -14
- data/.gitignore +0 -17
- data/ellington.gemspec +0 -19
data/test/route_test.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class RouteTest < MicroTest::Test
|
4
|
+
|
5
|
+
before do
|
6
|
+
@route = BasicMath.new
|
7
|
+
end
|
8
|
+
|
9
|
+
test "lines on class" do
|
10
|
+
assert @route.lines.length == 3
|
11
|
+
assert @route.lines[0].is_a?(Addition)
|
12
|
+
assert @route.lines[1].is_a?(Division)
|
13
|
+
assert @route.lines[2].is_a?(Multiplication)
|
14
|
+
end
|
15
|
+
|
16
|
+
test "type of lines must be unique" do
|
17
|
+
begin
|
18
|
+
@route.lines << Addition.new
|
19
|
+
rescue Ellington::ListAlreadyContainsType => e
|
20
|
+
end
|
21
|
+
assert !e.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
test "lines are assigned route" do
|
25
|
+
@route.lines.each do |line|
|
26
|
+
assert line.route == BasicMath
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
test "goal" do
|
31
|
+
goals = @route.goal & [@route.lines[1].goal, @route.lines[2].goal].flatten
|
32
|
+
assert @route.goal.length == goals.length
|
33
|
+
end
|
34
|
+
|
35
|
+
test "fail_target" do
|
36
|
+
assert !@route.fail_target.empty?
|
37
|
+
assert((@route.fail_target & @route.pass_target).empty?)
|
38
|
+
expected = (@route.states.keys - @route.pass_target).delete_if do |state|
|
39
|
+
state.to_s =~ /\AERROR/
|
40
|
+
end
|
41
|
+
assert @route.fail_target == expected
|
42
|
+
end
|
43
|
+
|
44
|
+
test "connections" do
|
45
|
+
assert @route.connections.first.line == @route.lines[1]
|
46
|
+
assert @route.connections.first.states == @route.lines[0].pass_target
|
47
|
+
assert @route.connections.last.line == @route.lines[2]
|
48
|
+
assert @route.connections.last.states == @route.lines[0].fail_target
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class StationTest < MicroTest::Test
|
4
|
+
|
5
|
+
before do
|
6
|
+
@route = BasicMath.new
|
7
|
+
@line = @route.lines.first
|
8
|
+
@station = @line.stations.first
|
9
|
+
@passenger = Ellington::Passenger.new(NumberWithHistory.new(0), @route)
|
10
|
+
@passenger.current_state = @route.initial_state
|
11
|
+
@passenger.lock
|
12
|
+
end
|
13
|
+
|
14
|
+
test "name" do
|
15
|
+
assert @station.name == "Add10::Addition"
|
16
|
+
end
|
17
|
+
|
18
|
+
test "state_name" do
|
19
|
+
assert @station.state_name(:foo) == "FOO Add10::Addition"
|
20
|
+
end
|
21
|
+
|
22
|
+
test "passed" do
|
23
|
+
assert @station.passed == "PASS Add10::Addition"
|
24
|
+
end
|
25
|
+
|
26
|
+
test "failed" do
|
27
|
+
assert @station.failed == "FAIL Add10::Addition"
|
28
|
+
end
|
29
|
+
|
30
|
+
test "errored" do
|
31
|
+
assert @station.errored == "ERROR Add10::Addition"
|
32
|
+
end
|
33
|
+
|
34
|
+
test "states keys" do
|
35
|
+
assert @station.states.keys == [
|
36
|
+
@station.passed,
|
37
|
+
@station.failed,
|
38
|
+
@station.errored
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
test "error state can transition to passed" do
|
43
|
+
assert @station.states.can_transition?(@station.errored => @station.passed)
|
44
|
+
end
|
45
|
+
|
46
|
+
test "error state can transition to failed" do
|
47
|
+
assert @station.states.can_transition?(@station.errored => @station.failed)
|
48
|
+
end
|
49
|
+
|
50
|
+
test "pass state is terminating" do
|
51
|
+
assert @station.states[@station.passed].nil?
|
52
|
+
assert !@station.states.can_transition?(@station.passed => @station.failed)
|
53
|
+
assert !@station.states.can_transition?(@station.passed => @station.errored)
|
54
|
+
end
|
55
|
+
|
56
|
+
test "fail state is terminating" do
|
57
|
+
assert @station.states[@station.failed].nil?
|
58
|
+
assert !@station.states.can_transition?(@station.failed => @station.passed)
|
59
|
+
assert !@station.states.can_transition?(@station.failed => @station.errored)
|
60
|
+
end
|
61
|
+
|
62
|
+
test "pass properly transitions passenger's state" do
|
63
|
+
@passenger.current_state = @route.initial_state
|
64
|
+
@station.pass @passenger
|
65
|
+
assert @passenger.current_state == @station.passed
|
66
|
+
end
|
67
|
+
|
68
|
+
test "fail properly transitions passenger's state" do
|
69
|
+
@passenger.current_state = @route.initial_state
|
70
|
+
@station.fail @passenger
|
71
|
+
assert @passenger.current_state == @station.failed
|
72
|
+
end
|
73
|
+
|
74
|
+
test "error properly transitions passenger's state" do
|
75
|
+
@passenger.current_state = @route.initial_state
|
76
|
+
@station.error @passenger
|
77
|
+
assert @passenger.current_state == @station.errored
|
78
|
+
end
|
79
|
+
|
80
|
+
test "can_engage? returns true for the expected inital state" do
|
81
|
+
@passenger.current_state = @route.initial_state
|
82
|
+
assert @station.can_engage?(@passenger)
|
83
|
+
end
|
84
|
+
|
85
|
+
test "can_engage? returns false for unexpected inital states" do
|
86
|
+
@passenger.current_state = @line.stations.last.passed
|
87
|
+
assert !@station.can_engage?(@passenger)
|
88
|
+
@passenger.current_state = :unexpected
|
89
|
+
assert !@station.can_engage?(@passenger)
|
90
|
+
end
|
91
|
+
|
92
|
+
test "engage" do
|
93
|
+
@passenger.current_state = @route.initial_state
|
94
|
+
@station.engage(@passenger, :pass => true)
|
95
|
+
assert @passenger.current_state == @station.passed
|
96
|
+
end
|
97
|
+
|
98
|
+
test "observers are notified after a station completes" do
|
99
|
+
observer = MicroMock.make.new
|
100
|
+
observer.attr :callbacks, []
|
101
|
+
observer.def :update do |info|
|
102
|
+
callbacks << info
|
103
|
+
end
|
104
|
+
@station.add_observer observer
|
105
|
+
@passenger.current_state = @route.initial_state
|
106
|
+
@station.call(@passenger, :pass => true)
|
107
|
+
assert observer.callbacks.length == 1
|
108
|
+
info = observer.callbacks.first
|
109
|
+
assert info.station == @station
|
110
|
+
assert info.passenger == @passenger
|
111
|
+
assert info.transition.old_state == @route.initial_state
|
112
|
+
assert info.transition.new_state == @station.passed
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
data/test/target_test.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class TargetTest < MicroTest::Test
|
4
|
+
|
5
|
+
before do
|
6
|
+
@number = NumberWithHistory.new(0)
|
7
|
+
end
|
8
|
+
|
9
|
+
test "basic goal" do
|
10
|
+
goal = Ellington::Target.new(:finished)
|
11
|
+
assert goal.include?(:finished)
|
12
|
+
end
|
13
|
+
|
14
|
+
test "multiple states" do
|
15
|
+
goal = Ellington::Target.new(:one, :two, :three)
|
16
|
+
assert goal.include?(:one)
|
17
|
+
assert goal.include?(:two)
|
18
|
+
assert goal.include?(:three)
|
19
|
+
end
|
20
|
+
|
21
|
+
test "not satisfied for nil passenger" do
|
22
|
+
goal = Ellington::Target.new(:finished)
|
23
|
+
assert !goal.satisfied?(nil)
|
24
|
+
end
|
25
|
+
|
26
|
+
test "not satisfied for passenger in the wrong state" do
|
27
|
+
passenger = Ellington::Passenger.new(@number, Ellington::Ticket.new, StateJacket::Catalog.new)
|
28
|
+
passenger.current_state = :open
|
29
|
+
goal = Ellington::Target.new(:closed)
|
30
|
+
assert !goal.satisfied?(passenger)
|
31
|
+
end
|
32
|
+
|
33
|
+
test "satisfied for passenger in the right state" do
|
34
|
+
passenger = Ellington::Passenger.new(@number, Ellington::Ticket.new, StateJacket::Catalog.new)
|
35
|
+
passenger.current_state = :closed
|
36
|
+
goal = Ellington::Target.new(:closed)
|
37
|
+
assert goal.satisfied?(passenger)
|
38
|
+
end
|
39
|
+
|
40
|
+
test "satisfied for passenger in an expected state" do
|
41
|
+
passenger = Ellington::Passenger.new(@number, Ellington::Ticket.new, StateJacket::Catalog.new)
|
42
|
+
passenger.current_state = :two
|
43
|
+
goal = Ellington::Target.new(:one, :two, :three)
|
44
|
+
assert goal.satisfied?(passenger)
|
45
|
+
end
|
46
|
+
|
47
|
+
test "not satisfied for passenger not in an expected state" do
|
48
|
+
passenger = Ellington::Passenger.new(@number, Ellington::Ticket.new, StateJacket::Catalog.new)
|
49
|
+
passenger.current_state = :four
|
50
|
+
goal = Ellington::Target.new(:one, :two, :three)
|
51
|
+
assert !goal.satisfied?(passenger)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/ticket_test.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
require "digest"
|
3
|
+
|
4
|
+
class TicketTest < MicroTest::Test
|
5
|
+
|
6
|
+
before do
|
7
|
+
@route = BasicMath.new
|
8
|
+
@ticket = Ellington::Ticket.new(Ellington::Target.new(:closed),
|
9
|
+
:user_id => "458e9710-c1c4-495b-b25a-c622e893f6f7",
|
10
|
+
:debit_id => "b834fb69-2eb3-4e57-b313-16b863e91f74",
|
11
|
+
:credit_id => "9a670fce-4826-4a90-aaf7-a58738a4ce5b"
|
12
|
+
)
|
13
|
+
@passenger = Ellington::Passenger.new(0, @route, @ticket)
|
14
|
+
end
|
15
|
+
|
16
|
+
test "basic ticket" do
|
17
|
+
assert @ticket[:user_id] == "458e9710-c1c4-495b-b25a-c622e893f6f7"
|
18
|
+
assert @ticket[:debit_id] == "b834fb69-2eb3-4e57-b313-16b863e91f74"
|
19
|
+
assert @ticket[:credit_id] == "9a670fce-4826-4a90-aaf7-a58738a4ce5b"
|
20
|
+
end
|
21
|
+
|
22
|
+
test "ticket id" do
|
23
|
+
assert @ticket.id == Digest::SHA256.hexdigest(@ticket.values.map(&:to_s).join)
|
24
|
+
end
|
25
|
+
|
26
|
+
test "goal" do
|
27
|
+
assert @ticket.goal.to_a == [:closed]
|
28
|
+
end
|
29
|
+
|
30
|
+
test "goal is not achieved when passenger is not in the correct state" do
|
31
|
+
assert !@ticket.goal.satisfied?(@passenger)
|
32
|
+
end
|
33
|
+
|
34
|
+
test "goal is achieved when passenger is in the correct state" do
|
35
|
+
@passenger.current_state = :closed
|
36
|
+
assert @ticket.goal.satisfied?(@passenger)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ellington
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,92 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
13
|
-
dependencies:
|
14
|
-
|
12
|
+
date: 2013-02-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: hero
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.1.7
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.1.7
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: state_jacket
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.0.7
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.0.7
|
46
|
+
description: ! "\n Ellington is a collection of simple concepts designed to bring
|
47
|
+
discipline, organization, and modularity to a project.\n\n The nomenclature is
|
48
|
+
taken from New York's subway system.\n We've found that using cohesive physical
|
49
|
+
metaphors helps people reason more clearly about the complexities of software.\n
|
50
|
+
\ The subway analogy isn't perfect but gets pretty close.\n\n The Ellington
|
51
|
+
architecture should only be applied after a good understanding of the problem domain
|
52
|
+
has been established.\n We recommend spiking a solution to learn your project's
|
53
|
+
requirements and then coming back to Ellington.\n "
|
15
54
|
email:
|
16
55
|
- natehop@gmail.com
|
17
56
|
executables: []
|
18
57
|
extensions: []
|
19
58
|
extra_rdoc_files: []
|
20
59
|
files:
|
21
|
-
- .
|
60
|
+
- lib/ellington/attendant.rb
|
61
|
+
- lib/ellington/conductor.rb
|
62
|
+
- lib/ellington/connection.rb
|
63
|
+
- lib/ellington/connection_list.rb
|
64
|
+
- lib/ellington/errros.rb
|
65
|
+
- lib/ellington/has_targets.rb
|
66
|
+
- lib/ellington/line.rb
|
67
|
+
- lib/ellington/line_info.rb
|
68
|
+
- lib/ellington/line_list.rb
|
69
|
+
- lib/ellington/logger.rb
|
70
|
+
- lib/ellington/passenger.rb
|
71
|
+
- lib/ellington/route.rb
|
72
|
+
- lib/ellington/route_info.rb
|
73
|
+
- lib/ellington/station.rb
|
74
|
+
- lib/ellington/station_info.rb
|
75
|
+
- lib/ellington/station_list.rb
|
76
|
+
- lib/ellington/target.rb
|
77
|
+
- lib/ellington/ticket.rb
|
78
|
+
- lib/ellington/transition_info.rb
|
79
|
+
- lib/ellington/unique_type_array.rb
|
80
|
+
- lib/ellington/version.rb
|
81
|
+
- lib/ellington.rb
|
22
82
|
- Gemfile
|
83
|
+
- Gemfile.lock
|
23
84
|
- LICENSE.txt
|
24
|
-
- README.md
|
25
85
|
- Rakefile
|
26
|
-
-
|
27
|
-
-
|
28
|
-
-
|
29
|
-
|
86
|
+
- README.md
|
87
|
+
- test/attendant_test.rb
|
88
|
+
- test/conductor_test.rb
|
89
|
+
- test/example.rb
|
90
|
+
- test/line_test.rb
|
91
|
+
- test/passenger_test.rb
|
92
|
+
- test/route_test.rb
|
93
|
+
- test/station_test.rb
|
94
|
+
- test/target_test.rb
|
95
|
+
- test/test_helper.rb
|
96
|
+
- test/ticket_test.rb
|
97
|
+
homepage: https://github.com/hopsoft/ellington
|
30
98
|
licenses: []
|
31
99
|
post_install_message:
|
32
100
|
rdoc_options: []
|
@@ -46,9 +114,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
114
|
version: '0'
|
47
115
|
requirements: []
|
48
116
|
rubyforge_project:
|
49
|
-
rubygems_version: 1.8.
|
117
|
+
rubygems_version: 1.8.25
|
50
118
|
signing_key:
|
51
119
|
specification_version: 3
|
52
|
-
summary:
|
53
|
-
|
54
|
-
|
120
|
+
summary: A framework for moving stateful objects through a complex series of business
|
121
|
+
rules.
|
122
|
+
test_files:
|
123
|
+
- test/attendant_test.rb
|
124
|
+
- test/conductor_test.rb
|
125
|
+
- test/example.rb
|
126
|
+
- test/line_test.rb
|
127
|
+
- test/passenger_test.rb
|
128
|
+
- test/route_test.rb
|
129
|
+
- test/station_test.rb
|
130
|
+
- test/target_test.rb
|
131
|
+
- test/test_helper.rb
|
132
|
+
- test/ticket_test.rb
|
data/.gitignore
DELETED
data/ellington.gemspec
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'ellington/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |gem|
|
7
|
-
gem.name = "ellington"
|
8
|
-
gem.version = Ellington::VERSION
|
9
|
-
gem.authors = ["Nathan Hopkins"]
|
10
|
-
gem.email = ["natehop@gmail.com"]
|
11
|
-
gem.description = %q{Write a gem description}
|
12
|
-
gem.summary = %q{Write a gem summary}
|
13
|
-
gem.homepage = ""
|
14
|
-
|
15
|
-
gem.files = `git ls-files`.split($/)
|
16
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
-
gem.require_paths = ["lib"]
|
19
|
-
end
|