async-graph 0.1.1 → 0.1.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.
@@ -91,4 +91,156 @@ RSpec.describe AsyncGraph::Graph do
91
91
  expect(step.destinations.map(&:to)).to eq([:done])
92
92
  end
93
93
  end
94
+
95
+ it "validates that an entry point exists before execution" do
96
+ graph = described_class.new do
97
+ node :start do
98
+ end
99
+ end
100
+
101
+ expect do
102
+ graph.step(state: {}, node: :start)
103
+ end.to raise_error(AsyncGraph::ValidationError, /Entry point is not set/)
104
+ end
105
+
106
+ it "validates graph edges before execution" do
107
+ graph = described_class.new do
108
+ node :start do
109
+ end
110
+
111
+ set_entry_point :start
112
+ edge :start, :missing
113
+ end
114
+
115
+ expect do
116
+ graph.step(state: {}, node: graph.entry)
117
+ end.to raise_error(AsyncGraph::ValidationError, /Edge target missing is not defined/)
118
+ end
119
+
120
+ it "rejects duplicate node definitions" do
121
+ expect do
122
+ described_class.new do
123
+ node :start do
124
+ end
125
+
126
+ node :start do
127
+ end
128
+ end
129
+ end.to raise_error(AsyncGraph::ValidationError, /Node start is already defined/)
130
+ end
131
+
132
+ it "parks and releases join tokens inside the library" do
133
+ graph = described_class.new do
134
+ node :left do
135
+ end
136
+
137
+ node :right do
138
+ end
139
+
140
+ node :merge do
141
+ end
142
+
143
+ set_entry_point :left
144
+ edge %i[left right], :merge
145
+ end
146
+
147
+ parked = graph.process_join(
148
+ token: {
149
+ token_uid: "t1.left",
150
+ node: :merge,
151
+ state: {user_id: 7, left_ready: true},
152
+ fork_uid: "fork-1",
153
+ branch: :left,
154
+ source_node: :left,
155
+ awaits: {}
156
+ },
157
+ joins: {}
158
+ )
159
+
160
+ expect(parked).to be_a(AsyncGraph::JoinParked)
161
+ expect(parked.joins.keys).to eq([:'fork-1:merge'])
162
+
163
+ released = graph.process_join(
164
+ token: {
165
+ token_uid: "t1.right",
166
+ node: :merge,
167
+ state: {user_id: 7, right_ready: true},
168
+ fork_uid: "fork-1",
169
+ branch: :right,
170
+ source_node: :right,
171
+ awaits: {}
172
+ },
173
+ joins: parked.joins
174
+ )
175
+
176
+ aggregate_failures do
177
+ expect(released).to be_a(AsyncGraph::JoinReleased)
178
+ expect(released.joins).to eq({})
179
+ expect(released.token.fetch(:token_uid)).to eq("fork-1.join")
180
+ expect(released.token.fetch(:node)).to eq(:merge)
181
+ expect(released.token.fetch(:state)).to eq(
182
+ user_id: 7,
183
+ left_ready: true,
184
+ right_ready: true
185
+ )
186
+ end
187
+ end
188
+
189
+ it "raises when join branches disagree on the same state key" do
190
+ graph = described_class.new do
191
+ node :left do
192
+ end
193
+
194
+ node :right do
195
+ end
196
+
197
+ node :merge do
198
+ end
199
+
200
+ set_entry_point :left
201
+ edge %i[left right], :merge
202
+ end
203
+
204
+ parked = graph.process_join(
205
+ token: {
206
+ token_uid: "t1.left",
207
+ node: :merge,
208
+ state: {shared: 1},
209
+ fork_uid: "fork-1",
210
+ branch: :left,
211
+ source_node: :left,
212
+ awaits: {}
213
+ },
214
+ joins: {}
215
+ )
216
+
217
+ expect do
218
+ graph.process_join(
219
+ token: {
220
+ token_uid: "t1.right",
221
+ node: :merge,
222
+ state: {shared: 2},
223
+ fork_uid: "fork-1",
224
+ branch: :right,
225
+ source_node: :right,
226
+ awaits: {}
227
+ },
228
+ joins: parked.joins
229
+ )
230
+ end.to raise_error(AsyncGraph::JoinConflictError, /shared/)
231
+ end
232
+
233
+ it "validates explicit goto targets when commands are applied" do
234
+ graph = described_class.new do
235
+ node :start do
236
+ AsyncGraph::Command.goto(:missing)
237
+ end
238
+
239
+ set_entry_point :start
240
+ end
241
+
242
+ expect do
243
+ graph.step(state: {}, node: graph.entry)
244
+ end.to raise_error(AsyncGraph::ValidationError, /Goto target missing is not defined/)
245
+ end
94
246
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-graph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Borodkin
@@ -102,6 +102,7 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - ".github/workflows/ci.yml"
105
+ - ".github/workflows/docs.yml"
105
106
  - ".github/workflows/release.yml"
106
107
  - ".gitignore"
107
108
  - ".rspec"
@@ -113,6 +114,7 @@ files:
113
114
  - Rakefile
114
115
  - async-graph.gemspec
115
116
  - bin/console
117
+ - examples/all_in_one_runner.rb
116
118
  - examples/app_graph.rb
117
119
  - examples/execute_jobs.rb
118
120
  - examples/graph_run.rb
@@ -120,6 +122,8 @@ files:
120
122
  - examples/run.sh
121
123
  - lib/async-graph.rb
122
124
  - lib/async-graph/graph.rb
125
+ - lib/async-graph/graph_validation.rb
126
+ - lib/async-graph/runner.rb
123
127
  - lib/async-graph/version.rb
124
128
  - spec/async_graph_spec.rb
125
129
  - spec/spec_helper.rb