dev_suite 0.2.7 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- 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)}"
|