teckel 0.1.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +114 -0
  3. data/LICENSE_LOGO +4 -0
  4. data/README.md +22 -14
  5. data/lib/teckel.rb +11 -2
  6. data/lib/teckel/chain.rb +47 -152
  7. data/lib/teckel/chain/config.rb +246 -0
  8. data/lib/teckel/chain/result.rb +38 -0
  9. data/lib/teckel/chain/runner.rb +62 -0
  10. data/lib/teckel/chain/step.rb +18 -0
  11. data/lib/teckel/config.rb +41 -52
  12. data/lib/teckel/contracts.rb +19 -0
  13. data/lib/teckel/operation.rb +108 -253
  14. data/lib/teckel/operation/config.rb +396 -0
  15. data/lib/teckel/operation/result.rb +92 -0
  16. data/lib/teckel/operation/runner.rb +75 -0
  17. data/lib/teckel/result.rb +52 -53
  18. data/lib/teckel/version.rb +1 -1
  19. data/spec/chain/default_settings_spec.rb +39 -0
  20. data/spec/chain/inheritance_spec.rb +116 -0
  21. data/spec/chain/none_input_spec.rb +36 -0
  22. data/spec/chain/results_spec.rb +53 -0
  23. data/spec/chain_around_hook_spec.rb +100 -0
  24. data/spec/chain_spec.rb +180 -0
  25. data/spec/config_spec.rb +26 -0
  26. data/spec/doctest_helper.rb +7 -0
  27. data/spec/operation/contract_trace_spec.rb +116 -0
  28. data/spec/operation/default_settings_spec.rb +94 -0
  29. data/spec/operation/inheritance_spec.rb +94 -0
  30. data/spec/operation/result_spec.rb +34 -0
  31. data/spec/operation/results_spec.rb +117 -0
  32. data/spec/operation_spec.rb +483 -0
  33. data/spec/rb27/pattern_matching_spec.rb +193 -0
  34. data/spec/result_spec.rb +22 -0
  35. data/spec/spec_helper.rb +25 -0
  36. data/spec/support/dry_base.rb +8 -0
  37. data/spec/support/fake_db.rb +12 -0
  38. data/spec/support/fake_models.rb +20 -0
  39. data/spec/teckel_spec.rb +7 -0
  40. metadata +64 -46
  41. data/.github/workflows/ci.yml +0 -67
  42. data/.github/workflows/pages.yml +0 -50
  43. data/.gitignore +0 -13
  44. data/.rspec +0 -3
  45. data/.rubocop.yml +0 -12
  46. data/.ruby-version +0 -1
  47. data/DEVELOPMENT.md +0 -28
  48. data/Gemfile +0 -8
  49. data/Gemfile.lock +0 -71
  50. data/Rakefile +0 -30
  51. data/bin/console +0 -15
  52. data/bin/rake +0 -29
  53. data/bin/rspec +0 -29
  54. data/bin/rubocop +0 -18
  55. data/bin/setup +0 -8
  56. data/lib/teckel/operation/results.rb +0 -71
  57. data/teckel.gemspec +0 -33
@@ -1,67 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- paths:
6
- - .github/workflows/ci.yml
7
- - lib/**
8
- - spec/**
9
- - Gemfile
10
- - "*.gemspec"
11
- - ".rubocop.yml"
12
-
13
- jobs:
14
- rubocop:
15
- runs-on: ubuntu-latest
16
- steps:
17
- - uses: actions/checkout@v1
18
- - name: Set up Ruby
19
- uses: actions/setup-ruby@v1
20
- with:
21
- ruby-version: 2.4.x
22
- - name: Install bundler
23
- run: gem install bundler
24
- - name: Run rubocop
25
- run: bin/rubocop -ESD
26
-
27
- cruby:
28
- runs-on: ubuntu-latest
29
- strategy:
30
- fail-fast: false
31
- matrix:
32
- ruby: ["2.6.x", "2.5.x", "2.4.x"]
33
-
34
- steps:
35
- - uses: actions/checkout@v1
36
- - name: Set up Ruby
37
- uses: actions/setup-ruby@v1
38
- with:
39
- ruby-version: ${{matrix.ruby}}
40
- - name: Bundle install
41
- run: |
42
- gem install bundler
43
- bundle install --jobs 4 --retry 3 --without tools docs benchmarks
44
- - name: Run all tests
45
- run: bundle exec rake
46
-
47
- other-ruby:
48
- runs-on: ubuntu-latest
49
- strategy:
50
- fail-fast: false
51
- matrix:
52
- image: ["jruby:9.2.9", "ruby:2.7"]
53
- container:
54
- image: ${{matrix.image}}
55
-
56
- steps:
57
- - uses: actions/checkout@v1
58
- - name: Install git
59
- run: |
60
- apt-get update
61
- apt-get install -y --no-install-recommends git
62
- - name: Bundle install
63
- run: |
64
- gem install bundler
65
- bundle install --jobs 4 --retry 3 --without tools docs benchmarks
66
- - name: Run all tests
67
- run: bundle exec rake
@@ -1,50 +0,0 @@
1
- name: pages
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
- paths:
8
- - .github/workflows/pages.yml
9
- - lib/**
10
- - README.md
11
- - .yardopts
12
- - Rakefile
13
-
14
- jobs:
15
- build-docs:
16
- runs-on: ubuntu-latest
17
- steps:
18
- - uses: actions/checkout@v2
19
- - name: Set up Ruby
20
- uses: actions/setup-ruby@v1
21
- with:
22
- ruby-version: 2.6.x
23
- - name: Bundle install
24
- run: |
25
- gem install bundler
26
- bundle install --jobs 4 --retry 3 --without tools docs benchmarks
27
- - name: Build docs
28
- run: 'bin/rake docs:yard'
29
- - name: config git
30
- run: |
31
- git config --local user.email "action@github.com"
32
- git config --local user.name "GitHub Action"
33
- - name: Checkout Pages
34
- run: 'git fetch origin gh-pages && git checkout gh-pages'
35
- - name: Replace and commit docs
36
- run: |
37
- rm -rf doc && mv _yardoc doc
38
- git add -A doc
39
- git commit -m"Update API docs"
40
- - name: Replace index
41
- run: |
42
- git checkout master README.md
43
- mv -f README.md index.md
44
- if [ ! -z "$(git diff --name-only -- index.md)" ]; then
45
- git commit index.md -m"update index"
46
- fi
47
- - name: Push
48
- env:
49
- INPUT_GITHUB_TOKEN: "${{ secrets.DEPLOY_TOKEN }}"
50
- run: git push https://git:${INPUT_GITHUB_TOKEN}@github.com/fnordfish/teckel.git gh-pages
data/.gitignore DELETED
@@ -1,13 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
12
-
13
- .rubocop-http*
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
@@ -1,12 +0,0 @@
1
- inherit_from:
2
- - https://relaxed.ruby.style/rubocop.yml
3
-
4
- AllCops:
5
- TargetRubyVersion: 2.4
6
-
7
- Metrics/BlockLength:
8
- Exclude:
9
- - spec/**/*_spec.rb
10
-
11
- Layout/FirstArrayElementIndentation:
12
- EnforcedStyle: consistent
@@ -1 +0,0 @@
1
- ruby-2.6.5
@@ -1,28 +0,0 @@
1
- # Development Guidelines
2
-
3
- - Keep is simple.
4
- - Favor easy debug-ability over clever solutions.
5
- - Aim to be a 0-dependency lib (at runtime)
6
-
7
- ## Roadmap
8
-
9
- - Add "Settings" for Operations and Chains
10
-
11
- ```
12
- MyOp.with(foo: "bar").call("input")
13
-
14
- class MyOp
15
- settings Types::Hash.schema(foo: Types::String)
16
-
17
- def call(input)
18
- input == "input"
19
- settings.foo == "bar"
20
- end
21
- end
22
-
23
- MyCain.with(:step1) { { foo: "bar" } }.with(:stepX) { { another: :setting} }.call(params)
24
- ```
25
- - Add support for around hooks in Chains (for db transactions etc.)
26
- - Add a dry-monads mixin to wrap Operations and Chains result/error into a Result Monad
27
- - ...
28
-
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in teckel.gemspec
8
- gemspec
@@ -1,71 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- teckel (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- concurrent-ruby (1.1.5)
10
- diff-lcs (1.3)
11
- dry-configurable (0.9.0)
12
- concurrent-ruby (~> 1.0)
13
- dry-core (~> 0.4, >= 0.4.7)
14
- dry-container (0.7.2)
15
- concurrent-ruby (~> 1.0)
16
- dry-configurable (~> 0.1, >= 0.1.3)
17
- dry-core (0.4.9)
18
- concurrent-ruby (~> 1.0)
19
- dry-equalizer (0.3.0)
20
- dry-inflector (0.2.0)
21
- dry-logic (1.0.5)
22
- concurrent-ruby (~> 1.0)
23
- dry-core (~> 0.2)
24
- dry-equalizer (~> 0.2)
25
- dry-struct (1.2.0)
26
- dry-core (~> 0.4, >= 0.4.3)
27
- dry-equalizer (~> 0.3)
28
- dry-types (~> 1.0)
29
- ice_nine (~> 0.11)
30
- dry-types (1.2.2)
31
- concurrent-ruby (~> 1.0)
32
- dry-container (~> 0.3)
33
- dry-core (~> 0.4, >= 0.4.4)
34
- dry-equalizer (~> 0.3)
35
- dry-inflector (~> 0.1, >= 0.1.2)
36
- dry-logic (~> 1.0, >= 1.0.2)
37
- ice_nine (0.11.2)
38
- minitest (5.13.0)
39
- rake (13.0.1)
40
- rspec (3.9.0)
41
- rspec-core (~> 3.9.0)
42
- rspec-expectations (~> 3.9.0)
43
- rspec-mocks (~> 3.9.0)
44
- rspec-core (3.9.1)
45
- rspec-support (~> 3.9.1)
46
- rspec-expectations (3.9.0)
47
- diff-lcs (>= 1.2.0, < 2.0)
48
- rspec-support (~> 3.9.0)
49
- rspec-mocks (3.9.1)
50
- diff-lcs (>= 1.2.0, < 2.0)
51
- rspec-support (~> 3.9.0)
52
- rspec-support (3.9.2)
53
- yard (0.9.22)
54
- yard-doctest (0.1.17)
55
- minitest
56
- yard
57
-
58
- PLATFORMS
59
- ruby
60
-
61
- DEPENDENCIES
62
- bundler (~> 2.0)
63
- dry-struct (>= 1.1.1, < 2)
64
- rake (>= 10.0)
65
- rspec (~> 3.0)
66
- teckel!
67
- yard
68
- yard-doctest
69
-
70
- BUNDLED WITH
71
- 2.1.2
data/Rakefile DELETED
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
- require "yard"
6
- require "yard/doctest/rake"
7
-
8
- RSpec::Core::RakeTask.new(:spec)
9
-
10
- namespace :docs do
11
- YARD::Rake::YardocTask.new do |t|
12
- t.files = ['lib/**/*.rb']
13
- t.options = []
14
- t.stats_options = ['--list-undoc']
15
- end
16
-
17
- task :fswatch do
18
- sh 'fswatch -0 lib | while read -d "" e; do rake docs:yard; done'
19
- end
20
-
21
- YARD::Doctest::RakeTask.new do |task|
22
- task.doctest_opts = %w[-v]
23
- task.pattern = Dir.glob('lib/**/*.rb')
24
- end
25
- end
26
-
27
- task :default do
28
- Rake::Task["spec"].invoke
29
- Rake::Task["docs:yard:doctest"].invoke
30
- end
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "teckel"
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
data/bin/rake DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'rake' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path('bundle', __dir__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("rake", "rake")
data/bin/rspec DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'rspec' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path('bundle', __dir__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("rspec-core", "rspec")
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/inline'
5
- require 'bundler'
6
-
7
- # We need the `Bundler.settings.temporary` for a bundler bug:
8
- # https://github.com/bundler/bundler/issues/7114
9
- # Will get fixed in bundler version 2.1.0
10
- Bundler.settings.temporary(frozen: false) do
11
- gemfile do
12
- source 'https://rubygems.org'
13
- gem 'rubocop', '~> 0.78.0'
14
- gem 'relaxed-rubocop', '2.4'
15
- end
16
- end
17
-
18
- load Gem.bin_path("rubocop", "rubocop")
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Teckel
4
- module Operation
5
- # Works just like +Teckel::Operation+, but wraps +output+ and +error+ into a +Teckel::Result+.
6
- #
7
- # A +Teckel::Result+ given as +input+ will get unwrapped, so that the original +value+
8
- # gets passed to your Operation code.
9
- #
10
- # @example
11
- #
12
- # class CreateUser
13
- # include Teckel::Operation::Results
14
- #
15
- # input Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer)
16
- # output Types.Instance(User)
17
- # error Types::Hash.schema(message: Types::String, errors: Types::Array.of(Types::Hash))
18
- #
19
- # # @param [Hash<name: String, age: Integer>]
20
- # # @return [User | Hash<message: String, errors: [Hash]>]
21
- # def call(input)
22
- # user = User.new(name: input[:name], age: input[:age])
23
- # if user.safe
24
- # # exits early with success, prevents any further execution
25
- # success!(user)
26
- # else
27
- # fail!(message: "Could not safe User", errors: user.errors)
28
- # end
29
- # end
30
- # end
31
- #
32
- # # A success call:
33
- # CreateUser.call(name: "Bob", age: 23).is_a?(Teckel::Result) #=> true
34
- # CreateUser.call(name: "Bob", age: 23).success.is_a?(User) #=> true
35
- #
36
- # # A failure call:
37
- # CreateUser.call(name: "Bob", age: 10).is_a?(Teckel::Result) #=> true
38
- # CreateUser.call(name: "Bob", age: 10).failure.is_a?(Hash) #=> true
39
- #
40
- # # Unwrapping success input:
41
- # CreateUser.call(Teckel::Result.new({name: "Bob", age: 23}, true)).success.is_a?(User) #=> true
42
- #
43
- # # Unwrapping failure input:
44
- # CreateUser.call(Teckel::Result.new({name: "Bob", age: 23}, false)).success.is_a?(User) #=> true
45
- #
46
- # @api public
47
- module Results
48
- module InstanceMethods
49
- private
50
-
51
- def build_input(input)
52
- input = input.value if input.is_a?(Teckel::Result)
53
- super(input)
54
- end
55
-
56
- def build_output(*args)
57
- Teckel::Result.new(super, true)
58
- end
59
-
60
- def build_error(*args)
61
- Teckel::Result.new(super, false)
62
- end
63
- end
64
-
65
- def self.included(receiver)
66
- receiver.send :include, Teckel::Operation unless Teckel::Operation >= receiver
67
- receiver.send :include, InstanceMethods
68
- end
69
- end
70
- end
71
- end