kiba 3.6.0 → 4.0.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/ci.yml +41 -0
- data/Changes.md +8 -2
- data/Gemfile +1 -1
- data/README.md +2 -2
- data/Rakefile +2 -2
- data/kiba.gemspec +19 -20
- data/lib/kiba.rb +7 -10
- data/lib/kiba/context.rb +5 -5
- data/lib/kiba/control.rb +1 -1
- data/lib/kiba/dsl_extensions/config.rb +1 -1
- data/lib/kiba/streaming_runner.rb +57 -5
- data/lib/kiba/version.rb +1 -1
- data/test/helper.rb +8 -8
- data/test/shared_runner_tests.rb +43 -44
- data/test/support/shared_tests.rb +1 -1
- data/test/support/test_aggregate_transform.rb +2 -2
- data/test/support/test_array_destination.rb +2 -2
- data/test/support/test_csv_destination.rb +2 -2
- data/test/support/test_csv_source.rb +1 -1
- data/test/support/test_destination_returning_nil.rb +3 -3
- data/test/support/test_duplicate_row_transform.rb +1 -1
- data/test/support/test_keyword_arguments_component.rb +1 -1
- data/test/support/test_mixed_arguments_component.rb +2 -2
- data/test/support/test_yielding_transform.rb +1 -1
- data/test/test_integration.rb +36 -31
- data/test/test_parser.rb +16 -17
- data/test/test_run.rb +6 -7
- data/test/test_streaming_runner.rb +23 -23
- metadata +19 -11
- data/.travis.yml +0 -13
- data/appveyor.yml +0 -29
- data/bin/kiba +0 -15
- data/lib/kiba/runner.rb +0 -74
- data/test/test_runner.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f6a466478d2837d085445593c36b2af804e53d29c8046fd4f71b6786f84fedc8
|
|
4
|
+
data.tar.gz: 99d67dd7c6ab706ba12d79031684bbd6b6f2099409beac0bf1cb9593e987a2e8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 71765fe5a8dccd2b9db96b88919958c99b0010f117944bfffe8916ac81348c538306d58d0cdaa6e64e3605bd6714f2d7d223e32deed52446d94738d69895a2f9
|
|
7
|
+
data.tar.gz: ebb45df0fe69b0513efdfd07af38c63b15fa7f881068c11a53d5649d22d0f421aa1a17f2d48363188d41cfa30c1794d4c95ad752808ac2350f93d20523b1939e
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI build
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
build:
|
|
5
|
+
strategy:
|
|
6
|
+
fail-fast: false
|
|
7
|
+
matrix:
|
|
8
|
+
os: [ubuntu-latest]
|
|
9
|
+
ruby:
|
|
10
|
+
- '2.5'
|
|
11
|
+
- '2.6'
|
|
12
|
+
- '2.7'
|
|
13
|
+
- '3.0'
|
|
14
|
+
- head
|
|
15
|
+
- jruby
|
|
16
|
+
- jruby-head
|
|
17
|
+
- truffleruby
|
|
18
|
+
- truffleruby-head
|
|
19
|
+
runs-on: ${{ matrix.os }}
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v2
|
|
22
|
+
- uses: ruby/setup-ruby@v1
|
|
23
|
+
with:
|
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
|
25
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
26
|
+
- run: bundle exec rake
|
|
27
|
+
# NOTE: calling "bundle install" because the cache apparently did not update due to the gemspec injection
|
|
28
|
+
- run: bundle install && bundle exec standardrb
|
|
29
|
+
if: matrix.ruby == '3.0' # not using "head" because rubocop won't work there yet
|
|
30
|
+
# What's below helps having a single "status check" for mergeability, without
|
|
31
|
+
# having to add each new version to the list of expected status checks in GitHub.
|
|
32
|
+
# See https://github.community/t/status-check-for-a-matrix-jobs/127354/7
|
|
33
|
+
global:
|
|
34
|
+
if: ${{ always() }}
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
name: build (matrix)
|
|
37
|
+
needs: build
|
|
38
|
+
steps:
|
|
39
|
+
- name: Check build matrix status
|
|
40
|
+
if: ${{ needs.build.result != 'success' }}
|
|
41
|
+
run: exit 1
|
data/Changes.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
4.0.0
|
|
2
|
+
-----
|
|
3
|
+
|
|
4
|
+
- Breaking: Ruby 2.4 (EOL since 2020-03-31) is not officially supported anymore.
|
|
5
|
+
- CI changes: moving from Travis CI (EOL) to GitHub actions. The Windows CI has been removed for now (see [#97](https://github.com/thbar/kiba/pull/97))
|
|
6
|
+
- Breaking: if your jobs use Kiba's "legacy runner" via `config :kiba, runner: Kiba::Runner`, be aware that this legacy runner has been removed in [#96](https://github.com/thbar/kiba/pull/96). The upgrade path is to remove this config line and let Kiba use the more modern `Kiba::StreamingRunner`, which is the default anyway since Kiba v3.0.0 (see [#83](https://github.com/thbar/kiba/pull/83) for context) and is normally fully backward-compatible.
|
|
7
|
+
- Cleanup: in Kiba v3, the `kiba` shell command had been deprecated and replaced by a simple stub printing a warning to STDERR. It is now removed for good.
|
|
8
|
+
- [StandardRB](https://github.com/testdouble/standard) has been added for formatting & linting the codebase.
|
|
3
9
|
|
|
4
10
|
3.6.0
|
|
5
11
|
-----
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Kiba ETL
|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/kiba)
|
|
4
|
-
[](https://github.com/thbar/kiba/actions) [](https://codeclimate.com/github/thbar/kiba)
|
|
5
5
|
|
|
6
6
|
Writing reliable, concise, well-tested & maintainable data-processing code is tricky.
|
|
7
7
|
|
|
@@ -19,7 +19,7 @@ You can also check out the [author blog](https://thibautbarrere.com) and [StackO
|
|
|
19
19
|
|
|
20
20
|
## Supported Ruby versions
|
|
21
21
|
|
|
22
|
-
Kiba currently supports Ruby 2.
|
|
22
|
+
Kiba currently supports Ruby 2.5+, JRuby 9.2+ and TruffleRuby. See [test matrix](https://github.com/thbar/kiba/actions).
|
|
23
23
|
|
|
24
24
|
## ETL consulting & commercial version
|
|
25
25
|
|
data/Rakefile
CHANGED
data/kiba.gemspec
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
require File.expand_path('../lib/kiba/version', __FILE__)
|
|
1
|
+
require File.expand_path("../lib/kiba/version", __FILE__)
|
|
3
2
|
|
|
4
3
|
Gem::Specification.new do |gem|
|
|
5
|
-
gem.authors
|
|
6
|
-
gem.email
|
|
7
|
-
gem.description
|
|
8
|
-
gem.homepage
|
|
9
|
-
gem.license
|
|
10
|
-
gem.files
|
|
11
|
-
gem.test_files
|
|
12
|
-
gem.name
|
|
13
|
-
gem.require_paths = [
|
|
14
|
-
gem.version
|
|
15
|
-
gem.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
'documentation_uri' => 'https://github.com/thbar/kiba/wiki',
|
|
4
|
+
gem.authors = ["Thibaut Barrère"]
|
|
5
|
+
gem.email = ["thibaut.barrere@gmail.com"]
|
|
6
|
+
gem.description = gem.summary = "Lightweight ETL for Ruby"
|
|
7
|
+
gem.homepage = "https://www.kiba-etl.org"
|
|
8
|
+
gem.license = "LGPL-3.0"
|
|
9
|
+
gem.files = `git ls-files | grep -Ev '^(examples)'`.split("\n")
|
|
10
|
+
gem.test_files = `git ls-files -- test/*`.split("\n")
|
|
11
|
+
gem.name = "kiba"
|
|
12
|
+
gem.require_paths = ["lib"]
|
|
13
|
+
gem.version = Kiba::VERSION
|
|
14
|
+
gem.metadata = {
|
|
15
|
+
"source_code_uri" => "https://github.com/thbar/kiba",
|
|
16
|
+
"documentation_uri" => "https://github.com/thbar/kiba/wiki"
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
gem.add_development_dependency
|
|
22
|
-
gem.add_development_dependency
|
|
23
|
-
gem.add_development_dependency
|
|
24
|
-
gem.add_development_dependency
|
|
19
|
+
gem.add_development_dependency "rake"
|
|
20
|
+
gem.add_development_dependency "minitest", "~> 5.9"
|
|
21
|
+
gem.add_development_dependency "awesome_print"
|
|
22
|
+
gem.add_development_dependency "minitest-focus"
|
|
23
|
+
gem.add_development_dependency "standard"
|
|
25
24
|
end
|
data/lib/kiba.rb
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
require 'kiba/version'
|
|
1
|
+
require "kiba/version"
|
|
3
2
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require 'kiba/dsl_extensions/config'
|
|
3
|
+
require "kiba/control"
|
|
4
|
+
require "kiba/context"
|
|
5
|
+
require "kiba/parser"
|
|
6
|
+
require "kiba/streaming_runner"
|
|
7
|
+
require "kiba/dsl_extensions/config"
|
|
10
8
|
|
|
11
9
|
Kiba.extend(Kiba::Parser)
|
|
12
10
|
|
|
13
11
|
module Kiba
|
|
14
12
|
def self.run(job = nil, &block)
|
|
15
|
-
unless
|
|
13
|
+
unless job.nil? ^ block.nil?
|
|
16
14
|
fail ArgumentError.new("Kiba.run takes either one argument (the job) or a block (defining the job)")
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
job ||= Kiba.parse { instance_exec(&block) }
|
|
20
18
|
|
|
21
|
-
# NOTE: use Hash#dig when Ruby 2.2 reaches EOL
|
|
22
19
|
runner = job.config.fetch(:kiba, {}).fetch(:runner, Kiba::StreamingRunner)
|
|
23
20
|
runner.run(job)
|
|
24
21
|
end
|
data/lib/kiba/context.rb
CHANGED
|
@@ -5,23 +5,23 @@ module Kiba
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def pre_process(&block)
|
|
8
|
-
@control.pre_processes << {
|
|
8
|
+
@control.pre_processes << {block: block}
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def source(klass, *initialization_params)
|
|
12
|
-
@control.sources << {
|
|
12
|
+
@control.sources << {klass: klass, args: initialization_params}
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def transform(klass = nil, *initialization_params, &block)
|
|
16
|
-
@control.transforms << {
|
|
16
|
+
@control.transforms << {klass: klass, args: initialization_params, block: block}
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def destination(klass, *initialization_params)
|
|
20
|
-
@control.destinations << {
|
|
20
|
+
@control.destinations << {klass: klass, args: initialization_params}
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def post_process(&block)
|
|
24
|
-
@control.post_processes << {
|
|
24
|
+
@control.post_processes << {block: block}
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
[:source, :transform, :destination].each do |m|
|
data/lib/kiba/control.rb
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
module Kiba
|
|
2
2
|
module StreamingRunner
|
|
3
|
-
include Runner
|
|
4
3
|
extend self
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
# allow to handle a block form just like a regular transform
|
|
6
|
+
class AliasingProc < Proc
|
|
7
|
+
alias_method :process, :call
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run(control)
|
|
11
|
+
run_pre_processes(control)
|
|
12
|
+
process_rows(
|
|
13
|
+
to_instances(control.sources),
|
|
14
|
+
to_instances(control.transforms, true),
|
|
15
|
+
destinations = to_instances(control.destinations)
|
|
16
|
+
)
|
|
17
|
+
close_destinations(destinations)
|
|
18
|
+
run_post_processes(control)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def run_pre_processes(control)
|
|
22
|
+
to_instances(control.pre_processes, true, false).each(&:call)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def run_post_processes(control)
|
|
26
|
+
to_instances(control.post_processes, true, false).each(&:call)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def close_destinations(destinations)
|
|
30
|
+
destinations
|
|
31
|
+
.find_all { |d| d.respond_to?(:close) }
|
|
32
|
+
.each(&:close)
|
|
33
|
+
end
|
|
34
|
+
|
|
6
35
|
def transform_stream(stream, t)
|
|
7
36
|
Enumerator.new do |y|
|
|
8
37
|
stream.each do |input_row|
|
|
@@ -18,7 +47,7 @@ module Kiba
|
|
|
18
47
|
end
|
|
19
48
|
end
|
|
20
49
|
end
|
|
21
|
-
|
|
50
|
+
|
|
22
51
|
def source_stream(sources)
|
|
23
52
|
Enumerator.new do |y|
|
|
24
53
|
sources.each do |source|
|
|
@@ -29,10 +58,33 @@ module Kiba
|
|
|
29
58
|
|
|
30
59
|
def process_rows(sources, transforms, destinations)
|
|
31
60
|
stream = source_stream(sources)
|
|
32
|
-
recurser = lambda { |s,t| transform_stream(s, t) }
|
|
61
|
+
recurser = lambda { |s, t| transform_stream(s, t) }
|
|
33
62
|
transforms.inject(stream, &recurser).each do |r|
|
|
34
63
|
destinations.each { |d| d.write(r) }
|
|
35
64
|
end
|
|
36
65
|
end
|
|
66
|
+
|
|
67
|
+
def to_instances(definitions, allow_block = false, allow_class = true)
|
|
68
|
+
definitions.map do |definition|
|
|
69
|
+
to_instance(
|
|
70
|
+
*definition.values_at(:klass, :args, :block),
|
|
71
|
+
allow_block, allow_class
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def to_instance(klass, args, block, allow_block, allow_class)
|
|
77
|
+
if klass && block
|
|
78
|
+
fail "Class and block form cannot be used together at the moment"
|
|
79
|
+
elsif klass
|
|
80
|
+
fail "Class form is not allowed here" unless allow_class
|
|
81
|
+
klass.new(*args)
|
|
82
|
+
elsif block
|
|
83
|
+
fail "Block form is not allowed here" unless allow_block
|
|
84
|
+
AliasingProc.new(&block)
|
|
85
|
+
else
|
|
86
|
+
fail "Nil parameters not allowed here"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
37
89
|
end
|
|
38
|
-
end
|
|
90
|
+
end
|
data/lib/kiba/version.rb
CHANGED
data/test/helper.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require "minitest/autorun"
|
|
2
|
+
require "minitest/pride"
|
|
3
|
+
require "minitest/focus"
|
|
4
|
+
require "kiba"
|
|
5
5
|
|
|
6
|
-
if ENV[
|
|
6
|
+
if ENV["CI"] == "true"
|
|
7
7
|
puts "Running with MiniTest version #{MiniTest::VERSION}"
|
|
8
8
|
end
|
|
9
9
|
|
|
@@ -15,10 +15,10 @@ class Kiba::Test < Minitest::Test
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def fixture(file)
|
|
18
|
-
File.join(File.dirname(__FILE__),
|
|
18
|
+
File.join(File.dirname(__FILE__), "fixtures", file)
|
|
19
19
|
end
|
|
20
|
-
|
|
21
|
-
unless
|
|
20
|
+
|
|
21
|
+
unless method_defined?(:assert_mock)
|
|
22
22
|
def assert_mock(mock)
|
|
23
23
|
mock.verify
|
|
24
24
|
end
|
data/test/shared_runner_tests.rb
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
require
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
1
|
+
require "minitest/mock"
|
|
2
|
+
require_relative "support/test_enumerable_source"
|
|
3
|
+
require_relative "support/test_destination_returning_nil"
|
|
4
4
|
|
|
5
5
|
module SharedRunnerTests
|
|
6
6
|
def rows
|
|
7
7
|
@rows ||= [
|
|
8
|
-
{
|
|
9
|
-
{
|
|
8
|
+
{identifier: "first-row"},
|
|
9
|
+
{identifier: "second-row"}
|
|
10
10
|
]
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
def control
|
|
14
14
|
@control ||= begin
|
|
15
15
|
control = Kiba::Control.new
|
|
@@ -21,18 +21,18 @@ module SharedRunnerTests
|
|
|
21
21
|
control
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
def test_block_transform_processing
|
|
26
26
|
# is there a better way to assert a block was called in minitest?
|
|
27
|
-
control.transforms << {
|
|
27
|
+
control.transforms << {block: lambda { |r| (@called = true) && (return r) }}
|
|
28
28
|
kiba_run(control)
|
|
29
29
|
assert_equal true, @called
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def test_dismissed_row_not_passed_to_next_transform
|
|
33
33
|
@called = nil
|
|
34
|
-
control.transforms << {
|
|
35
|
-
control.transforms << {
|
|
34
|
+
control.transforms << {block: lambda { |_| }}
|
|
35
|
+
control.transforms << {block: lambda { |_| (@called = true) && (return nil) }}
|
|
36
36
|
kiba_run(control)
|
|
37
37
|
assert_nil @called
|
|
38
38
|
end
|
|
@@ -40,23 +40,23 @@ module SharedRunnerTests
|
|
|
40
40
|
def test_post_process_runs_once
|
|
41
41
|
assert_equal 2, rows.size
|
|
42
42
|
@called = 0
|
|
43
|
-
control.post_processes << {
|
|
43
|
+
control.post_processes << {block: lambda { @called += 1 }}
|
|
44
44
|
kiba_run(control)
|
|
45
45
|
assert_equal 1, @called
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def test_post_process_not_called_after_row_failure
|
|
49
49
|
@called = nil
|
|
50
|
-
control.transforms << {
|
|
51
|
-
control.post_processes << {
|
|
52
|
-
assert_raises(RuntimeError,
|
|
50
|
+
control.transforms << {block: lambda { |_| fail "FAIL" }}
|
|
51
|
+
control.post_processes << {block: lambda { @called = true }}
|
|
52
|
+
assert_raises(RuntimeError, "FAIL") { kiba_run(control) }
|
|
53
53
|
assert_nil @called
|
|
54
54
|
end
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
def test_pre_process_runs_once
|
|
57
57
|
assert_equal 2, rows.size
|
|
58
58
|
@called = 0
|
|
59
|
-
control.pre_processes << {
|
|
59
|
+
control.pre_processes << {block: lambda { @called += 1 }}
|
|
60
60
|
kiba_run(control)
|
|
61
61
|
assert_equal 1, @called
|
|
62
62
|
end
|
|
@@ -70,27 +70,27 @@ module SharedRunnerTests
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
control = Kiba::Control.new
|
|
73
|
-
control.pre_processes << {
|
|
74
|
-
control.sources << {
|
|
73
|
+
control.pre_processes << {block: lambda { calls << :pre_processor_executed }}
|
|
74
|
+
control.sources << {klass: mock_source_class}
|
|
75
75
|
kiba_run(control)
|
|
76
76
|
|
|
77
77
|
assert_equal [:pre_processor_executed, :source_instantiated], calls
|
|
78
78
|
assert_mock mock_source_class
|
|
79
79
|
end
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
def test_no_error_raised_if_destination_close_not_implemented
|
|
82
82
|
# NOTE: this fake destination does not implement `close`
|
|
83
83
|
destination_instance = MiniTest::Mock.new
|
|
84
84
|
|
|
85
85
|
mock_destination_class = MiniTest::Mock.new
|
|
86
86
|
mock_destination_class.expect(:new, destination_instance)
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
control = Kiba::Control.new
|
|
89
|
-
control.destinations << {
|
|
89
|
+
control.destinations << {klass: mock_destination_class}
|
|
90
90
|
kiba_run(control)
|
|
91
91
|
assert_mock mock_destination_class
|
|
92
92
|
end
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
def test_destination_close_called_if_defined
|
|
95
95
|
destination_instance = MiniTest::Mock.new
|
|
96
96
|
destination_instance.expect(:close, nil)
|
|
@@ -98,54 +98,53 @@ module SharedRunnerTests
|
|
|
98
98
|
mock_destination_class.expect(:new, destination_instance)
|
|
99
99
|
|
|
100
100
|
control = Kiba::Control.new
|
|
101
|
-
control.destinations << {
|
|
101
|
+
control.destinations << {klass: mock_destination_class}
|
|
102
102
|
kiba_run(control)
|
|
103
103
|
assert_mock destination_instance
|
|
104
104
|
assert_mock mock_destination_class
|
|
105
105
|
end
|
|
106
|
-
|
|
106
|
+
|
|
107
107
|
def test_use_next_to_exit_early_from_block_transform
|
|
108
108
|
assert_equal 2, rows.size
|
|
109
109
|
|
|
110
110
|
# calling "return row" from a block is forbidden, but you can use "next" instead
|
|
111
111
|
b = lambda do |row|
|
|
112
|
-
if row.fetch(:identifier) ==
|
|
112
|
+
if row.fetch(:identifier) == "first-row"
|
|
113
113
|
# demonstrate how to remove a row from the pipeline via next
|
|
114
114
|
next
|
|
115
115
|
else
|
|
116
116
|
# demonstrate how you can reformat via next
|
|
117
117
|
next({new_identifier: row.fetch(:identifier)})
|
|
118
118
|
end
|
|
119
|
-
fail "This should not be called"
|
|
120
119
|
end
|
|
121
|
-
control.transforms << {
|
|
120
|
+
control.transforms << {block: b}
|
|
122
121
|
|
|
123
122
|
# keep track of the rows
|
|
124
123
|
@remaining_rows = []
|
|
125
|
-
checker = lambda { |row| @remaining_rows << row
|
|
126
|
-
control.transforms << {
|
|
124
|
+
checker = lambda { |row| (@remaining_rows << row) && (return row) }
|
|
125
|
+
control.transforms << {block: checker}
|
|
127
126
|
|
|
128
127
|
kiba_run(control)
|
|
129
|
-
|
|
128
|
+
|
|
130
129
|
# the first row should have been removed
|
|
131
130
|
# and the second row should have been reformatted
|
|
132
|
-
assert_equal [{new_identifier:
|
|
131
|
+
assert_equal [{new_identifier: "second-row"}], @remaining_rows
|
|
133
132
|
end
|
|
134
|
-
|
|
133
|
+
|
|
135
134
|
def test_destination_returning_nil_does_not_remove_row_from_pipeline
|
|
136
135
|
# safeguard to avoid modification on the support code
|
|
137
136
|
assert_nil TestDestinationReturningNil.new.write("FOOBAR")
|
|
138
137
|
|
|
139
138
|
destinations = []
|
|
140
139
|
control = Kiba.parse do
|
|
141
|
-
source TestEnumerableSource, [{key:
|
|
140
|
+
source TestEnumerableSource, [{key: "value"}]
|
|
142
141
|
2.times do
|
|
143
142
|
destination TestDestinationReturningNil, on_init: lambda { |d| destinations << d }
|
|
144
143
|
end
|
|
145
144
|
end
|
|
146
145
|
kiba_run(control)
|
|
147
146
|
2.times do |i|
|
|
148
|
-
assert_equal [{key:
|
|
147
|
+
assert_equal [{key: "value"}], destinations[i].instance_variable_get(:@written_rows)
|
|
149
148
|
end
|
|
150
149
|
end
|
|
151
150
|
|
|
@@ -153,11 +152,11 @@ module SharedRunnerTests
|
|
|
153
152
|
control = Kiba.parse do
|
|
154
153
|
transform
|
|
155
154
|
end
|
|
156
|
-
assert_raises(RuntimeError,
|
|
155
|
+
assert_raises(RuntimeError, "Nil parameters not allowed here") { kiba_run(control) }
|
|
157
156
|
end
|
|
158
157
|
|
|
159
158
|
def test_ruby_3_source_kwargs
|
|
160
|
-
# NOTE: before Ruby 3 kwargs support, a Ruby warning would
|
|
159
|
+
# NOTE: before Ruby 3 kwargs support, a Ruby warning would
|
|
161
160
|
# be captured here with Ruby 2.7 & ensure we fail,
|
|
162
161
|
# and an error would be raised with Ruby 2.8.0-dev
|
|
163
162
|
# NOTE: only the first warning will be captured, though, but
|
|
@@ -167,7 +166,7 @@ module SharedRunnerTests
|
|
|
167
166
|
Kiba.run(Kiba.parse do
|
|
168
167
|
source TestKeywordArgumentsComponent,
|
|
169
168
|
mandatory: "first",
|
|
170
|
-
on_init: ->
|
|
169
|
+
on_init: ->(values) { storage = values }
|
|
171
170
|
end)
|
|
172
171
|
end
|
|
173
172
|
assert_equal({
|
|
@@ -175,14 +174,14 @@ module SharedRunnerTests
|
|
|
175
174
|
optional: nil
|
|
176
175
|
}, storage)
|
|
177
176
|
end
|
|
178
|
-
|
|
177
|
+
|
|
179
178
|
def test_ruby_3_transform_kwargs
|
|
180
179
|
storage = nil
|
|
181
180
|
assert_silent do
|
|
182
181
|
Kiba.run(Kiba.parse do
|
|
183
182
|
transform TestKeywordArgumentsComponent,
|
|
184
183
|
mandatory: "first",
|
|
185
|
-
on_init: ->
|
|
184
|
+
on_init: ->(values) { storage = values }
|
|
186
185
|
end)
|
|
187
186
|
end
|
|
188
187
|
assert_equal({
|
|
@@ -190,14 +189,14 @@ module SharedRunnerTests
|
|
|
190
189
|
optional: nil
|
|
191
190
|
}, storage)
|
|
192
191
|
end
|
|
193
|
-
|
|
192
|
+
|
|
194
193
|
def test_ruby_3_destination_kwargs
|
|
195
194
|
storage = nil
|
|
196
195
|
assert_silent do
|
|
197
196
|
Kiba.run(Kiba.parse do
|
|
198
197
|
destination TestKeywordArgumentsComponent,
|
|
199
198
|
mandatory: "first",
|
|
200
|
-
on_init: ->
|
|
199
|
+
on_init: ->(values) { storage = values }
|
|
201
200
|
end)
|
|
202
201
|
end
|
|
203
202
|
assert_equal({
|
|
@@ -205,7 +204,7 @@ module SharedRunnerTests
|
|
|
205
204
|
optional: nil
|
|
206
205
|
}, storage)
|
|
207
206
|
end
|
|
208
|
-
|
|
207
|
+
|
|
209
208
|
def test_positional_plus_keyword_arguments
|
|
210
209
|
storage = nil
|
|
211
210
|
assert_silent do
|
|
@@ -213,12 +212,12 @@ module SharedRunnerTests
|
|
|
213
212
|
source TestMixedArgumentsComponent,
|
|
214
213
|
"some positional argument",
|
|
215
214
|
mandatory: "first",
|
|
216
|
-
on_init: ->
|
|
215
|
+
on_init: ->(values) {
|
|
217
216
|
storage = values
|
|
218
217
|
}
|
|
219
218
|
end)
|
|
220
219
|
end
|
|
221
|
-
|
|
220
|
+
|
|
222
221
|
assert_equal({
|
|
223
222
|
some_value: "some positional argument",
|
|
224
223
|
mandatory: "first",
|