y_petri 2.0.7 → 2.0.14.p1

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.
@@ -0,0 +1,153 @@
1
+ #! /usr/bin/ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require_relative '../../lib/y_petri' # tested component itself
7
+ # require 'y_petri'
8
+ # require 'sy'
9
+
10
+ describe "Use of TimedSimulation with units" do
11
+ before do
12
+ require 'sy'
13
+
14
+ @m = YPetri::Manipulator.new
15
+
16
+ # === General assumptions
17
+ Cytoplasm_volume = 5.0e-11.l
18
+ Pieces_per_concentration = SY::Nᴀ * Cytoplasm_volume
19
+
20
+ # === Simulation settings
21
+ @m.set_step 60.s
22
+ @m.set_target_time 10.min
23
+ @m.set_sampling 120.s
24
+
25
+ # === Places
26
+ AMP = @m.Place m!: 8695.0.µM
27
+ ADP = @m.Place m!: 6521.0.µM
28
+ ATP = @m.Place m!: 3152.0.µM
29
+ Deoxycytidine = @m.Place m!: 0.5.µM
30
+ DeoxyCTP = @m.Place m!: 1.0.µM
31
+ DeoxyGMP = @m.Place m!: 1.0.µM
32
+ U12P = @m.Place m!: 2737.0.µM
33
+ DeoxyU12P = @m.Place m!: 0.0.µM
34
+ DeoxyTMP = @m.Place m!: 3.3.µM
35
+ DeoxyT23P = @m.Place m!: 5.0.µM
36
+ Thymidine = @m.Place m!: 0.5.µM
37
+ TK1 = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
38
+ TYMS = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
39
+ RNR = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
40
+ TMPK = @m.Place m!: 100_000.unit.( SY::MoleAmount ) / Cytoplasm_volume
41
+
42
+ # === Enzyme molecular masses
43
+ TK1_m = 24.8.kDa
44
+ TYMS_m = 66.0.kDa
45
+ RNR_m = 140.0.kDa
46
+ TMPK_m = 50.0.kDa
47
+
48
+ # === Specific activities of the enzymes
49
+ TK1_a = 5.40.µmol.min⁻¹.mg⁻¹
50
+ TYMS_a = 3.80.µmol.min⁻¹.mg⁻¹
51
+ RNR_a = 1.00.µmol.min⁻¹.mg⁻¹
52
+ TMPK_a = 0.83.µmol.min⁻¹.mg⁻¹
53
+
54
+ # === Clamps
55
+ @m.clamp AMP: 8695.0.µM, ADP: 6521.0.µM, ATP: 3152.0.µM
56
+ @m.clamp Deoxycytidine: 0.5.µM, DeoxyCTP: 1.0.µM, DeoxyGMP: 1.0.µM
57
+ @m.clamp Thymidine: 0.5.µM
58
+ @m.clamp U12P: 2737.0.µM
59
+
60
+ # === Function closures
61
+
62
+ # Vmax of an enzyme.
63
+ #
64
+ Vmax_enzyme = lambda { |specific_activity, mass, enzyme_conc|
65
+ specific_activity * mass * enzyme_conc.( SY::Molecularity )
66
+ }
67
+
68
+ # Michaelis constant reduced for competitive inhibitors.
69
+ #
70
+ Km_reduced = lambda { |km, ki_hash={}|
71
+ ki_hash.map { |concentration, ci_Ki|
72
+ concentration / ci_Ki }
73
+ .reduce( 1, :+ ) * km
74
+ }
75
+
76
+ # Occupancy of enzyme active sites at given concentration of reactants
77
+ # and competitive inhibitors.
78
+ #
79
+ Occupancy = lambda { |ʀ_conc, ʀ_Km, cɪ_Kɪ={}|
80
+ ʀ_conc / ( ʀ_conc + Km_reduced.( ʀ_Km, cɪ_Kɪ ) )
81
+ }
82
+
83
+ # Michaelis and Menten equation with competitive inhibitors.
84
+ #
85
+ MMi = MM_equation_with_inhibitors = lambda {
86
+ |ʀ_conc, ᴇ_specific_activity, ᴇ_mass, ᴇ_conc, ʀ_Km, cɪ_Kɪ={}|
87
+ Vmax_enzyme.( ᴇ_specific_activity, ᴇ_mass, ᴇ_conc ) *
88
+ Occupancy.( ʀ_conc, ʀ_Km, cɪ_Kɪ )
89
+ }
90
+
91
+ # === Michaelis constants of the enzymes involved.
92
+
93
+ TK1_Thymidine_Km = 5.0.µM
94
+ TYMS_DeoxyUMP_Km = 2.0.µM
95
+ RNR_UDP_Km = 1.0.µM
96
+ TMPK_DeoxyTMP_Km = 12.0.µM
97
+
98
+ # === DNA synthesis speed.
99
+
100
+ DNA_creation_speed = 3_000_000_000.unit.( SY::MoleAmount ) / 12.h / Cytoplasm_volume
101
+
102
+ # === Transitions
103
+
104
+ # Synthesis of TMP by TK1.
105
+ #
106
+ TK1_Thymidine_DeoxyTMP = @m.Transition s: { Thymidine: -1, DeoxyTMP: 1 },
107
+ domain: [ Thymidine, TK1, DeoxyT23P, DeoxyCTP, Deoxycytidine, AMP, ADP, ATP ],
108
+ rate: proc { |rc, e, pool1, ci2, ci3, master1, master2, master3|
109
+ ci1 = pool1 * master3 / ( master2 + master3 )
110
+ MMi.( rc, TK1_a, TK1_m, e, TK1_Thymidine_Km,
111
+ ci1 => 13.5.µM, ci2 => 0.8.µM, ci3 => 40.0.µM )
112
+ }
113
+
114
+ # Methylation of DeoxyUMP into TMP by TYMS.
115
+ TYMS_DeoxyUMP_DeoxyTMP = @m.Transition s: { DeoxyU12P: -1, DeoxyTMP: 1 },
116
+ domain: [ DeoxyU12P, TYMS, AMP, ADP, ATP ],
117
+ rate: proc { |pool, e, master1, master2, master3|
118
+ rc = pool * master2 / ( master1 + master2 )
119
+ MMi.( rc, TYMS_a, TYMS_m, e, TYMS_DeoxyUMP_Km )
120
+ }
121
+
122
+ # Reduction of UDP into DeoxyUDP by RNR.
123
+ RNR_UDP_DeoxyUDP = @m.Transition s: { U12P: -1, DeoxyU12P: 1 },
124
+ domain: [ U12P, RNR, DeoxyU12P, AMP, ADP, ATP ],
125
+ rate: proc { |pool, e, master1, master2, master3|
126
+ rc = pool * master2 / ( master1 + master2 )
127
+ MMi.( rc, RNR_a, RNR_m, e, RNR_UDP_Km )
128
+ }
129
+
130
+ # Consumption of TTP by DNA synthesis.
131
+ DeoxyTTP_to_DNA = @m.Transition s: { DeoxyT23P: -1 },
132
+ rate: proc { DNA_creation_speed / 4 }
133
+
134
+ # Phosphorylation of TMP into TDP-TTP pool.
135
+ TMPK_DeoxyTMP_DeoxyTDP = @m.Transition s: { DeoxyTMP: -1, TMPK: 0, DeoxyT23P: 1 },
136
+ domain: [ DeoxyTMP, TMPK, ADP, DeoxyT23P, DeoxyGMP, AMP, ATP ],
137
+ rate: proc { |rc, e, ci1, pool, ci4, master1, master3|
138
+ master2 = ci1
139
+ ci2 = pool * master2 / ( master2 + master3 )
140
+ ci3 = pool * master3 / ( master2 + master3 )
141
+ MMi.( rc, TMPK_a, TMPK_m, e, TMPK_DeoxyTMP_Km,
142
+ ci1 => 250.0.µM, ci2 => 30.0.µM, ci3 => 750.µM, ci4 => 117.µM )
143
+ }
144
+ end
145
+
146
+ it "should work" do
147
+ # === Simulation execution
148
+ @m.run!
149
+ # === Plotting of the results
150
+ @m.plot_state
151
+ sleep 20
152
+ end
153
+ end
@@ -0,0 +1,36 @@
1
+ #! /usr/bin/ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require_relative '../../lib/y_petri' # tested component itself
7
+ # require 'y_petri'
8
+ # require 'sy'
9
+
10
+ describe "Token game" do
11
+ before do
12
+ @m = YPetri::Manipulator.new
13
+ @m.Place name: "A"
14
+ @m.Place name: "B"
15
+ @m.Place name: "C", marking: 7.77
16
+ @m.Transition name: "A2B", stoichiometry: { A: -1, B: 1 }
17
+ @m.Transition name: "C_decay", stoichiometry: { C: -1 }, rate: 0.05
18
+ end
19
+
20
+ it "should work" do
21
+ @m.place( :A ).marking = 2
22
+ @m.place( :B ).marking = 5
23
+ @m.places.map( &:name ).must_equal [:A, :B, :C]
24
+ @m.places.map( &:marking ).must_equal [2, 5, 7.77]
25
+ @m.transition( :A2B ).arcs.must_equal [ @m.place( :A ), @m.place( :B ) ]
26
+ @m.transition( :A2B ).fire!
27
+ @m.places.map( &:marking ).must_equal [1, 6, 7.77]
28
+ @m.transition( :A2B ).fire!
29
+ @m.place( :A ).marking.must_equal 0
30
+ @m.place( :B ).marking.must_equal 7
31
+ 2.times do @m.transition( :C_decay ).fire! 1 end
32
+ @m.transition( :C_decay ).fire! 0.1
33
+ 200.times do @m.transition( :C_decay ).fire! 1 end
34
+ assert_in_delta @m.place( :C ).marking, 0.00024, 0.00001
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ #! /usr/bin/ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require_relative '../../lib/y_petri' # tested component itself
7
+ # require 'y_petri'
8
+ # require 'sy'
9
+
10
+ describe "Graphviz visualization" do
11
+ before do
12
+ @m = YPetri::Manipulator.new
13
+ @m.Place name: :A, m!: 1
14
+ @m.Place name: :B, m!: 1.5
15
+ @m.Place name: :C, m!: 2
16
+ @m.Place name: :D, m!: 2.5
17
+ @m.Transition name: :A_pump, s: { A: -1 }, rate: proc { 0.005 }
18
+ @m.Transition name: :B_decay, s: { B: -1 }, rate: 0.05
19
+ @m.Transition name: :C_guard, assignment: true, codomain: :C, action: -> { 2 }
20
+ end
21
+
22
+ it "should work" do
23
+ @m.net.visualize
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ #! /usr/bin/ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require_relative '../lib/y_petri' # tested component itself
7
+ # require 'y_petri'
8
+ # require 'sy'
9
+
10
+ require_relative 'acceptance/token_game_test'
11
+ require_relative 'acceptance/basic_usage_test'
12
+ require_relative 'acceptance/simulation_test'
13
+ require_relative 'acceptance/visualization_test'
14
+ require_relative 'acceptance/simulation_with_physical_units_test'
@@ -0,0 +1,100 @@
1
+ #! /usr/bin/ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require_relative '../lib/y_petri' # tested component itself
7
+ # require 'y_petri'
8
+ # require 'sy'
9
+
10
+ describe ::YPetri::Manipulator do
11
+ before do
12
+ @m = ::YPetri::Manipulator.new
13
+ end
14
+
15
+ it "has net basic points" do
16
+ # --- net point related assets ---
17
+ @m.net_point_reset
18
+ @m.net_point_set @m.workspace.net( :Top )
19
+ @m.net.must_equal @m.workspace.Net::Top
20
+ # --- simulation point related assets ---
21
+ @m.simulation_point.reset
22
+ @m.simulation.must_equal nil
23
+ @m.simulation_point.key.must_equal nil
24
+ # --- cc point related assets ---
25
+ @m.cc_point.reset
26
+ @m.cc_point.set :Base
27
+ @m.cc.must_equal @m.workspace.clamp_collection
28
+ @m.cc.wont_equal :Base
29
+ @m.cc_point.key.must_equal :Base
30
+ # --- imc point related assets ---
31
+ @m.imc_point.reset
32
+ @m.imc_point.set :Base
33
+ @m.imc.must_equal @m.workspace.initial_marking_collection
34
+ @m.imc.wont_equal :Base
35
+ @m.imc_point.key.must_equal :Base
36
+ # --- ssc point related assets ---
37
+ @m.ssc_point.reset
38
+ @m.ssc_point.set :Base
39
+ @m.ssc.must_equal @m.workspace.simulation_settings_collection
40
+ @m.ssc.wont_equal :Base
41
+ @m.ssc_point.key.must_equal :Base
42
+ end
43
+
44
+ it "has basic selections" do
45
+ @m.net_selection.clear
46
+ @m.simulation_selection.clear
47
+ @m.cc_selection.clear
48
+ @m.imc_selection.clear
49
+ @m.ssc_selection.clear
50
+ @m.net_selection.get.must_equal []
51
+ @m.simulation_selection.get.must_equal []
52
+ @m.ssc_selection.get.must_equal []
53
+ @m.cc_selection.get.must_equal []
54
+ @m.imc_selection.get.must_equal []
55
+ end
56
+
57
+ it "presents some methods from workspace" do
58
+ [ @m.places, @m.transitions, @m.nets, @m.simulations ].map( &:size )
59
+ .must_equal [ 0, 0, 1, 0 ]
60
+ [ @m.clamp_collections,
61
+ @m.initial_marking_collections,
62
+ @m.simulation_settings_collections ].map( &:size ).must_equal [ 1, 1, 1 ]
63
+ [ @m.clamp_collections,
64
+ @m.initial_marking_collections,
65
+ @m.simulation_settings_collections ]
66
+ .map( &:keys ).must_equal [[:Base]] * 3
67
+ @m.pp.must_equal []
68
+ @m.tt.must_equal []
69
+ @m.nn.must_equal [ :Top ] # ie. :Top net spanning whole workspace
70
+ end
71
+
72
+ describe "slightly more complicated case" do
73
+ before do
74
+ @p = @m.Place ɴ: "P", default_marking: 1
75
+ @q = @m.Place ɴ: "Q", default_marking: 1
76
+ @decay_t = @m.Transition ɴ: "Tp", s: { P: -1 }, rate: 0.1
77
+ @constant_flux_t = @m.Transition ɴ: "Tq", s: { Q: 1 }, rate: -> { 0.02 }
78
+ @m.initial_marking @p => 1.2
79
+ @m.initial_marking @q => 2
80
+ @m.set_step 0.01
81
+ @m.set_sampling 1
82
+ @m.set_time 30
83
+ end
84
+
85
+ it "works" do
86
+ @m.run!
87
+ @m.simulation.places.must_equal [ @p, @q ]
88
+ @m.simulation.transitions.must_equal [ @decay_t, @constant_flux_t ]
89
+ @m.simulation.SR_tt.must_equal [ :Tp, :Tq ]
90
+ @m.simulation.sparse_stoichiometry_vector( :Tp )
91
+ .must_equal Matrix.column_vector( [-1, 0] )
92
+ @m.simulation.stoichiometry_matrix_for( @m.transitions ).column_size
93
+ .must_equal 2
94
+ @m.simulation.stoichiometry_matrix_for( @m.transitions ).row_size
95
+ .must_equal 2
96
+ @m.simulation.flux_vector.row_size.must_equal 2
97
+ # @m.plot_recording
98
+ end
99
+ end
100
+ end
data/test/net_test.rb ADDED
@@ -0,0 +1,171 @@
1
+ #! /usr/bin/ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require_relative '../lib/y_petri' # tested component itself
7
+ # require 'y_petri'
8
+ # require 'sy'
9
+
10
+ describe YPetri::Net do
11
+ before do
12
+ @tç = tç = Class.new YPetri::Transition
13
+ @pç = pç = Class.new YPetri::Place
14
+ @nç = nç = Class.new YPetri::Net
15
+ [ tç, pç, nç ].each { |ç|
16
+ ç.namespace!.class_exec {
17
+ define_method :Place do pç end
18
+ define_method :Transition do tç end
19
+ define_method :Net do nç end
20
+ private :Place, :Transition, :Net
21
+ }
22
+ }
23
+ @p1 = pç.new ɴ: "A", quantum: 0.1, marking: 1.1
24
+ @p2 = pç.new ɴ: "B", quantum: 0.1, marking: 2.2
25
+ @p3 = pç.new ɴ: "C", quantum: 0.1, marking: 3.3
26
+ @net = nç.new
27
+ [@p1, @p2, @p3].each { |p| @net.include_place! p }
28
+ @p_not_included = pç.new ɴ: "X", marking: 0
29
+ end
30
+
31
+ describe "net of 3 places and no transitions" do
32
+ before do
33
+ @p1.m = 1.1
34
+ @p2.m = 2.2
35
+ @p3.m = 3.3
36
+ end
37
+
38
+ it "should expose its elements" do
39
+ assert_equal [@p1, @p2, @p3], @net.places
40
+ assert_equal [:A, :B, :C], @net.pp
41
+ assert_equal [], @net.transitions
42
+ end
43
+
44
+ it "should expose transition groups" do
45
+ assert_equal [], @net.transitions_with_rate
46
+ assert_equal [], @net.rateless_transitions
47
+ assert_equal [], @net.transitions_without_rate
48
+ assert_equal [], @net.stoichiometric_transitions
49
+ assert_equal [], @net.nonstoichiometric_transitions
50
+ end
51
+
52
+ it "should tell its qualities" do
53
+ assert_equal true, @net.functional?
54
+ assert_equal true, @net.timed?
55
+ assert @net.include?( @p1 ) && !@net.include?( YPetri::Place.new )
56
+ end
57
+
58
+ it "should have 'standard equipment' methods" do
59
+ assert @net == @net.dup
60
+ assert @net.inspect.start_with? "#<Net:"
61
+ assert @net.include?( @p1 )
62
+ assert ! @net.include?( @p_not_included )
63
+ begin
64
+ @net.exclude_place! @p_not_included
65
+ @net.include_transition! YPetri::Transition.new( s: { @p_not_included => -1 } )
66
+ flunk "Attempt to include illegal transition fails to raise"
67
+ rescue; end
68
+ end
69
+
70
+ describe "plus 1 stoichio. transition with rate" do
71
+ before do
72
+ @t1 = @tç.new!( ɴ: "T1",
73
+ s: { @p1 => 1, @p2 => -1, @p3 => -1 },
74
+ rate: 0.01 )
75
+ @net.include_transition! @t1
76
+ end
77
+
78
+ it "should expose its elements" do
79
+ assert_equal [@t1], @net.transitions
80
+ assert_equal [:T1], @net.tt
81
+ end
82
+
83
+ it "should expose transition groups" do
84
+ assert_equal true, @t1.has_rate?
85
+ assert_equal [@t1], @net.transitions_with_rate
86
+ assert_equal [], @net.rateless_transitions
87
+ assert_equal [@t1], @net.stoichiometric_transitions
88
+ assert_equal [], @net.nonstoichiometric_transitions
89
+ end
90
+
91
+ it "should tell its qualities" do
92
+ assert_equal true, @net.functional?
93
+ assert_equal true, @net.timed?
94
+ assert @net.include?( @t1 )
95
+ end
96
+
97
+ it "should have #place & #transition for safe access to the said elements" do
98
+ @net.send( :place, @p1 ).must_equal @p1
99
+ @net.send( :transition, @t1 ).must_equal @t1
100
+ end
101
+
102
+ it "has #new_simulation & #new_timed_simulation constructors" do
103
+ @net.must_respond_to :new_simulation
104
+ @net.must_respond_to :new_timed_simulation
105
+ end
106
+
107
+ it "should have other methods" do
108
+ assert_equal [1.1, 2.2, 3.3], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
109
+ assert_equal 2.2 * 3.3 * 0.01, @t1.rate_closure.call( @p2.marking, @p3.marking )
110
+ assert_equal [ @p2, @p3 ], @t1.domain
111
+ @t1.fire! 1
112
+ assert_equal [1.1726, 2.1274, 3.2274], [@p1, @p2, @p3].map( &:marking ).map{ |n| n.round 6 }
113
+ end
114
+
115
+ describe "plus 1 more nameless timeless functionless transition" do
116
+ before do
117
+ @t2 = @tç.new s: { @p2 => -1, @p3 => 1 }
118
+ @net.include_transition! @t2
119
+ end
120
+
121
+ it "should expose its elements" do
122
+ assert_equal [@t1, @t2], @net.transitions
123
+ assert_equal [:T1, nil], @net.tt
124
+ @net.tap{ |n| n.exclude_transition! @t1 }.exclude_transition! @t2
125
+ @net.tap{ |n| n.exclude_place! @p3 }.pp.must_equal [:A, :B]
126
+ end
127
+
128
+ it "should expose transition groups" do
129
+ assert_equal [], @net.timeless_nonstoichiometric_transitions
130
+ assert_equal [], @net.timeless_nonstoichiometric_tt
131
+ assert_equal [@t2], @net.timeless_stoichiometric_transitions
132
+ assert_equal [nil], @net.timeless_stoichiometric_tt
133
+ assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
134
+ assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
135
+ assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
136
+ assert_equal [], @net.timed_rateless_nonstoichiometric_tt
137
+ assert_equal [], @net.timed_nonstoichiometric_transitions_without_rate
138
+ assert_equal [], @net.timed_rateless_nonstoichiometric_transitions
139
+ assert_equal [], @net.timed_nonstoichiometric_tt_without_rate
140
+ assert_equal [], @net.timed_rateless_nonstoichiometric_tt
141
+ assert_equal [], @net.nonstoichiometric_transitions_with_rate
142
+ assert_equal [], @net.nonstoichiometric_tt_with_rate
143
+ assert_equal [@t1], @net.stoichiometric_transitions_with_rate
144
+ assert_equal [:T1], @net.stoichiometric_tt_with_rate
145
+ assert_equal [], @net.assignment_transitions
146
+ assert_equal [], @net.assignment_tt
147
+ assert_equal [@t1, @t2], @net.stoichiometric_transitions
148
+ assert_equal [:T1, nil], @net.stoichiometric_tt
149
+ assert_equal [], @net.nonstoichiometric_transitions
150
+ assert_equal [], @net.nonstoichiometric_tt
151
+ assert_equal [@t1], @net.timed_transitions
152
+ assert_equal [:T1], @net.timed_tt
153
+ assert_equal [@t2], @net.timeless_transitions
154
+ assert_equal [nil], @net.timeless_tt
155
+ assert_equal [@t1], @net.transitions_with_rate
156
+ assert_equal [:T1], @net.tt_with_rate
157
+ assert_equal [@t2], @net.rateless_transitions
158
+ assert_equal [nil], @net.rateless_tt
159
+ end
160
+
161
+ it "should tell its qualities" do
162
+ assert_equal false, @net.functional?
163
+ assert_equal false, @net.timed?
164
+ @net.exclude_transition! @t2
165
+ assert_equal true, @net.functional?
166
+ assert_equal true, @net.timed?
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
data/test/place_test.rb CHANGED
@@ -66,18 +66,19 @@ describe YPetri::Place do
66
66
  end
67
67
 
68
68
  it "should have guard mechanics" do
69
- @p.guards.size.must_equal 2 # working automatic guard construction
69
+ @p.guards.size.must_equal 3 # working automatic guard construction
70
70
  g1, g2 = @p.guards
71
- g1.assertion.must_include "number"
72
- g2.assertion.must_include "complex"
71
+ [g1.assertion, g2.assertion].tap { |u, v|
72
+ assert u.include?( "number" ) || u.include?( "Numeric" )
73
+ assert v.include?( "complex" ) || v.include?( "Complex" )
74
+ }
73
75
  begin; g1.validate 11.1; g2.validate 11.1; @p.guard.( 11.1 ); :nothing_raised
74
76
  rescue; :error end.must_equal :nothing_raised
75
77
  -> { g2.validate Complex( 1, 1 ) }.must_raise YPetri::GuardError
76
78
  @p.marking "must be in 0..10" do |m| fail unless ( 0..10 ) === m end
77
- @p.guards.size.must_equal 3
79
+ @p.guards.size.must_equal 4
78
80
  g = @p.federated_guard_closure
79
81
  -> { g.( 11.1 ) }.must_raise YPetri::GuardError
80
- @p.marking = -1.11
81
- -> { @p.guard! }.must_raise YPetri::GuardError
82
+ -> { @p.marking = -1.11 }.must_raise YPetri::GuardError
82
83
  end
83
84
  end