pushdown 0.1.0.pre.20210714190141 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../../spec_helper'
5
+
6
+ require 'pushdown'
7
+ require 'pushdown/transition/push'
8
+
9
+
10
+ RSpec.describe( Pushdown::Transition::Push ) do
11
+
12
+ let( :state_class ) do
13
+ Class.new( Pushdown::State )
14
+ end
15
+ let( :other_state_class ) do
16
+ Class.new( Pushdown::State )
17
+ end
18
+
19
+ let( :state_data ) { Object.new }
20
+
21
+
22
+
23
+ it "pushes a new state onto the stack when applied" do
24
+ stack = [ state_class.new, state_class.new ]
25
+ transition = described_class.new( :push_test, other_state_class )
26
+
27
+ new_stack = transition.apply( stack )
28
+
29
+ expect( new_stack ).to be_an( Array )
30
+ expect( new_stack.length ).to eq( 3 )
31
+ expect( new_stack.last ).to be_a( other_state_class )
32
+ expect( new_stack.last.data ).to be_nil
33
+ end
34
+
35
+
36
+ it "passes on state data to the new state if given" do
37
+ stack = []
38
+ transition = described_class.new( :push_test, state_class, state_data )
39
+
40
+ new_stack = transition.apply( stack )
41
+
42
+ expect( new_stack.last.data ).to be( state_data )
43
+ end
44
+
45
+
46
+ it "calls the transition callbacks of the former current state and the new state" do
47
+ new_state = instance_double( other_state_class )
48
+ stack = [
49
+ state_class.new,
50
+ state_class.new
51
+ ]
52
+ transition = described_class.new( :push_test, other_state_class )
53
+
54
+ expect( stack.last ).to receive( :on_pause )
55
+ expect( other_state_class ).to receive( :new ).and_return( new_state )
56
+ expect( new_state ).to receive( :on_start )
57
+
58
+ transition.apply( stack )
59
+ end
60
+
61
+ end
62
+
@@ -0,0 +1,72 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../../spec_helper'
5
+
6
+ require 'pushdown/transition/replace'
7
+ require 'pushdown/state'
8
+
9
+ RSpec.describe( Pushdown::Transition::Replace ) do
10
+
11
+ let( :state_class ) do
12
+ Class.new( Pushdown::State )
13
+ end
14
+ let( :other_state_class ) do
15
+ Class.new( Pushdown::State )
16
+ end
17
+
18
+ let( :state_a ) { state_class.new }
19
+ let( :state_b ) { state_class.new }
20
+ let( :state_c ) { state_class.new }
21
+ let( :state_d ) { other_state_class.new }
22
+
23
+ let( :stack ) do
24
+ return [ state_a, state_b, state_c ]
25
+ end
26
+
27
+ let( :state_data ) { Object.new }
28
+
29
+
30
+ it "replaces the current stack members with a single new instance of a state when applied" do
31
+ stack = [ state_class.new, state_class.new ]
32
+ transition = described_class.new( :replace_test, other_state_class )
33
+
34
+ new_stack = transition.apply( stack )
35
+
36
+ expect( new_stack ).to be_an( Array )
37
+ expect( new_stack.length ).to eq( 1 )
38
+ expect( new_stack.last ).to be_a( other_state_class )
39
+ end
40
+
41
+
42
+ it "passes on state data to the new state if given" do
43
+ stack = []
44
+ transition = described_class.new( :replace_test, state_class, state_data )
45
+
46
+ new_stack = transition.apply( stack )
47
+
48
+ expect( new_stack.last.data ).to be( state_data )
49
+ end
50
+
51
+
52
+ it "calls the transition callbacks of all the former states and the new state" do
53
+ new_state = instance_double( other_state_class )
54
+ stack = [
55
+ state_class.new,
56
+ state_class.new,
57
+ other_state_class.new
58
+ ]
59
+ transition = described_class.new( :replace_test, other_state_class )
60
+
61
+ expect( stack[2] ).to receive( :on_stop ).ordered
62
+ expect( stack[1] ).to receive( :on_stop ).ordered
63
+ expect( stack[0] ).to receive( :on_stop ).ordered
64
+
65
+ expect( other_state_class ).to receive( :new ).and_return( new_state )
66
+ expect( new_state ).to receive( :on_start ).ordered
67
+
68
+ transition.apply( stack )
69
+ end
70
+
71
+ end
72
+
@@ -0,0 +1,71 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../../spec_helper'
5
+
6
+ require 'pushdown/transition/switch'
7
+ require 'pushdown/state'
8
+
9
+ RSpec.describe( Pushdown::Transition::Switch ) do
10
+
11
+ let( :state_class ) do
12
+ Class.new( Pushdown::State )
13
+ end
14
+ let( :other_state_class ) do
15
+ Class.new( Pushdown::State )
16
+ end
17
+
18
+ let( :state_data ) { Object.new }
19
+
20
+
21
+
22
+ it "switches the current state the stack with a new one when applied" do
23
+ stack = [ state_class.new, state_class.new ]
24
+ transition = described_class.new( :switch_test, other_state_class )
25
+
26
+ new_stack = transition.apply( stack )
27
+
28
+ expect( new_stack ).to be_an( Array )
29
+ expect( new_stack.length ).to eq( 2 )
30
+ expect( new_stack.last ).to be_a( other_state_class )
31
+ expect( new_stack.last.data ).to be_nil
32
+ end
33
+
34
+
35
+ it "passes on state data to the new state if given" do
36
+ stack = [ state_class.new ]
37
+ transition = described_class.new( :switch_test, state_class, state_data )
38
+
39
+ new_stack = transition.apply( stack )
40
+
41
+ expect( new_stack.last.data ).to be( state_data )
42
+ end
43
+
44
+
45
+ it "calls the transition callbacks of the former current state and the new state" do
46
+ new_state = instance_double( other_state_class )
47
+ stack = [
48
+ state_class.new,
49
+ state_class.new
50
+ ]
51
+ transition = described_class.new( :switch_test, other_state_class )
52
+
53
+ expect( stack.last ).to receive( :on_stop )
54
+ expect( other_state_class ).to receive( :new ).and_return( new_state )
55
+ expect( new_state ).to receive( :on_start )
56
+
57
+ transition.apply( stack )
58
+ end
59
+
60
+
61
+ it "errors if applied to an empty stack" do
62
+ stack = []
63
+ transition = described_class.new( :switch_test, other_state_class )
64
+
65
+ expect {
66
+ transition.apply( stack )
67
+ }.to raise_error( Pushdown::TransitionError, /can't switch/i )
68
+ end
69
+
70
+ end
71
+
@@ -0,0 +1,109 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../spec_helper'
5
+
6
+ require 'pushdown/transition'
7
+ require 'pushdown/state'
8
+
9
+
10
+ RSpec.describe( Pushdown::Transition ) do
11
+
12
+ let( :state_class ) do
13
+ Class.new( Pushdown::State )
14
+ end
15
+
16
+ let( :state_a ) { state_class.new }
17
+ let( :state_b ) { state_class.new }
18
+
19
+
20
+ it "is an abstract class" do
21
+ expect {
22
+ described_class.new( :change_state )
23
+ }.to raise_error( NoMethodError )
24
+ end
25
+
26
+
27
+ describe 'complete concrete subclass' do
28
+
29
+ let( :subclass ) do
30
+ Class.new( described_class ) do
31
+
32
+ def initialize( name, new_state, *args )
33
+ super( name, *args )
34
+ @new_state = new_state
35
+ end
36
+
37
+ attr_reader :new_state
38
+
39
+ def apply( stack )
40
+ stack.push( self.new_state.new )
41
+ return stack
42
+ end
43
+
44
+ end
45
+ end
46
+
47
+ it "can be instantiated" do
48
+ result = subclass.new( :change_state, state_class )
49
+ expect( result ).to be_a( described_class )
50
+ expect( result.name ).to eq( :change_state )
51
+ end
52
+
53
+
54
+ it "requires a name to be instantiated" do
55
+ expect {
56
+ subclass.new
57
+ }.to raise_error( ArgumentError, /wrong number of arguments/i )
58
+ end
59
+
60
+
61
+ it "can alter the stack" do
62
+ stack = [ state_a, state_b ]
63
+ transition = subclass.new( :go_home, state_class )
64
+
65
+ result = transition.apply( stack )
66
+
67
+ expect( result ).to be_an( Array )
68
+ expect( result.length ).to eq( 3 )
69
+ expect( result.last ).to be_a( state_class )
70
+ end
71
+
72
+
73
+ it "knows what the name of its type is" do
74
+ subclass.singleton_class.attr_accessor :name
75
+ subclass.name = 'Acme::Transition::Frobnicate'
76
+
77
+ transition = subclass.new( :rejigger, state_class )
78
+
79
+ expect( transition.type_name ).to eq( :frobnicate )
80
+ end
81
+
82
+
83
+ it "handles anonymous classes for #type_name" do
84
+ transition = subclass.new( :rejigger, state_class )
85
+
86
+ expect( transition.type_name ).to eq( :anonymous )
87
+ end
88
+
89
+ end
90
+
91
+
92
+ describe 'incomplete concrete subclass' do
93
+
94
+ let( :subclass ) { Class.new(described_class) }
95
+
96
+
97
+ it "raises an error when applied to a stack" do
98
+ stack = [ state_a, state_b ]
99
+ transition = subclass.new( :change_state )
100
+
101
+ expect {
102
+ transition.apply( stack )
103
+ }.to raise_error( NotImplementedError, /apply/i )
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
data/spec/spec_helper.rb CHANGED
@@ -7,6 +7,8 @@ require 'rspec'
7
7
 
8
8
  require 'loggability/spechelpers'
9
9
 
10
+ require 'pushdown'
11
+
10
12
 
11
13
  ### Mock with RSpec
12
14
  RSpec.configure do |config|
@@ -23,6 +25,8 @@ RSpec.configure do |config|
23
25
  config.run_all_when_everything_filtered = true
24
26
  config.shared_context_metadata_behavior = :apply_to_host_groups
25
27
  # config.warnings = true
28
+
29
+ config.include( Loggability::SpecHelpers )
26
30
  end
27
31
 
28
32
 
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,15 +1,82 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pushdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.20210714190141
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
11
- date: 2021-07-14 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIID+DCCAmCgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdnZWQv
14
+ REM9RmFlcmllTVVEL0RDPW9yZzAeFw0yMDEyMjQyMDU1MjlaFw0yMTEyMjQyMDU1
15
+ MjlaMCIxIDAeBgNVBAMMF2dlZC9EQz1GYWVyaWVNVUQvREM9b3JnMIIBojANBgkq
16
+ hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyVhkRzvlEs0fe7145BYLfN6njX9ih5H
17
+ L60U0p0euIurpv84op9CNKF9tx+1WKwyQvQP7qFGuZxkSUuWcP/sFhDXL1lWUuIl
18
+ M4uHbGCRmOshDrF4dgnBeOvkHr1fIhPlJm5FO+Vew8tSQmlDsosxLUx+VB7DrVFO
19
+ 5PU2AEbf04GGSrmqADGWXeaslaoRdb1fu/0M5qfPTRn5V39sWD9umuDAF9qqil/x
20
+ Sl6phTvgBrG8GExHbNZpLARd3xrBYLEFsX7RvBn2UPfgsrtvpdXjsHGfpT3IPN+B
21
+ vQ66lts4alKC69TE5cuKasWBm+16A4aEe3XdZBRNmtOu/g81gvwA7fkJHKllJuaI
22
+ dXzdHqq+zbGZVSQ7pRYHYomD0IiDe1DbIouFnPWmagaBnGHwXkDT2bKKP+s2v21m
23
+ ozilJg4aar2okb/RA6VS87o+d7g6LpDDMMQjH4G9OPnJENLdhu8KnPw/ivSVvQw7
24
+ N2I4L/ZOIe2DIVuYH7aLHfjZDQv/mNgpAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYD
25
+ VR0PBAQDAgSwMB0GA1UdDgQWBBRyjf55EbrHagiRLqt5YAd3yb8k4DANBgkqhkiG
26
+ 9w0BAQsFAAOCAYEAMYegZanJi8zq7QKPT7wqXefX4C88I5JWeBHR3PvvWK0CwyMV
27
+ peyiu5I13w/lYX+HUZjE4qsSpJMJFXWl4WZCOo+AMprOcf0PxfuJpxCej5D4tavf
28
+ vRfhahSw7XJrcZih/3J+/UgoH7R05MJ+8LTcy3HGrB3a0vTafjm8OY7Xpa0LJDoN
29
+ JDqxK321VIHyTibbKeA1hWSE6ljlQDvFbTqiCj3Ulp1jTv3TOlvRl8fqcfhxUJI0
30
+ +5Q82jJODjEN+GaWs0V+NlrbU94cXwS2PH5dXogftB5YYA5Ex8A0ikZ73xns4Hdo
31
+ XxdLdd92F5ovxA23j/rKe/IDwqr6FpDkU3nPXH/Qp0TVGv9zZnVJc/Z6ChkuWj8z
32
+ pW7JAyyiiHZgKKDReDrA2LA7Zs3o/7KA6UtUH0FHf8LYhcK+pfHk6RtjRe65ffw+
33
+ MCh97sQ/Z/MOusb5+QddBmB+k8EicXyGNl4b5L4XpL7fIQu+Y96TB3JEJlShxFD9
34
+ k9FjI4d9EP54gS/4
35
+ -----END CERTIFICATE-----
36
+ date: 2021-09-21 00:00:00.000000000 Z
12
37
  dependencies:
38
+ - !ruby/object:Gem::Dependency
39
+ name: loggability
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '0.18'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: '0.18'
52
+ - !ruby/object:Gem::Dependency
53
+ name: pluggability
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '0.7'
59
+ type: :runtime
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '0.7'
66
+ - !ruby/object:Gem::Dependency
67
+ name: e2mmap
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '0.1'
73
+ type: :runtime
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '0.1'
13
80
  - !ruby/object:Gem::Dependency
14
81
  name: rake-deveiate
15
82
  requirement: !ruby/object:Gem::Requirement
@@ -32,22 +99,38 @@ executables: []
32
99
  extensions: []
33
100
  extra_rdoc_files: []
34
101
  files:
35
- - ".simplecov"
36
102
  - History.md
103
+ - LICENSE.txt
37
104
  - README.md
38
- - Rakefile
39
105
  - lib/pushdown.rb
106
+ - lib/pushdown/automaton.rb
107
+ - lib/pushdown/exceptions.rb
108
+ - lib/pushdown/spec_helpers.rb
109
+ - lib/pushdown/state.rb
110
+ - lib/pushdown/transition.rb
111
+ - lib/pushdown/transition/pop.rb
112
+ - lib/pushdown/transition/push.rb
113
+ - lib/pushdown/transition/replace.rb
114
+ - lib/pushdown/transition/switch.rb
115
+ - spec/pushdown/automaton_spec.rb
116
+ - spec/pushdown/spec_helpers_spec.rb
117
+ - spec/pushdown/state_spec.rb
118
+ - spec/pushdown/transition/pop_spec.rb
119
+ - spec/pushdown/transition/push_spec.rb
120
+ - spec/pushdown/transition/replace_spec.rb
121
+ - spec/pushdown/transition/switch_spec.rb
122
+ - spec/pushdown/transition_spec.rb
40
123
  - spec/pushdown_spec.rb
41
124
  - spec/spec_helper.rb
42
125
  homepage: http://hg.sr.ht/~ged/Pushdown
43
126
  licenses:
44
127
  - BSD-3-Clause
45
128
  metadata:
46
- bug_tracker_uri: http://todo.sr.ht/~ged/Pushdown
47
- changelog_uri: http://deveiate.org/code/pushdown/History_md.html
48
- documentation_uri: http://deveiate.org/code/pushdown
49
129
  homepage_uri: http://hg.sr.ht/~ged/Pushdown
130
+ documentation_uri: http://deveiate.org/code/pushdown
131
+ changelog_uri: http://deveiate.org/code/pushdown/History_md.html
50
132
  source_uri: http://hg.sr.ht/~ged/Pushdown
133
+ bug_tracker_uri: http://todo.sr.ht/~ged/Pushdown
51
134
  post_install_message:
52
135
  rdoc_options: []
53
136
  require_paths:
@@ -59,9 +142,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
59
142
  version: '0'
60
143
  required_rubygems_version: !ruby/object:Gem::Requirement
61
144
  requirements:
62
- - - ">"
145
+ - - ">="
63
146
  - !ruby/object:Gem::Version
64
- version: 1.3.1
147
+ version: '0'
65
148
  requirements: []
66
149
  rubygems_version: 3.1.6
67
150
  signing_key:
metadata.gz.sig ADDED
Binary file
data/.simplecov DELETED
@@ -1,9 +0,0 @@
1
- # Simplecov config
2
-
3
- SimpleCov.start do
4
- add_filter 'spec'
5
- add_filter 'integration'
6
- add_group "Needing tests" do |file|
7
- file.covered_percent < 90
8
- end
9
- end
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby -S rake
2
-
3
- require 'rake/deveiate'
4
-
5
- Rake::DevEiate.setup( 'pushdown' ) do |project|
6
- project.publish_to = 'deveiate:/usr/local/www/public/code'
7
- end
8
-