dev_suite 0.2.7 → 0.2.10
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 +4 -4
- data/.codeclimate.yml +12 -0
- data/.github/workflows/ci.yml +1 -1
- data/.sonarcloud.properties +23 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +17 -33
- data/README.md +216 -0
- data/dev_suite.gemspec +1 -0
- data/examples/helpers/api_helper.rb +51 -0
- data/examples/helpers/data_helper.rb +72 -0
- data/examples/helpers/helpers.rb +4 -0
- data/examples/workflow/basic_workflow.rb +15 -0
- data/examples/workflow/composite_workflow.rb +21 -0
- data/examples/workflow/conditional_workflow.rb +17 -0
- data/examples/workflow/full_workflow.rb +79 -0
- data/examples/workflow/loop_workflow.rb +17 -0
- data/examples/workflow/order_processing_workflow.rb +163 -0
- data/examples/workflow/parallel_workflow.rb +17 -0
- data/lib/dev_suite/dev_suite.rb +3 -0
- data/lib/dev_suite/method_tracer/config/config.rb +11 -0
- data/lib/dev_suite/method_tracer/config/configuration.rb +16 -0
- data/lib/dev_suite/method_tracer/config.rb +9 -0
- data/lib/dev_suite/method_tracer/helpers.rb +41 -0
- data/lib/dev_suite/method_tracer/logger.rb +46 -0
- data/lib/dev_suite/method_tracer/method_tracer.rb +20 -0
- data/lib/dev_suite/method_tracer/tracer.rb +65 -0
- data/lib/dev_suite/method_tracer.rb +7 -0
- data/lib/dev_suite/request_builder/builder/base.rb +27 -0
- data/lib/dev_suite/request_builder/builder/builder.rb +10 -0
- data/lib/dev_suite/request_builder/builder/http.rb +32 -0
- data/lib/dev_suite/request_builder/builder.rb +9 -0
- data/lib/dev_suite/request_builder/config/config.rb +11 -0
- data/lib/dev_suite/request_builder/config/configuration.rb +24 -0
- data/lib/dev_suite/request_builder/config.rb +9 -0
- data/lib/dev_suite/request_builder/formatter/base.rb +13 -0
- data/lib/dev_suite/request_builder/formatter/formatter.rb +10 -0
- data/lib/dev_suite/request_builder/formatter/graphql.rb +19 -0
- data/lib/dev_suite/request_builder/formatter.rb +9 -0
- data/lib/dev_suite/request_builder/request_builder.rb +21 -0
- data/lib/dev_suite/request_builder/tool/base.rb +19 -0
- data/lib/dev_suite/request_builder/tool/curl.rb +91 -0
- data/lib/dev_suite/request_builder/tool/tool.rb +11 -0
- data/lib/dev_suite/request_builder/tool/validator/curl.rb +38 -0
- data/lib/dev_suite/request_builder/tool/validator/validator.rb +11 -0
- data/lib/dev_suite/request_builder/tool/validator.rb +11 -0
- data/lib/dev_suite/request_builder/tool.rb +9 -0
- data/lib/dev_suite/request_builder.rb +7 -0
- data/lib/dev_suite/request_logger/adapter/adapter.rb +11 -9
- data/lib/dev_suite/request_logger/adapter/faraday.rb +12 -1
- data/lib/dev_suite/request_logger/adapter/middleware/faraday.rb +3 -3
- data/lib/dev_suite/request_logger/adapter/net_http.rb +15 -6
- data/lib/dev_suite/request_logger/config/configuration.rb +1 -0
- data/lib/dev_suite/request_logger/extractor/base.rb +8 -2
- data/lib/dev_suite/request_logger/extractor/extractor.rb +5 -6
- data/lib/dev_suite/request_logger/extractor/faraday.rb +32 -14
- data/lib/dev_suite/request_logger/extractor/net_http.rb +53 -12
- data/lib/dev_suite/request_logger/logger.rb +9 -3
- data/lib/dev_suite/request_logger/request.rb +12 -0
- data/lib/dev_suite/request_logger/response.rb +34 -9
- data/lib/dev_suite/utils/construct/component/base.rb +13 -0
- data/lib/dev_suite/utils/construct/component/component.rb +1 -0
- data/lib/dev_suite/utils/construct/component/manager.rb +27 -10
- data/lib/dev_suite/utils/construct/component/validator/base.rb +25 -0
- data/lib/dev_suite/utils/construct/component/validator/validation_error.rb +21 -0
- data/lib/dev_suite/utils/construct/component/validator/validation_rule.rb +68 -0
- data/lib/dev_suite/utils/construct/component/validator/validator.rb +15 -0
- data/lib/dev_suite/utils/construct/component/validator.rb +13 -0
- data/lib/dev_suite/utils/construct/config/dependency_handler.rb +25 -34
- data/lib/dev_suite/utils/construct/config/settings/base.rb +43 -26
- data/lib/dev_suite/utils/data/base_operations.rb +61 -0
- data/lib/dev_suite/utils/data/data.rb +19 -0
- data/lib/dev_suite/utils/data/path_access.rb +172 -0
- data/lib/dev_suite/utils/data/search_filter.rb +60 -0
- data/lib/dev_suite/utils/data/serialization.rb +29 -0
- data/lib/dev_suite/utils/data/transformations.rb +45 -0
- data/lib/dev_suite/utils/data.rb +9 -0
- data/lib/dev_suite/utils/dependency_loader.rb +2 -2
- data/lib/dev_suite/utils/emoji.rb +19 -0
- data/lib/dev_suite/utils/file_loader/file_loader.rb +1 -5
- data/lib/dev_suite/utils/file_loader/loader/json.rb +4 -1
- data/lib/dev_suite/utils/file_loader/loader/loader.rb +23 -19
- data/lib/dev_suite/utils/file_loader/loader.rb +0 -2
- data/lib/dev_suite/utils/file_writer/atomic_writer.rb +53 -0
- data/lib/dev_suite/utils/file_writer/backup_manager.rb +21 -0
- data/lib/dev_suite/utils/file_writer/file_writer.rb +24 -0
- data/lib/dev_suite/utils/file_writer/writer/base.rb +43 -0
- data/lib/dev_suite/utils/file_writer/writer/json.rb +24 -0
- data/lib/dev_suite/utils/file_writer/writer/text.rb +27 -0
- data/lib/dev_suite/utils/file_writer/writer/writer.rb +14 -0
- data/lib/dev_suite/utils/file_writer/writer/yaml.rb +44 -0
- data/lib/dev_suite/utils/file_writer/writer.rb +11 -0
- data/lib/dev_suite/utils/file_writer/writer_manager.rb +32 -0
- data/lib/dev_suite/utils/file_writer.rb +9 -0
- data/lib/dev_suite/utils/logger.rb +7 -5
- data/lib/dev_suite/utils/store/config/config.rb +13 -0
- data/lib/dev_suite/utils/store/config/configuration.rb +30 -0
- data/lib/dev_suite/utils/store/config.rb +11 -0
- data/lib/dev_suite/utils/store/driver/base.rb +35 -0
- data/lib/dev_suite/utils/store/driver/driver.rb +18 -0
- data/lib/dev_suite/utils/store/driver/file.rb +61 -0
- data/lib/dev_suite/utils/store/driver/memory.rb +42 -0
- data/lib/dev_suite/utils/store/driver.rb +11 -0
- data/lib/dev_suite/utils/store/store.rb +69 -0
- data/lib/dev_suite/utils/store.rb +9 -0
- data/lib/dev_suite/utils/utils.rb +17 -5
- data/lib/dev_suite/utils/warning_handler.rb +25 -0
- data/lib/dev_suite/version.rb +1 -1
- data/lib/dev_suite/workflow/engine.rb +27 -0
- data/lib/dev_suite/workflow/step/base.rb +56 -0
- data/lib/dev_suite/workflow/step/composite.rb +27 -0
- data/lib/dev_suite/workflow/step/conditional.rb +23 -0
- data/lib/dev_suite/workflow/step/loop.rb +21 -0
- data/lib/dev_suite/workflow/step/parallel.rb +18 -0
- data/lib/dev_suite/workflow/step/step.rb +21 -0
- data/lib/dev_suite/workflow/step.rb +9 -0
- data/lib/dev_suite/workflow/step_context.rb +46 -0
- data/lib/dev_suite/workflow/workflow.rb +39 -0
- data/lib/dev_suite/workflow.rb +7 -0
- metadata +101 -3
- data/lib/dev_suite/utils/construct/component/initializer.rb +0 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 92ff382f54afdf8f68f1f3d5f2f3bec8c496138b0af875b0970b2cceaec24e36
|
|
4
|
+
data.tar.gz: 743a74d46e4448c8e363d7b00e501bd1b2740eb5a10eb1bd019432cb01afd4ea
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7dffd5d2cf8ca2f1712e4e9599e5432666e654a8b6c5696fc185a7898342f574018c2d1311fd96a832a956f4c3aacf1023a7c3ffd83523c3094fb8823b3133f2
|
|
7
|
+
data.tar.gz: db80d0b5c8d9f425ac520b59b6b0988bf5dabadaaaff2647312511aa47bb5eaf738661ec6efe6253028d031baedd49012b910cd0bda65dac6872eaa7c314affe
|
data/.codeclimate.yml
ADDED
data/.github/workflows/ci.yml
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Project identification
|
|
2
|
+
sonar.projectKey=patrick204nqh_dev_suite
|
|
3
|
+
# sonar.organization=
|
|
4
|
+
|
|
5
|
+
# Source code encoding
|
|
6
|
+
sonar.sourceEncoding=UTF-8
|
|
7
|
+
|
|
8
|
+
# Sources and tests
|
|
9
|
+
sonar.sources=lib,exe
|
|
10
|
+
sonar.tests=spec
|
|
11
|
+
|
|
12
|
+
# Paths to coverage reports
|
|
13
|
+
# sonar.ruby.coverage.reportPaths=coverage/.resultset.json
|
|
14
|
+
# sonar.testExecutionReportPaths=coverage/test-reports
|
|
15
|
+
|
|
16
|
+
# Exclusions
|
|
17
|
+
# sonar.exclusions=log/**, tmp/**, node_modules/**
|
|
18
|
+
|
|
19
|
+
# Language specific settings
|
|
20
|
+
sonar.language=ruby
|
|
21
|
+
|
|
22
|
+
# Specify the main branch
|
|
23
|
+
sonar.branch.name=master
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
dev_suite (0.2.
|
|
4
|
+
dev_suite (0.2.10)
|
|
5
5
|
benchmark (~> 0.1)
|
|
6
|
+
csv (~> 3.0)
|
|
6
7
|
get_process_mem (~> 1.0)
|
|
7
8
|
thor (~> 1.1)
|
|
8
9
|
|
|
@@ -13,9 +14,13 @@ GEM
|
|
|
13
14
|
benchmark (0.3.0)
|
|
14
15
|
bigdecimal (3.1.8)
|
|
15
16
|
coderay (1.1.3)
|
|
17
|
+
concurrent-ruby (1.3.4)
|
|
18
|
+
csv (3.3.0)
|
|
16
19
|
diff-lcs (1.5.1)
|
|
17
20
|
docile (1.4.1)
|
|
18
|
-
|
|
21
|
+
faker (2.23.0)
|
|
22
|
+
i18n (>= 1.8.11, < 2)
|
|
23
|
+
faraday (1.10.4)
|
|
19
24
|
faraday-em_http (~> 1.0)
|
|
20
25
|
faraday-em_synchrony (~> 1.0)
|
|
21
26
|
faraday-excon (~> 1.1)
|
|
@@ -38,26 +43,18 @@ GEM
|
|
|
38
43
|
faraday-patron (1.0.0)
|
|
39
44
|
faraday-rack (1.0.0)
|
|
40
45
|
faraday-retry (1.0.3)
|
|
41
|
-
ffi (1.17.0)
|
|
42
|
-
ffi (1.17.0-aarch64-linux-gnu)
|
|
43
|
-
ffi (1.17.0-aarch64-linux-musl)
|
|
44
|
-
ffi (1.17.0-arm-linux-gnu)
|
|
45
|
-
ffi (1.17.0-arm-linux-musl)
|
|
46
46
|
ffi (1.17.0-arm64-darwin)
|
|
47
|
-
ffi (1.17.0-x86-linux-gnu)
|
|
48
|
-
ffi (1.17.0-x86-linux-musl)
|
|
49
|
-
ffi (1.17.0-x86_64-darwin)
|
|
50
|
-
ffi (1.17.0-x86_64-linux-gnu)
|
|
51
|
-
ffi (1.17.0-x86_64-linux-musl)
|
|
52
47
|
get_process_mem (1.0.0)
|
|
53
48
|
bigdecimal (>= 2.0)
|
|
54
49
|
ffi (~> 1.0)
|
|
50
|
+
i18n (1.14.5)
|
|
51
|
+
concurrent-ruby (~> 1.0)
|
|
55
52
|
json (2.7.2)
|
|
56
53
|
language_server-protocol (3.17.0.3)
|
|
57
54
|
method_source (1.1.0)
|
|
58
55
|
multipart-post (2.4.1)
|
|
59
|
-
parallel (1.
|
|
60
|
-
parser (3.3.
|
|
56
|
+
parallel (1.26.3)
|
|
57
|
+
parser (3.3.5.0)
|
|
61
58
|
ast (~> 2.4.1)
|
|
62
59
|
racc
|
|
63
60
|
pry (0.14.2)
|
|
@@ -67,8 +64,6 @@ GEM
|
|
|
67
64
|
rainbow (3.1.1)
|
|
68
65
|
rake (13.2.1)
|
|
69
66
|
regexp_parser (2.9.2)
|
|
70
|
-
rexml (3.3.6)
|
|
71
|
-
strscan
|
|
72
67
|
rspec (3.13.0)
|
|
73
68
|
rspec-core (~> 3.13.0)
|
|
74
69
|
rspec-expectations (~> 3.13.0)
|
|
@@ -82,18 +77,17 @@ GEM
|
|
|
82
77
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
83
78
|
rspec-support (~> 3.13.0)
|
|
84
79
|
rspec-support (3.13.1)
|
|
85
|
-
rubocop (1.
|
|
80
|
+
rubocop (1.66.1)
|
|
86
81
|
json (~> 2.3)
|
|
87
82
|
language_server-protocol (>= 3.17.0)
|
|
88
83
|
parallel (~> 1.10)
|
|
89
84
|
parser (>= 3.3.0.2)
|
|
90
85
|
rainbow (>= 2.2.2, < 4.0)
|
|
91
86
|
regexp_parser (>= 2.4, < 3.0)
|
|
92
|
-
|
|
93
|
-
rubocop-ast (>= 1.31.1, < 2.0)
|
|
87
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
|
94
88
|
ruby-progressbar (~> 1.7)
|
|
95
89
|
unicode-display_width (>= 2.4.0, < 3.0)
|
|
96
|
-
rubocop-ast (1.32.
|
|
90
|
+
rubocop-ast (1.32.3)
|
|
97
91
|
parser (>= 3.3.1.0)
|
|
98
92
|
rubocop-shopify (2.15.1)
|
|
99
93
|
rubocop (~> 1.51)
|
|
@@ -105,25 +99,15 @@ GEM
|
|
|
105
99
|
simplecov_json_formatter (~> 0.1)
|
|
106
100
|
simplecov-html (0.12.3)
|
|
107
101
|
simplecov_json_formatter (0.1.4)
|
|
108
|
-
|
|
109
|
-
thor (1.3.1)
|
|
102
|
+
thor (1.3.2)
|
|
110
103
|
unicode-display_width (2.5.0)
|
|
111
104
|
|
|
112
105
|
PLATFORMS
|
|
113
|
-
|
|
114
|
-
aarch64-linux-musl
|
|
115
|
-
arm-linux-gnu
|
|
116
|
-
arm-linux-musl
|
|
117
|
-
arm64-darwin
|
|
118
|
-
ruby
|
|
119
|
-
x86-linux-gnu
|
|
120
|
-
x86-linux-musl
|
|
121
|
-
x86_64-darwin
|
|
122
|
-
x86_64-linux-gnu
|
|
123
|
-
x86_64-linux-musl
|
|
106
|
+
arm64-darwin-23
|
|
124
107
|
|
|
125
108
|
DEPENDENCIES
|
|
126
109
|
dev_suite!
|
|
110
|
+
faker (~> 2.18)
|
|
127
111
|
faraday (~> 1.4)
|
|
128
112
|
pry (~> 0.14)
|
|
129
113
|
rake (~> 13.0)
|
data/README.md
CHANGED
|
@@ -214,6 +214,222 @@ Log detailed HTTP requests and responses across different adapters like Net::HTT
|
|
|
214
214
|
```
|
|
215
215
|
</details>
|
|
216
216
|
|
|
217
|
+
### Workflow Engine
|
|
218
|
+
Manage complex workflows consisting of multiple sequential steps, including handling data between steps and supporting dynamic operations like conditionals, loops, and parallel execution.
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary>Show more</summary>
|
|
222
|
+
|
|
223
|
+
**How to Use**:
|
|
224
|
+
```ruby
|
|
225
|
+
workflow = DevSuite::Workflow.create_engine(initial_context)
|
|
226
|
+
|
|
227
|
+
# Define steps
|
|
228
|
+
step1 = DevSuite::Workflow.create_step("Step 1") do |ctx|
|
|
229
|
+
ctx.update({ result: "Step 1 Complete" })
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
step2 = DevSuite::Workflow.create_step("Step 2") do |ctx|
|
|
233
|
+
puts "Previous Result: #{ctx.get(:result)}"
|
|
234
|
+
ctx.update({ result: "Step 2 Complete" })
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Chain steps together
|
|
238
|
+
workflow.step(step1).step(step2)
|
|
239
|
+
|
|
240
|
+
# Execute workflow
|
|
241
|
+
workflow.execute
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Chaining Steps**:
|
|
245
|
+
You can chain multiple steps together to create a workflow:
|
|
246
|
+
```ruby
|
|
247
|
+
workflow = DevSuite::Workflow.create_engine(initial_context)
|
|
248
|
+
|
|
249
|
+
step1 = DevSuite::Workflow.create_step("Step 1") { |ctx| ctx.update({ data: 'Data from Step 1' }) }
|
|
250
|
+
step2 = DevSuite::Workflow.create_step("Step 2") { |ctx| puts "Received: #{ctx.get(:data)}" }
|
|
251
|
+
|
|
252
|
+
workflow.step(step1)
|
|
253
|
+
.step(step2)
|
|
254
|
+
.execute
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Data Handling**:
|
|
258
|
+
Each step in the workflow has access to a shared context, where you can store and retrieve data:
|
|
259
|
+
```ruby
|
|
260
|
+
workflow = DevSuite::Workflow.create_engine({ some_key: 'initial_value' })
|
|
261
|
+
|
|
262
|
+
step1 = DevSuite::Workflow.create_step("Step 1") do |ctx|
|
|
263
|
+
# Retrieve data
|
|
264
|
+
puts ctx.get(:some_key) # Output: initial_value
|
|
265
|
+
# Set data
|
|
266
|
+
ctx.update({ new_key: 'new_value' })
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
step2 = DevSuite::Workflow.create_step("Step 2") do |ctx|
|
|
270
|
+
# Use updated data
|
|
271
|
+
puts ctx.get(:new_key) # Output: new_value
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
workflow.step(step1).step(step2).execute
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Conditional Execution**:
|
|
278
|
+
Conditionally execute steps based on logic defined in the workflow context:
|
|
279
|
+
```ruby
|
|
280
|
+
conditional_step = DevSuite::Workflow.create_conditional_step("Conditional Step", condition: ->(ctx) { ctx.get(:result) == "Step 1 Complete" }) do |ctx|
|
|
281
|
+
puts "Condition met! Executing conditional step."
|
|
282
|
+
ctx.update({ result: "Conditional Step Executed" })
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
workflow.step(conditional_step).execute
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Parallel Execution**:
|
|
289
|
+
You can execute multiple steps in parallel:
|
|
290
|
+
```ruby
|
|
291
|
+
parallel_step = DevSuite::Workflow.create_parallel_step("Parallel Step") do |ctx|
|
|
292
|
+
[
|
|
293
|
+
->(ctx) { ctx.update({ task1: "Task 1 done" }) },
|
|
294
|
+
->(ctx) { ctx.update({ task2: "Task 2 done" }) }
|
|
295
|
+
]
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
workflow.step(parallel_step).execute
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Save and Load Context**:
|
|
302
|
+
Save the workflow's context to a file and reload it for later use:
|
|
303
|
+
```ruby
|
|
304
|
+
# Saving context to a YAML file
|
|
305
|
+
workflow = DevSuite::Workflow.create_engine({ user: 'John' })
|
|
306
|
+
workflow.step(DevSuite::Workflow.create_step("Example") { |ctx| ctx.update({ status: 'completed' }) })
|
|
307
|
+
workflow.execute
|
|
308
|
+
|
|
309
|
+
File.open('context.yml', 'w') { |file| file.write(YAML.dump(workflow.context.data)) }
|
|
310
|
+
|
|
311
|
+
# Loading context from a YAML file
|
|
312
|
+
loaded_data = YAML.load_file('context.yml')
|
|
313
|
+
workflow = DevSuite::Workflow.create_engine(loaded_data)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Looping**:
|
|
317
|
+
You can loop steps in the workflow, for instance, if you need to repeat a step multiple times:
|
|
318
|
+
```ruby
|
|
319
|
+
loop_step = DevSuite::Workflow.create_loop_step("Repeat 5 Times", iterations: 5) do |ctx|
|
|
320
|
+
count = ctx.get(:count) || 0
|
|
321
|
+
ctx.update({ count: count + 1 })
|
|
322
|
+
puts "Iteration: #{ctx.get(:count)}"
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
workflow.step(loop_step).execute
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Using the Store**:
|
|
329
|
+
By default, the workflow context provides access to an integrated store via ctx.store. You can save and retrieve data across steps:
|
|
330
|
+
```ruby
|
|
331
|
+
# Using the store in the workflow
|
|
332
|
+
workflow = DevSuite::Workflow.create_engine(
|
|
333
|
+
{},
|
|
334
|
+
driver: :file,
|
|
335
|
+
path: "tmp/workflow.yml",
|
|
336
|
+
)
|
|
337
|
+
step = DevSuite::Workflow.create_step("Store Example") do |ctx|
|
|
338
|
+
ctx.store.set(:step_result, "Step 1 Completed")
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
workflow.step(step).execute
|
|
342
|
+
|
|
343
|
+
# Fetch data from the store
|
|
344
|
+
puts ctx.store.fetch(:step_result) # Output: Step 1 Completed
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Sample Output**:
|
|
348
|
+
```bash
|
|
349
|
+
Step 1 executed: result => Step 1 Complete
|
|
350
|
+
Step 2 executed: Previous Result: Step 1 Complete
|
|
351
|
+
Task 1 done
|
|
352
|
+
Task 2 done
|
|
353
|
+
Iteration: 1
|
|
354
|
+
Iteration: 2
|
|
355
|
+
...
|
|
356
|
+
Condition met! Executing conditional step.
|
|
357
|
+
Store contains: { name: "John Doe", age: 30 }
|
|
358
|
+
Step 1 Completed
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
</details>
|
|
362
|
+
|
|
363
|
+
### Method Tracer
|
|
364
|
+
Trace all method calls within a specific block of code, including optional logging of parameters, results, and execution time. This feature is useful for debugging, profiling, and understanding the flow of method calls in your code.
|
|
365
|
+
|
|
366
|
+
<details>
|
|
367
|
+
<summary>Show more</summary>
|
|
368
|
+
|
|
369
|
+
**How to Use**:
|
|
370
|
+
```ruby
|
|
371
|
+
# Sample class for demonstration
|
|
372
|
+
class MathOperations
|
|
373
|
+
def add(a, b)
|
|
374
|
+
multiply(a, b) + 3
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def multiply(a, b)
|
|
378
|
+
a * b
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def greet(name)
|
|
382
|
+
"Hello, #{name}!"
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# Using MethodTracer to trace method calls
|
|
387
|
+
DevSuite::MethodTracer.trace(show_params: true, show_results: true, show_execution_time: true) do
|
|
388
|
+
math = MathOperations.new
|
|
389
|
+
result = math.add(5, 3)
|
|
390
|
+
puts result
|
|
391
|
+
|
|
392
|
+
greeting = math.greet("Ruby")
|
|
393
|
+
puts greeting # Should print the greeting
|
|
394
|
+
end
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Configuration Guide**:
|
|
398
|
+
Customize the method tracing behavior by setting configuration options:
|
|
399
|
+
```ruby
|
|
400
|
+
DevSuite::MethodTracer.trace(
|
|
401
|
+
show_params: true,
|
|
402
|
+
show_results: true,
|
|
403
|
+
show_execution_time: true,
|
|
404
|
+
max_depth: 2
|
|
405
|
+
) do
|
|
406
|
+
# Code block to trace
|
|
407
|
+
end
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Configuration Options**:
|
|
411
|
+
|
|
412
|
+
Below is a table describing the available options for `MethodTracer`:
|
|
413
|
+
|
|
414
|
+
| Option | Description | Default Value | Example Values |
|
|
415
|
+
|----------------------|-----------------------------------------------------|---------------|---------------------------|
|
|
416
|
+
| `:show_params` | Enables logging of method parameters. | `false` | `true`, `false` |
|
|
417
|
+
| `:show_results` | Logs the return values of the methods. | `false` | `true`, `false` |
|
|
418
|
+
| `:show_execution_time` | Logs the execution time for each method. | `false` | `true`, `false` |
|
|
419
|
+
| `:max_depth` | Limits the depth of method calls to log. | `nil` | `1`, `2`, `3`, ... |
|
|
420
|
+
|
|
421
|
+
**Sample Output**:
|
|
422
|
+
```bash
|
|
423
|
+
🚀 #depth:1 > MathOperations#add at (irb):2 (5, 3)
|
|
424
|
+
🚀 #depth:2 > MathOperations#multiply at (irb):6 (5, 3)
|
|
425
|
+
🏁 #depth:2 < MathOperations#multiply #=> 15 at (irb):8 in 0.02ms
|
|
426
|
+
🏁 #depth:1 < MathOperations#add #=> 23 at (irb):4 in 7.35ms
|
|
427
|
+
🚀 #depth:1 > MathOperations#greet at (irb):10 ("Ruby")
|
|
428
|
+
🏁 #depth:1 < MathOperations#greet #=> "Hello, Ruby!" at (irb):12 in 0.02ms
|
|
429
|
+
Hello, Ruby!
|
|
430
|
+
```
|
|
431
|
+
</details>
|
|
432
|
+
|
|
217
433
|
## Development
|
|
218
434
|
|
|
219
435
|
After checking out the repo, run `bin/setup`for an interactive prompt that will allow you to experiment.
|
data/dev_suite.gemspec
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module APIHelper
|
|
4
|
+
require "net/http"
|
|
5
|
+
require "uri"
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def make_post_request(endpoint:, headers:, body_data:, success_criteria: nil)
|
|
9
|
+
uri = URI.parse(endpoint)
|
|
10
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
11
|
+
http.use_ssl = true
|
|
12
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
|
13
|
+
request.body = URI.encode_www_form(body_data)
|
|
14
|
+
|
|
15
|
+
response = http.request(request)
|
|
16
|
+
parsed_response = JSON.parse(response.body)
|
|
17
|
+
|
|
18
|
+
success = if success_criteria
|
|
19
|
+
success_criteria.call(parsed_response)
|
|
20
|
+
else
|
|
21
|
+
response.is_a?(Net::HTTPSuccess)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
{ success: success, response: parsed_response }
|
|
25
|
+
rescue StandardError => e
|
|
26
|
+
DevSuite::Utils::Logger.log("Error during POST request: #{e.message}", level: :error)
|
|
27
|
+
{ success: false, error: e.message }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def make_get_request(endpoint:, headers:, success_criteria: nil)
|
|
31
|
+
uri = URI.parse(endpoint)
|
|
32
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
33
|
+
http.use_ssl = true
|
|
34
|
+
request = Net::HTTP::Get.new(uri.request_uri, headers)
|
|
35
|
+
|
|
36
|
+
response = http.request(request)
|
|
37
|
+
parsed_response = JSON.parse(response.body)
|
|
38
|
+
|
|
39
|
+
success = if success_criteria
|
|
40
|
+
success_criteria.call(parsed_response)
|
|
41
|
+
else
|
|
42
|
+
response.is_a?(Net::HTTPSuccess)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
{ success: success, response: parsed_response }
|
|
46
|
+
rescue StandardError => e
|
|
47
|
+
DevSuite::Utils::Logger.log("Error during GET request: #{e.message}", level: :error)
|
|
48
|
+
{ success: false, error: e.message }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DataHelper
|
|
4
|
+
require "faker"
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
# Generate a human-readable username with a random number inserted
|
|
8
|
+
def generate_human_username
|
|
9
|
+
base_username = Faker::Internet.username(specifier: 8..12)
|
|
10
|
+
random_number = rand(100..999)
|
|
11
|
+
random_position = rand(0..base_username.length)
|
|
12
|
+
base_username.insert(random_position, random_number.to_s)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Generate a random phone number (can specify format: :national, :international, :mobile)
|
|
16
|
+
def generate_phone_number(format: :national)
|
|
17
|
+
case format
|
|
18
|
+
when :national
|
|
19
|
+
Faker::PhoneNumber.phone_number
|
|
20
|
+
when :international
|
|
21
|
+
Faker::PhoneNumber.cell_phone_in_e164
|
|
22
|
+
when :mobile
|
|
23
|
+
Faker::PhoneNumber.cell_phone
|
|
24
|
+
else
|
|
25
|
+
Faker::PhoneNumber.phone_number
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Generate a random email address (can specify domain)
|
|
30
|
+
def generate_email(username = nil, domain = "example.com")
|
|
31
|
+
username ||= Faker::Internet.username(specifier: 8..12)
|
|
32
|
+
"#{username}@#{domain}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Generate a secure random password
|
|
36
|
+
def generate_secure_password(length: 12)
|
|
37
|
+
Faker::Internet.password(min_length: length, mix_case: true, special_characters: true)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Generate a random full name (first and last)
|
|
41
|
+
def generate_full_name
|
|
42
|
+
"#{Faker::Name.first_name} #{Faker::Name.last_name}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Generate a random address
|
|
46
|
+
def generate_address
|
|
47
|
+
"#{Faker::Address.street_address}, #{Faker::Address.city}, #{Faker::Address.zip}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Generate a random date of birth (for users between min_age and max_age)
|
|
51
|
+
def generate_date_of_birth(min_age: 18, max_age: 65)
|
|
52
|
+
Faker::Date.birthday(min_age: min_age, max_age: max_age)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Generate a random company name
|
|
56
|
+
def generate_company_name
|
|
57
|
+
Faker::Company.name
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Generate a random IPv4 or IPv6 address
|
|
61
|
+
def generate_ip_address(version: :v4)
|
|
62
|
+
case version
|
|
63
|
+
when :v4
|
|
64
|
+
Faker::Internet.ip_v4_address
|
|
65
|
+
when :v6
|
|
66
|
+
Faker::Internet.ip_v6_address
|
|
67
|
+
else
|
|
68
|
+
Faker::Internet.ip_v4_address
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
|
|
4
|
+
require "dev_suite"
|
|
5
|
+
|
|
6
|
+
# Create a basic workflow
|
|
7
|
+
engine = DevSuite::Workflow::Engine.new(user: "Alice")
|
|
8
|
+
|
|
9
|
+
# Add a basic step
|
|
10
|
+
basic_step = DevSuite::Workflow.create_step("Greet User") do |context|
|
|
11
|
+
puts "Hello, #{context.get(:user)}!"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
engine.step(basic_step)
|
|
15
|
+
engine.execute
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
|
|
4
|
+
require "dev_suite"
|
|
5
|
+
|
|
6
|
+
# Create a workflow with multiple sub-steps
|
|
7
|
+
engine = DevSuite::Workflow::Engine.new
|
|
8
|
+
|
|
9
|
+
composite_step = DevSuite::Workflow.create_composite_step("Composite Task")
|
|
10
|
+
|
|
11
|
+
# Add sub-steps
|
|
12
|
+
sub_step1 = DevSuite::Workflow.create_step("Sub-Step 1") do |context|
|
|
13
|
+
puts "Executing Sub-Step 1"
|
|
14
|
+
end
|
|
15
|
+
sub_step2 = DevSuite::Workflow.create_step("Sub-Step 2") do |context|
|
|
16
|
+
puts "Executing Sub-Step 2"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
composite_step.step(sub_step1).step(sub_step2)
|
|
20
|
+
engine.step(composite_step)
|
|
21
|
+
engine.execute
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
|
|
4
|
+
require "dev_suite"
|
|
5
|
+
|
|
6
|
+
# Create a conditional workflow
|
|
7
|
+
engine = DevSuite::Workflow::Engine.new(user: "Bob", role: "admin")
|
|
8
|
+
|
|
9
|
+
# Add a conditional step
|
|
10
|
+
conditional_step = DevSuite::Workflow.create_conditional_step("Admin Greeting", ->(ctx) {
|
|
11
|
+
ctx.get(:role) == "admin"
|
|
12
|
+
}) do |context|
|
|
13
|
+
puts "Welcome Admin, #{context.get(:user)}!"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
engine.step(conditional_step)
|
|
17
|
+
engine.execute
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../../lib", __dir__))
|
|
4
|
+
require "dev_suite"
|
|
5
|
+
|
|
6
|
+
# Create the workflow engine with an initial context
|
|
7
|
+
engine = DevSuite::Workflow.create_engine(
|
|
8
|
+
{
|
|
9
|
+
user: "Alice",
|
|
10
|
+
role: "admin",
|
|
11
|
+
iteration_count: 0,
|
|
12
|
+
},
|
|
13
|
+
driver: :file,
|
|
14
|
+
path: "tmp/workflow_store.json",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Step 1: Create a basic step to greet the user
|
|
18
|
+
greet_step = DevSuite::Workflow.create_step("Greet User") do |context|
|
|
19
|
+
puts "Hello, #{context.get(:user)}!"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Step 2: Create a conditional step to greet only admins
|
|
23
|
+
admin_step = DevSuite::Workflow.create_conditional_step("Admin Greeting", ->(ctx) {
|
|
24
|
+
ctx.get(:role) == "admin"
|
|
25
|
+
}) do |context|
|
|
26
|
+
puts "Welcome, Admin #{context.get(:user)}!"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Step 3: Create a loop step that repeats 3 times
|
|
30
|
+
loop_step = DevSuite::Workflow.create_loop_step("Loop Step", 3) do |ctx|
|
|
31
|
+
iteration = ctx.get(:iteration_count) + 1
|
|
32
|
+
ctx.update({ iteration_count: iteration })
|
|
33
|
+
puts "Iteration #{iteration} completed."
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Step 4: Create a parallel step to run two tasks simultaneously
|
|
37
|
+
parallel_step = DevSuite::Workflow.create_parallel_step("Parallel Task") do |context|
|
|
38
|
+
[
|
|
39
|
+
->(ctx) { puts "Task 1 executed" },
|
|
40
|
+
->(ctx) { puts "Task 2 executed" },
|
|
41
|
+
]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Step 5: Create a composite step that combines two sub-steps
|
|
45
|
+
composite_step = DevSuite::Workflow.create_composite_step("Composite Task")
|
|
46
|
+
|
|
47
|
+
# Sub-Step 1
|
|
48
|
+
sub_step1 = DevSuite::Workflow.create_step("Sub-Step 1") do |context|
|
|
49
|
+
puts "Executing Sub-Step 1"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Sub-Step 2
|
|
53
|
+
sub_step2 = DevSuite::Workflow.create_step("Sub-Step 2") do |context|
|
|
54
|
+
puts "Executing Sub-Step 2"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Add sub-steps to the composite step
|
|
58
|
+
composite_step.step(sub_step1).step(sub_step2)
|
|
59
|
+
|
|
60
|
+
# Step 6: A step to store the final workflow result
|
|
61
|
+
store_step = DevSuite::Workflow.create_step("Store Result") do |context|
|
|
62
|
+
context.store.set(:workflow_result, "Workflow Completed")
|
|
63
|
+
puts "Result stored in context."
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Add all steps to the workflow engine
|
|
67
|
+
engine.step(greet_step)
|
|
68
|
+
.step(admin_step)
|
|
69
|
+
.step(loop_step)
|
|
70
|
+
.step(parallel_step)
|
|
71
|
+
.step(composite_step)
|
|
72
|
+
.step(store_step)
|
|
73
|
+
|
|
74
|
+
# Execute the workflow
|
|
75
|
+
puts "Executing workflow..."
|
|
76
|
+
engine.execute
|
|
77
|
+
|
|
78
|
+
# Retrieve the result from the context store after execution
|
|
79
|
+
puts "Final result from context store: #{engine.context.store.fetch(:workflow_result)}"
|