teckel 0.1.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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