flows 0.2.0 → 0.6.0
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/.github/workflows/{build.yml → test.yml} +5 -10
- data/.gitignore +9 -1
- data/.mdlrc +1 -1
- data/.reek.yml +54 -0
- data/.rubocop.yml +26 -7
- data/.rubocop_todo.yml +27 -0
- data/.ruby-version +1 -1
- data/.yardopts +1 -0
- data/CHANGELOG.md +81 -0
- data/Gemfile +0 -6
- data/README.md +167 -363
- data/Rakefile +35 -1
- data/bin/.rubocop.yml +5 -0
- data/bin/all_the_errors +55 -0
- data/bin/benchmark +73 -105
- data/bin/benchmark_cli/compare.rb +118 -0
- data/bin/benchmark_cli/compare/a_plus_b.rb +22 -0
- data/bin/benchmark_cli/compare/base.rb +45 -0
- data/bin/benchmark_cli/compare/command.rb +47 -0
- data/bin/benchmark_cli/compare/ten_steps.rb +22 -0
- data/bin/benchmark_cli/examples.rb +23 -0
- data/bin/benchmark_cli/examples/.rubocop.yml +22 -0
- data/bin/benchmark_cli/examples/a_plus_b/dry_do.rb +23 -0
- data/bin/benchmark_cli/examples/a_plus_b/dry_transaction.rb +17 -0
- data/bin/benchmark_cli/examples/a_plus_b/flows_do.rb +22 -0
- data/bin/benchmark_cli/examples/a_plus_b/flows_railway.rb +13 -0
- data/bin/benchmark_cli/examples/a_plus_b/flows_scp.rb +13 -0
- data/bin/benchmark_cli/examples/a_plus_b/flows_scp_mut.rb +13 -0
- data/bin/benchmark_cli/examples/a_plus_b/flows_scp_oc.rb +21 -0
- data/bin/benchmark_cli/examples/a_plus_b/trailblazer.rb +15 -0
- data/bin/benchmark_cli/examples/ten_steps/dry_do.rb +70 -0
- data/bin/benchmark_cli/examples/ten_steps/dry_transaction.rb +64 -0
- data/bin/benchmark_cli/examples/ten_steps/flows_do.rb +69 -0
- data/bin/benchmark_cli/examples/ten_steps/flows_railway.rb +58 -0
- data/bin/benchmark_cli/examples/ten_steps/flows_scp.rb +58 -0
- data/bin/benchmark_cli/examples/ten_steps/flows_scp_mut.rb +58 -0
- data/bin/benchmark_cli/examples/ten_steps/flows_scp_oc.rb +66 -0
- data/bin/benchmark_cli/examples/ten_steps/trailblazer.rb +60 -0
- data/bin/benchmark_cli/helpers.rb +12 -0
- data/bin/benchmark_cli/ruby.rb +15 -0
- data/bin/benchmark_cli/ruby/command.rb +38 -0
- data/bin/benchmark_cli/ruby/method_exec.rb +71 -0
- data/bin/benchmark_cli/ruby/self_class.rb +69 -0
- data/bin/benchmark_cli/ruby/structs.rb +90 -0
- data/bin/console +1 -0
- data/bin/docserver +7 -0
- data/bin/errors +138 -0
- data/bin/errors_cli/contract_error_demo.rb +49 -0
- data/bin/errors_cli/di_error_demo.rb +38 -0
- data/bin/errors_cli/flow_error_demo.rb +22 -0
- data/bin/errors_cli/flows_router_error_demo.rb +15 -0
- data/bin/errors_cli/interface_error_demo.rb +17 -0
- data/bin/errors_cli/oc_error_demo.rb +40 -0
- data/bin/errors_cli/railway_error_demo.rb +10 -0
- data/bin/errors_cli/result_error_demo.rb +13 -0
- data/bin/errors_cli/scp_error_demo.rb +17 -0
- data/docs/README.md +3 -187
- data/docs/_sidebar.md +0 -24
- data/docs/index.html +1 -1
- data/flows.gemspec +27 -2
- data/forspell.dict +9 -0
- data/lefthook.yml +9 -0
- data/lib/flows.rb +11 -5
- data/lib/flows/contract.rb +402 -0
- data/lib/flows/contract/array.rb +55 -0
- data/lib/flows/contract/case_eq.rb +43 -0
- data/lib/flows/contract/compose.rb +77 -0
- data/lib/flows/contract/either.rb +53 -0
- data/lib/flows/contract/error.rb +24 -0
- data/lib/flows/contract/hash.rb +75 -0
- data/lib/flows/contract/hash_of.rb +70 -0
- data/lib/flows/contract/helpers.rb +22 -0
- data/lib/flows/contract/predicate.rb +34 -0
- data/lib/flows/contract/transformer.rb +50 -0
- data/lib/flows/contract/tuple.rb +70 -0
- data/lib/flows/flow.rb +96 -7
- data/lib/flows/flow/errors.rb +29 -0
- data/lib/flows/flow/node.rb +132 -0
- data/lib/flows/flow/router.rb +29 -0
- data/lib/flows/flow/router/custom.rb +59 -0
- data/lib/flows/flow/router/errors.rb +11 -0
- data/lib/flows/flow/router/simple.rb +25 -0
- data/lib/flows/plugin.rb +15 -0
- data/lib/flows/plugin/dependency_injector.rb +170 -0
- data/lib/flows/plugin/dependency_injector/dependency.rb +24 -0
- data/lib/flows/plugin/dependency_injector/dependency_definition.rb +16 -0
- data/lib/flows/plugin/dependency_injector/dependency_list.rb +55 -0
- data/lib/flows/plugin/dependency_injector/errors.rb +58 -0
- data/lib/flows/plugin/implicit_init.rb +45 -0
- data/lib/flows/plugin/interface.rb +84 -0
- data/lib/flows/plugin/output_contract.rb +85 -0
- data/lib/flows/plugin/output_contract/dsl.rb +48 -0
- data/lib/flows/plugin/output_contract/errors.rb +74 -0
- data/lib/flows/plugin/output_contract/wrapper.rb +55 -0
- data/lib/flows/plugin/profiler.rb +114 -0
- data/lib/flows/plugin/profiler/injector.rb +35 -0
- data/lib/flows/plugin/profiler/report.rb +48 -0
- data/lib/flows/plugin/profiler/report/events.rb +43 -0
- data/lib/flows/plugin/profiler/report/flat.rb +41 -0
- data/lib/flows/plugin/profiler/report/flat/method_report.rb +80 -0
- data/lib/flows/plugin/profiler/report/raw.rb +15 -0
- data/lib/flows/plugin/profiler/report/tree.rb +98 -0
- data/lib/flows/plugin/profiler/report/tree/calculated_node.rb +116 -0
- data/lib/flows/plugin/profiler/report/tree/node.rb +34 -0
- data/lib/flows/plugin/profiler/wrapper.rb +53 -0
- data/lib/flows/railway.rb +140 -34
- data/lib/flows/railway/dsl.rb +8 -18
- data/lib/flows/railway/errors.rb +8 -12
- data/lib/flows/railway/step.rb +24 -0
- data/lib/flows/railway/step_list.rb +38 -0
- data/lib/flows/result.rb +188 -2
- data/lib/flows/result/do.rb +158 -16
- data/lib/flows/result/err.rb +12 -6
- data/lib/flows/result/errors.rb +29 -17
- data/lib/flows/result/helpers.rb +25 -3
- data/lib/flows/result/ok.rb +12 -6
- data/lib/flows/shared_context_pipeline.rb +342 -0
- data/lib/flows/shared_context_pipeline/dsl.rb +12 -0
- data/lib/flows/shared_context_pipeline/dsl/callbacks.rb +35 -0
- data/lib/flows/shared_context_pipeline/dsl/tracks.rb +52 -0
- data/lib/flows/shared_context_pipeline/errors.rb +17 -0
- data/lib/flows/shared_context_pipeline/mutation_step.rb +30 -0
- data/lib/flows/shared_context_pipeline/router_definition.rb +21 -0
- data/lib/flows/shared_context_pipeline/step.rb +55 -0
- data/lib/flows/shared_context_pipeline/track.rb +54 -0
- data/lib/flows/shared_context_pipeline/track_list.rb +51 -0
- data/lib/flows/shared_context_pipeline/wrap.rb +73 -0
- data/lib/flows/util.rb +17 -0
- data/lib/flows/util/inheritable_singleton_vars.rb +86 -0
- data/lib/flows/util/inheritable_singleton_vars/dup_strategy.rb +100 -0
- data/lib/flows/util/inheritable_singleton_vars/isolation_strategy.rb +91 -0
- data/lib/flows/util/prepend_to_class.rb +191 -0
- data/lib/flows/version.rb +1 -1
- metadata +253 -38
- data/Gemfile.lock +0 -174
- data/bin/demo +0 -66
- data/bin/examples.rb +0 -195
- data/bin/profile_10steps +0 -106
- data/bin/ruby_benchmarks +0 -26
- data/docs/CNAME +0 -1
- data/docs/contributing/benchmarks_profiling.md +0 -3
- data/docs/contributing/local_development.md +0 -3
- data/docs/flow/direct_usage.md +0 -3
- data/docs/flow/general_idea.md +0 -3
- data/docs/operation/basic_usage.md +0 -1
- data/docs/operation/inject_steps.md +0 -3
- data/docs/operation/lambda_steps.md +0 -3
- data/docs/operation/result_shapes.md +0 -3
- data/docs/operation/routing_tracks.md +0 -3
- data/docs/operation/wrapping_steps.md +0 -3
- data/docs/overview/performance.md +0 -336
- data/docs/railway/basic_usage.md +0 -232
- data/docs/result_objects/basic_usage.md +0 -196
- data/docs/result_objects/do_notation.md +0 -139
- data/lib/flows/node.rb +0 -27
- data/lib/flows/operation.rb +0 -52
- data/lib/flows/operation/builder.rb +0 -130
- data/lib/flows/operation/builder/build_router.rb +0 -37
- data/lib/flows/operation/dsl.rb +0 -93
- data/lib/flows/operation/errors.rb +0 -75
- data/lib/flows/operation/executor.rb +0 -78
- data/lib/flows/railway/builder.rb +0 -68
- data/lib/flows/railway/executor.rb +0 -23
- data/lib/flows/result_router.rb +0 -14
- data/lib/flows/router.rb +0 -22
data/Rakefile
CHANGED
@@ -2,8 +2,42 @@ require 'bundler/gem_tasks'
|
|
2
2
|
|
3
3
|
require 'rspec/core/rake_task'
|
4
4
|
require 'rubocop/rake_task'
|
5
|
+
require 'reek/rake/task'
|
6
|
+
require 'inch/rake'
|
7
|
+
|
8
|
+
require 'forspell/cli'
|
9
|
+
require 'mdl'
|
5
10
|
|
6
11
|
RSpec::Core::RakeTask.new(:spec)
|
7
12
|
RuboCop::RakeTask.new(:rubocop)
|
13
|
+
Reek::Rake::Task.new
|
14
|
+
Inch::Rake::Suggest.new
|
15
|
+
|
16
|
+
PATHS_TO_SPELLCHECK = ['.'].freeze
|
17
|
+
PATHS_FOR_MDL = ['README.md', 'CHANGELOG.md', Dir.glob('docs/**/*.md')].flatten.freeze
|
18
|
+
|
19
|
+
desc 'Run self spellchecking'
|
20
|
+
task :spellcheck do |_task|
|
21
|
+
puts 'Run forspell checker...'
|
22
|
+
Forspell::CLI.new(PATHS_TO_SPELLCHECK).call
|
23
|
+
rescue SystemExit => err
|
24
|
+
if err.status.zero?
|
25
|
+
puts 'Everything is ok.'
|
26
|
+
else
|
27
|
+
exit err.status
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Run markdown linter'
|
32
|
+
task :mdl do |_task|
|
33
|
+
puts 'Run MDL linter...'
|
34
|
+
MarkdownLint.run(PATHS_FOR_MDL)
|
35
|
+
rescue SystemExit => err
|
36
|
+
if err.status.zero?
|
37
|
+
puts 'Everything is ok.'
|
38
|
+
else
|
39
|
+
exit err.status
|
40
|
+
end
|
41
|
+
end
|
8
42
|
|
9
|
-
task default: %i[rubocop spec]
|
43
|
+
task default: %i[rubocop reek spec spellcheck mdl]
|
data/bin/.rubocop.yml
ADDED
data/bin/all_the_errors
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
"${BASH_SOURCE%/*}/errors" contract
|
4
|
+
"${BASH_SOURCE%/*}/errors" router
|
5
|
+
|
6
|
+
echo
|
7
|
+
echo
|
8
|
+
echo "---------------------------"
|
9
|
+
echo "Dependency Injection plugin"
|
10
|
+
echo "---------------------------"
|
11
|
+
"${BASH_SOURCE%/*}/errors" di missing
|
12
|
+
"${BASH_SOURCE%/*}/errors" di unexpected
|
13
|
+
"${BASH_SOURCE%/*}/errors" di invalid_type
|
14
|
+
"${BASH_SOURCE%/*}/errors" di missing_default
|
15
|
+
|
16
|
+
echo
|
17
|
+
echo
|
18
|
+
echo "---------------------------"
|
19
|
+
echo "Output Contract plugin"
|
20
|
+
echo "---------------------------"
|
21
|
+
"${BASH_SOURCE%/*}/errors" output_contract no_contract
|
22
|
+
"${BASH_SOURCE%/*}/errors" output_contract contract
|
23
|
+
"${BASH_SOURCE%/*}/errors" output_contract status
|
24
|
+
"${BASH_SOURCE%/*}/errors" output_contract result_type
|
25
|
+
|
26
|
+
echo
|
27
|
+
echo
|
28
|
+
echo "---------------------------"
|
29
|
+
echo "Railway"
|
30
|
+
echo "---------------------------"
|
31
|
+
"${BASH_SOURCE%/*}/errors" railway no_steps
|
32
|
+
|
33
|
+
echo
|
34
|
+
echo
|
35
|
+
echo "---------------------------"
|
36
|
+
echo "Result"
|
37
|
+
echo "---------------------------"
|
38
|
+
"${BASH_SOURCE%/*}/errors" result ok_access
|
39
|
+
"${BASH_SOURCE%/*}/errors" result err_access
|
40
|
+
|
41
|
+
echo
|
42
|
+
echo
|
43
|
+
echo "---------------------------"
|
44
|
+
echo "Shared Context Pipeline"
|
45
|
+
echo "---------------------------"
|
46
|
+
"${BASH_SOURCE%/*}/errors" scp no_steps
|
47
|
+
"${BASH_SOURCE%/*}/errors" scp no_step_impl
|
48
|
+
|
49
|
+
echo
|
50
|
+
echo
|
51
|
+
echo "---------------------------"
|
52
|
+
echo "Flow"
|
53
|
+
echo "---------------------------"
|
54
|
+
"${BASH_SOURCE%/*}/errors" flow invalid_node_route
|
55
|
+
"${BASH_SOURCE%/*}/errors" flow no_first_node
|
data/bin/benchmark
CHANGED
@@ -1,111 +1,79 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# rubocop:disable all
|
3
2
|
|
4
3
|
require 'bundler/setup'
|
5
|
-
require '
|
6
|
-
|
7
|
-
require_relative './examples'
|
8
|
-
|
9
|
-
with_all = ENV['WITH_ALL']
|
10
|
-
|
11
|
-
with_railway = ENV['WITH_RW'] || with_all
|
12
|
-
with_operation = ENV['WITH_OP'] || with_all
|
13
|
-
with_dry = ENV['WITH_DRY'] || with_all
|
14
|
-
with_trailblazer = ENV['WITH_TB'] || with_all
|
15
|
-
|
16
|
-
with_poro = ENV['WITH_PORO']
|
17
|
-
|
18
|
-
no_prebuild = ENV['NO_PREBUILD']
|
19
|
-
no_eachbuild = ENV['NO_EACHBUILD']
|
20
|
-
|
21
|
-
|
22
|
-
puts '-' * 50
|
23
|
-
puts '- task: A + B, one step implementation'
|
24
|
-
puts '-' * 50
|
25
|
-
|
26
|
-
flows_summator = FlowsSummator.new
|
27
|
-
flows_railway_summator = FlowsRailwaySummator.new
|
28
|
-
dry_summator = DrySummator.new
|
29
|
-
|
30
|
-
Benchmark.ips do |b|
|
31
|
-
b.report 'Flows::Railway (build once)' do
|
32
|
-
flows_railway_summator.call(a: 1, b: 2)
|
33
|
-
end if with_railway && !no_prebuild
|
34
|
-
|
35
|
-
b.report 'Flows::Railway (build each time)' do
|
36
|
-
FlowsRailwaySummator.new.call(a: 1, b: 2)
|
37
|
-
end if with_railway && !no_eachbuild
|
38
|
-
|
39
|
-
b.report 'Flows::Operation (build once)' do
|
40
|
-
flows_summator.call(a: 1, b: 2)
|
41
|
-
end if with_operation && !no_prebuild
|
42
|
-
|
43
|
-
b.report 'Flows::Operation (build each time)' do
|
44
|
-
FlowsSummator.new.call(a: 1, b: 2)
|
45
|
-
end if with_operation && !no_eachbuild
|
46
|
-
|
47
|
-
b.report 'Dry::Transaction (build once)' do
|
48
|
-
dry_summator.call(a: 1, b: 2)
|
49
|
-
end if with_dry && !no_prebuild
|
50
|
-
|
51
|
-
b.report 'Dry::Transaction (build each time)' do
|
52
|
-
DrySummator.new.call(a: 1, b: 2)
|
53
|
-
end if with_dry && !no_eachbuild
|
4
|
+
require 'flows'
|
54
5
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
6
|
+
require 'benchmark/ips'
|
7
|
+
require 'pry'
|
8
|
+
require 'gli'
|
9
|
+
require 'warning'
|
10
|
+
|
11
|
+
require_relative 'benchmark_cli/helpers'
|
12
|
+
require_relative 'benchmark_cli/examples'
|
13
|
+
|
14
|
+
require_relative 'benchmark_cli/ruby'
|
15
|
+
require_relative 'benchmark_cli/compare'
|
16
|
+
|
17
|
+
Warning.ignore(/BigDecimal.new is deprecated/)
|
18
|
+
|
19
|
+
# Benchmarking CLI application
|
20
|
+
class BenchmarkCLI
|
21
|
+
extend GLI::App
|
22
|
+
extend Flows::Result::Helpers
|
23
|
+
|
24
|
+
program_desc 'Benchmark runner'
|
25
|
+
|
26
|
+
use_openstruct true
|
27
|
+
|
28
|
+
desc 'Run Ruby benchmarks'
|
29
|
+
ruby_benchmarks = Ruby::BENCHMARKS.keys.map(&:to_s)
|
30
|
+
command :ruby do |cmd|
|
31
|
+
cmd.flag(
|
32
|
+
%i[b benchmarks],
|
33
|
+
desc: "benchmarks to run. Pick from: #{ruby_benchmarks.join(', ')}. By default all the benchmarks are executed.",
|
34
|
+
type: String,
|
35
|
+
multiple: true,
|
36
|
+
must_match: ruby_benchmarks,
|
37
|
+
default_value: ruby_benchmarks
|
38
|
+
)
|
39
|
+
|
40
|
+
cmd.action do |_gopts, opts, _args|
|
41
|
+
result = Ruby::Command.new(opts.benchmarks).call
|
42
|
+
|
43
|
+
case result
|
44
|
+
when match_ok then puts 'Benchmark finished! Thank you for patience!'
|
45
|
+
when match_err then exit_now!(result.error)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Compare different Flows abstractions and alternatives from the other libraries'
|
51
|
+
command :compare do |cmd|
|
52
|
+
benchmarks = Compare::BENCHMARKS.keys.map(&:to_s)
|
53
|
+
cmd.flag %i[b benchmarks],
|
54
|
+
desc: 'benchmarks to run',
|
55
|
+
type: String,
|
56
|
+
multiple: true,
|
57
|
+
must_match: benchmarks,
|
58
|
+
default_value: benchmarks
|
59
|
+
|
60
|
+
implementations = Compare::IMPLEMENTATIONS.keys.map(&:to_s)
|
61
|
+
cmd.flag %i[i implementations],
|
62
|
+
desc: 'implementations to compare',
|
63
|
+
type: String,
|
64
|
+
multiple: true,
|
65
|
+
must_match: implementations,
|
66
|
+
default_value: implementations
|
67
|
+
|
68
|
+
cmd.action do |_gopts, opts, _args|
|
69
|
+
result = Compare::Command.new(opts.benchmarks, opts.implementations).call
|
70
|
+
|
71
|
+
case result
|
72
|
+
when match_ok then puts 'Benchmark finished! Thank you for patience!'
|
73
|
+
when match_err then exit_now!(result.error)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
64
77
|
end
|
65
|
-
puts
|
66
|
-
|
67
|
-
|
68
|
-
puts '-' * 50
|
69
|
-
puts '- task: ten steps returns successful result'
|
70
|
-
puts '-' * 50
|
71
|
-
|
72
|
-
flows_ten_steps = FlowsTenSteps.new
|
73
|
-
flows_railway_ten_steps = FlowsRailwayTenSteps.new
|
74
|
-
dry_ten_steps = DryTenSteps.new
|
75
|
-
|
76
|
-
Benchmark.ips do |b|
|
77
|
-
b.report 'Flows::Railway (build once)' do
|
78
|
-
flows_railway_ten_steps.call(a: 1, b: 2)
|
79
|
-
end if with_railway && !no_prebuild
|
80
|
-
|
81
|
-
b.report 'Flows::Railway (build each time)' do
|
82
|
-
FlowsRailwayTenSteps.new.call(a: 1, b: 2)
|
83
|
-
end if with_railway && !no_eachbuild
|
84
78
|
|
85
|
-
|
86
|
-
flows_ten_steps.call(a: 1, b: 2)
|
87
|
-
end if with_operation && !no_prebuild
|
88
|
-
|
89
|
-
b.report 'Flows::Operation (build each time)' do
|
90
|
-
FlowsTenSteps.new.call(a: 1, b: 2)
|
91
|
-
end if with_operation && !no_eachbuild
|
92
|
-
|
93
|
-
b.report 'Dry::Transaction (build once)' do
|
94
|
-
dry_ten_steps.call(a: 1, b: 2)
|
95
|
-
end if with_dry && !no_prebuild
|
96
|
-
|
97
|
-
b.report 'Dry::Transaction (build each time)' do
|
98
|
-
DryTenSteps.new.call(a: 1, b: 2)
|
99
|
-
end if with_dry && !no_eachbuild
|
100
|
-
|
101
|
-
b.report 'Trailblazer::Operation' do
|
102
|
-
TBTenSteps.call(a: 1, b: 2)
|
103
|
-
end if with_trailblazer
|
104
|
-
|
105
|
-
b.report 'PORO' do
|
106
|
-
POROTenSteps.call
|
107
|
-
end if with_poro
|
108
|
-
|
109
|
-
b.compare!
|
110
|
-
end
|
111
|
-
puts
|
79
|
+
exit BenchmarkCLI.run(ARGV)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative 'compare/base'
|
2
|
+
require_relative 'compare/a_plus_b'
|
3
|
+
require_relative 'compare/ten_steps'
|
4
|
+
|
5
|
+
require_relative 'compare/command'
|
6
|
+
|
7
|
+
class BenchmarkCLI
|
8
|
+
module Compare # rubocop:disable Metrics/ModuleLength
|
9
|
+
BENCHMARKS = {
|
10
|
+
APlusB::NAME => APlusB,
|
11
|
+
TenSteps::NAME => TenSteps
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
MODES = {
|
15
|
+
class_call: 'execute `Implementation.call(...)`',
|
16
|
+
instance_call: 'execute `instance.call(...)`'
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
IMPLEMENTATIONS = {
|
20
|
+
flows_do: {
|
21
|
+
title: 'Flows Do-notation',
|
22
|
+
mode: :instance_call,
|
23
|
+
classes: {
|
24
|
+
APlusB::NAME => Examples::APlusB::FlowsDo,
|
25
|
+
TenSteps::NAME => Examples::TenSteps::FlowsDo
|
26
|
+
}
|
27
|
+
},
|
28
|
+
flows_railway_class: {
|
29
|
+
title: 'Flows Railway',
|
30
|
+
mode: :class_call,
|
31
|
+
classes: {
|
32
|
+
APlusB::NAME => Examples::APlusB::FlowsRailway,
|
33
|
+
TenSteps::NAME => Examples::TenSteps::FlowsRailway
|
34
|
+
}
|
35
|
+
},
|
36
|
+
flows_railway_instance: {
|
37
|
+
title: 'Flows Railway',
|
38
|
+
mode: :instance_call,
|
39
|
+
classes: {
|
40
|
+
APlusB::NAME => Examples::APlusB::FlowsRailway,
|
41
|
+
TenSteps::NAME => Examples::TenSteps::FlowsRailway
|
42
|
+
}
|
43
|
+
},
|
44
|
+
flows_scp_class: {
|
45
|
+
title: 'Flows Shared Context Pipeline, functional steps',
|
46
|
+
mode: :class_call,
|
47
|
+
classes: {
|
48
|
+
APlusB::NAME => Examples::APlusB::FlowsSCP,
|
49
|
+
TenSteps::NAME => Examples::TenSteps::FlowsSCP
|
50
|
+
}
|
51
|
+
},
|
52
|
+
flows_scp_instance: {
|
53
|
+
title: 'Flows Shared Context Pipeline, functional steps',
|
54
|
+
mode: :instance_call,
|
55
|
+
classes: {
|
56
|
+
APlusB::NAME => Examples::APlusB::FlowsSCP,
|
57
|
+
TenSteps::NAME => Examples::TenSteps::FlowsSCP
|
58
|
+
}
|
59
|
+
},
|
60
|
+
flows_scp_oc_class: {
|
61
|
+
title: 'Flows Shared Context Pipeline with contract for output, functional steps',
|
62
|
+
mode: :class_call,
|
63
|
+
classes: {
|
64
|
+
APlusB::NAME => Examples::APlusB::FlowsSCPOC,
|
65
|
+
TenSteps::NAME => Examples::TenSteps::FlowsSCPOC
|
66
|
+
}
|
67
|
+
},
|
68
|
+
flows_scp_oc_instance: {
|
69
|
+
title: 'Flows Shared Context Pipeline with contract for output, functional steps',
|
70
|
+
mode: :instance_call,
|
71
|
+
classes: {
|
72
|
+
APlusB::NAME => Examples::APlusB::FlowsSCPOC,
|
73
|
+
TenSteps::NAME => Examples::TenSteps::FlowsSCPOC
|
74
|
+
}
|
75
|
+
},
|
76
|
+
flows_scp_mut_class: {
|
77
|
+
title: 'Flows Shared Context Pipeline, mutation steps',
|
78
|
+
mode: :class_call,
|
79
|
+
classes: {
|
80
|
+
APlusB::NAME => Examples::APlusB::FlowsSCPMut,
|
81
|
+
TenSteps::NAME => Examples::TenSteps::FlowsSCPMut
|
82
|
+
}
|
83
|
+
},
|
84
|
+
flows_scp_mut_instance: {
|
85
|
+
title: 'Flows Shared Context Pipeline, mutation steps',
|
86
|
+
mode: :instance_call,
|
87
|
+
classes: {
|
88
|
+
APlusB::NAME => Examples::APlusB::FlowsSCPMut,
|
89
|
+
TenSteps::NAME => Examples::TenSteps::FlowsSCPMut
|
90
|
+
}
|
91
|
+
},
|
92
|
+
dry_do: {
|
93
|
+
title: 'dry-rb Do-notation',
|
94
|
+
mode: :instance_call,
|
95
|
+
classes: {
|
96
|
+
APlusB::NAME => Examples::APlusB::DryDo,
|
97
|
+
TenSteps::NAME => Examples::TenSteps::DryDo
|
98
|
+
}
|
99
|
+
},
|
100
|
+
dry_transaction: {
|
101
|
+
title: 'dry-rb Transaction',
|
102
|
+
mode: :instance_call,
|
103
|
+
classes: {
|
104
|
+
APlusB::NAME => Examples::APlusB::DryTransaction,
|
105
|
+
TenSteps::NAME => Examples::TenSteps::DryTransaction
|
106
|
+
}
|
107
|
+
},
|
108
|
+
trailblazer: {
|
109
|
+
title: 'Trailblazer Operation',
|
110
|
+
mode: :class_call,
|
111
|
+
classes: {
|
112
|
+
APlusB::NAME => Examples::APlusB::TB,
|
113
|
+
TenSteps::NAME => Examples::TenSteps::TB
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}.freeze
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class BenchmarkCLI
|
2
|
+
module Compare
|
3
|
+
# 'A + B' comparison.
|
4
|
+
class APlusB < Base
|
5
|
+
TITLE = 'A + B: one step implementation, input provided as kwargs'.freeze
|
6
|
+
NAME = :a_plus_b
|
7
|
+
|
8
|
+
def report_class_call(benchmark, title, klass)
|
9
|
+
benchmark.report title do
|
10
|
+
klass.call(a: 100, b: 200)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def report_instance_call(benchmark, title, klass)
|
15
|
+
instance = klass.new
|
16
|
+
benchmark.report title do
|
17
|
+
instance.call(a: 100, b: 200)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class BenchmarkCLI
|
2
|
+
module Compare
|
3
|
+
# @abstract
|
4
|
+
#
|
5
|
+
# Base class for comparison benchmarks.
|
6
|
+
class Base
|
7
|
+
include Helpers
|
8
|
+
|
9
|
+
def initialize(implementations)
|
10
|
+
@implementations = implementations
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
header self.class::TITLE
|
15
|
+
|
16
|
+
Benchmark.ips do |benchmark|
|
17
|
+
benchmark.config(stats: :bootstrap, confidence: 95)
|
18
|
+
|
19
|
+
report_implementations(benchmark)
|
20
|
+
|
21
|
+
benchmark.compare!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def report_implementations(benchmark)
|
28
|
+
@implementations.each do |implementation|
|
29
|
+
report_implementation(benchmark, IMPLEMENTATIONS[implementation])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def report_implementation(benchmark, cfg)
|
34
|
+
mode = cfg[:mode]
|
35
|
+
title = "#{cfg[:title]} (#{MODES[mode]})"
|
36
|
+
klass = cfg[:classes][self.class::NAME]
|
37
|
+
|
38
|
+
case mode
|
39
|
+
when :class_call then report_class_call(benchmark, title, klass)
|
40
|
+
when :instance_call then report_instance_call(benchmark, title, klass)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|