kiba-common 0.7.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73129b07c0c847b9a1ed5b2a88e0fe3b9449200589fea6e0b88696959c86448f
4
- data.tar.gz: 1a73e5414c054fbb233c92c5459087153a6ad413bfa194c192d8ea54cd4ee3ef
3
+ metadata.gz: 7c572e8d0d2cea374d8ee86d54ada3d323dd1087d91c002ef30b565c8dd98199
4
+ data.tar.gz: 1153c67d2bff98455663f4b2859d8af8f723ddab135411e720bc4abdbca3da3b
5
5
  SHA512:
6
- metadata.gz: f984de5843f926e3c153c381a1e05d171275fa185c3b0b2c7d855250b75c6ed85841ad78d87cb55b9cc4d6759e7d50c585765483ef27f0c3c64f80b8a739e957
7
- data.tar.gz: 1e05cefc61c51f474f93b8f331e3d17a1de7c2ec3683212336796e3dcbc164bc9d5bc9049a8f255c25d237a8f8e38516d02db45f343a903d2bd76ad439515330
6
+ metadata.gz: 4cfccbc1d90c83bd202d5bbd996fe02a5599ca0b210921d1d3d7ff1d205ecb2484ebe1a686d3345773dc7298cd86616e8a89ceaa607312cfb495b4b5c41df010
7
+ data.tar.gz: 76fc871cc277824452e94db9545092a8333bf26404151c5a5d5367be6a0d7df0690c834b3a576eedcca79e6299a3947b393f5c502c6ad9041de9f88259ebc12f
@@ -0,0 +1 @@
1
+ github: thbar
@@ -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,55 @@
1
- HEAD
2
- ----
1
+ 1.5.0
2
+ -----
3
+
4
+ - Support for Kiba 4
5
+ - Breaking: Drop support for Ruby < 2.5
6
+ - Breaking: Require Kiba 3+
7
+ - [StandardRB](https://github.com/testdouble/standard) has been added for formatting & linting the codebase.
8
+
9
+
10
+ 1.1.0
11
+ -----
12
+
13
+ - Support for Ruby 2.7+ (affects CSV source and destination)
14
+ - Breaking: `show_me!` is now compatible with both `awesome_print` and its modern replacement `amazing_print`. You will have to `require` the one you want to use in your code from now on.
15
+ - Breaking: `SourceTransformAdapter` has been removed due to complexities with Ruby 2.7+ keyword arguments. The suggested replacement is to use `Enumerator` and `EnumerableExploder` like this:
16
+
17
+ ```ruby
18
+ # before
19
+ transform SourceTransformAdapter
20
+
21
+ # after
22
+ transform do |klass, args|
23
+ Enumerator.new do |y|
24
+ # NOTE: you may have to use double-splat (**) here instead
25
+ # if you provide keyword arguments, or other variants
26
+ klass.new(*args).each do |r|
27
+ y << r
28
+ end
29
+ end
30
+ end
31
+
32
+ transform Kiba::Common::Transforms::EnumerableExploder
33
+ ```
34
+
35
+ 1.0.0
36
+ -----
37
+
38
+ - Kiba ETL v3 compatibility
39
+ - New: Kiba::Common::Destinations::Lambda lets you write block-form destinations (handy for one-off scripts).
40
+
41
+ 0.9.0
42
+ -----
43
+
44
+ - New: Kiba::Common::Sources::CSV provides a basic CSV source for simple needs.
45
+
46
+ 0.8.0
47
+ -----
48
+
49
+ - Bugfix: `show_me!` used with a block should not modify the processed row.
50
+
51
+ 0.7.0
52
+ -----
3
53
 
4
54
  - New: Kiba::Common::Transforms::SourceTransformAdapter let you transform rows into parameters for source instantiation.
5
55
 
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  Kiba Common is a companion gem to [Kiba](https://github.com/thbar/kiba) and [Kiba Pro](https://github.com/thbar/kiba/blob/master/Pro-Changes.md) in which I'll share commonly used helpers.
2
2
 
3
- [![Build Status](https://travis-ci.org/thbar/kiba-common.svg?branch=master)](https://travis-ci.org/thbar/kiba-common) [![Gem Version](https://badge.fury.io/rb/kiba-common.svg)](https://badge.fury.io/rb/kiba-common)
3
+ [![Gem Version](https://badge.fury.io/rb/kiba-common.svg)](https://badge.fury.io/rb/kiba-common)
4
+ [![Build Status](https://github.com/thbar/kiba-common/actions/workflows/ci.yml/badge.svg)](https://github.com/thbar/kiba-common/actions)
4
5
 
5
6
  ## Usage
6
7
 
@@ -14,7 +15,8 @@ Then see below for each module usage & require clause.
14
15
 
15
16
  ## Supported Ruby versions
16
17
 
17
- `kiba-common` currently supports Ruby 2.3+ and JRuby (with its default 1.9 syntax). See [test matrix](https://travis-ci.org/thbar/kiba-common).
18
+ `kiba-common` currently supports Ruby 2.5+, JRuby 9.2+ and TruffleRuby. See [test matrix](https://github.com/thbar/kiba-common/actions).
19
+
18
20
 
19
21
  ## Available components
20
22
 
@@ -48,7 +50,7 @@ But since Kiba v2 introduction of `StreamingRunner`, it is possible for transfor
48
50
 
49
51
  Leveraging that possibility, you can use a `SourceTransformAdapter` to dynamically instantiate the source for each of your input rows.
50
52
 
51
- This allows to mix-and-match components in a much more versatile & powerful way.
53
+ This allows you to mix-and-match components in a much more versatile & powerful way.
52
54
 
53
55
  Requirements: Kiba v2 with `StreamingRunner` enabled.
54
56
 
@@ -85,7 +87,7 @@ require 'kiba-common/transforms/enumerable_exploder'
85
87
  transform Kiba::Common::Transforms::EnumerableExploder
86
88
  ```
87
89
 
88
- For instance, this can help if you are reading XML/JSON documents from a source, and each input document contains multiple rows that you'd want to extract.
90
+ This can help if you are reading XML/JSON documents from a source and each input document contains multiple rows that you want to extract.
89
91
 
90
92
  ```ruby
91
93
  source Kiba::Common::Sources::Enumerable, -> { Dir["input/*.xml"] }
@@ -104,7 +106,7 @@ Similarly, if you have a CSV document as your input:
104
106
  | ------------- | ------------- |
105
107
  | 00001 | John:Mary:Sally |
106
108
 
107
- and you want to reformat it to get this instead:
109
+ and you want to reformat it to the following:
108
110
 
109
111
  | po_number | buyer |
110
112
  |-------------|---------|
@@ -129,17 +131,81 @@ end
129
131
  transform Kiba::Common::Transforms::EnumerableExploder
130
132
  ```
131
133
 
134
+ ### Kiba::Common::Sources::CSV
135
+
136
+ A CSV source for basic needs (in particular, it doesn't yield row metadata, which are useful in more advanced scenarios).
137
+
138
+ Use the `csv_options` keyword to control the input format like when using [Ruby CSV class](http://ruby-doc.org/stdlib-2.4.0/libdoc/csv/rdoc/CSV.html#method-c-new).
139
+
140
+ Usage:
141
+
142
+ ```ruby
143
+ require 'kiba-common/sources/csv'
144
+
145
+ # by defaults, csv_options are empty
146
+ source Kiba::Common::Sources::CSV, filename: 'input.csv'
147
+
148
+ # you can provide your own csv_options
149
+ source Kiba::Common::Sources::CSV, filename: 'input.csv',
150
+ csv_options: { headers: true, header_converters: :symbol }
151
+ ```
152
+
153
+ Note that the emitted rows are instances of [`CSV::Row`](http://ruby-doc.org/stdlib-2.5.3/libdoc/csv/rdoc/CSV/Row.html), part `Array` and part `Hash`, which retain order of fields and allow duplicates (unlike a regular `Hash`).
154
+
155
+ If the rest of your pipeline expects `Hash` rows (like for instance `Kiba::Common::Destinations::CSV`), you'll want to transform the rows to `Hash` instances yourself using [`to_hash`](http://ruby-doc.org/stdlib-2.5.3/libdoc/csv/rdoc/CSV/Row.html#method-i-to_hash). This will "collapse the row into a simple Hash. Be warned that this discards field order and clobbers duplicate fields."
156
+
157
+ ```ruby
158
+ transform { |r| r.to_hash }
159
+ ```
160
+
161
+ #### Handling multiple input CSV files
162
+
163
+ You can process multiple files by chaining the various components available in Kiba Common (see `test/test_integration#test_multiple_csv_inputs` for an actual demo):
164
+
165
+ ```ruby
166
+ # create one row per input filename
167
+ source Kiba::Common::Sources::Enumerable, -> { Dir[File.join(dir, '*.csv')] }
168
+
169
+ # out of that row, create configuration for a CSV source
170
+ transform do |r|
171
+ [
172
+ Kiba::Common::Sources::CSV,
173
+ filename: r,
174
+ csv_options: { headers: true, header_converters: :symbol }
175
+ ]
176
+ end
177
+
178
+ # instantiate & yield CSV rows for each configuration
179
+ transform Kiba::Common::Transforms::SourceTransformAdapter
180
+ ```
181
+
182
+ Alternatively, you can wrap this source in your own source like this:
183
+
184
+ ```ruby
185
+ class MultipleCSVSource
186
+ def initialize(file_pattern:, csv_options:)
187
+
188
+ def each
189
+ Dir[file_pattern].each do |filename|
190
+ Kiba::Common::Sources::CSV.new(filename, csv_options).each do |row|
191
+ yield row
192
+ end
193
+ end
194
+ end
195
+ end
196
+ ```
197
+
132
198
  ### Kiba::Common::Destinations::CSV
133
199
 
134
200
  A way to dump `Hash` rows as CSV.
135
201
 
136
202
  All rows are expected to have the exact same set of keys as the first row.
137
203
 
138
- The headers will be the first row keys, unless you pass an array of keys via `headers`.
204
+ The headers will be the first row keys unless you pass an array of keys via `headers`.
139
205
 
140
- All keys are mandatory (although they can have a nil value).
206
+ All keys are mandatory (although they can have a `nil` value).
141
207
 
142
- Use the `csv_options` keyword to control the output format like you would do when using [Ruby CSV class](http://ruby-doc.org/stdlib-2.4.0/libdoc/csv/rdoc/CSV.html#method-c-new).
208
+ Use the `csv_options` keyword to control the output format like when using [Ruby CSV class](http://ruby-doc.org/stdlib-2.4.0/libdoc/csv/rdoc/CSV.html#method-c-new).
143
209
 
144
210
  Usage:
145
211
 
@@ -161,6 +227,30 @@ destination Kiba::Common::Destinations::CSV,
161
227
  headers: [:field, :other_field]
162
228
  ```
163
229
 
230
+ ### Kiba::Common::Destinations::Lambda
231
+
232
+ At times, it can be convenient to use a block form for a destination (pretty much like Kiba's built-in "block transform"), especially for one-off scripts.
233
+
234
+ The Lambda destination is there for that purpose.
235
+
236
+ Example use:
237
+
238
+ ```ruby
239
+ require 'kiba-common/destinations/lambda'
240
+
241
+ destination Kiba::Common::Destinations::Lambda,
242
+ # called at destination instantiation time (once)
243
+ on_init: -> { ... },
244
+ # called for each row
245
+ on_write: -> (row) { ... },
246
+ # called after all the rows have been written
247
+ on_close: -> { ... }
248
+ ```
249
+
250
+ Each "callback" (e.g. `on_init`) is optional.
251
+
252
+ The callback code can refer to scope variables or instance variables you may have declared above.
253
+
164
254
  ### Kiba::Common::DSLExtensions::Logger
165
255
 
166
256
  A simple logging facility.
@@ -189,7 +279,7 @@ logger = Logger.new(xxx)
189
279
 
190
280
  ### Kiba::Common::DSLExtensions::ShowMe
191
281
 
192
- A way to color-dump rows on the screen, useful at development time while you are looking at the data (requires the `awesome_print` gem).
282
+ A way to color-dump rows on the screen, useful during development when you are inspecting the data (requires either the `amazing_print` or the `awesome_print` gem).
193
283
 
194
284
  Usage:
195
285
 
@@ -212,6 +302,8 @@ show_me! { |r| r.except(:some_noisy_field) }
212
302
 
213
303
  ## Contributing & Legal
214
304
 
305
+ See [LICENSE](LICENSE) for license.
306
+
215
307
  (agreement below borrowed from Sidekiq Legal)
216
308
 
217
309
  By submitting a Pull Request, you disavow any rights or claims to any changes submitted to the Kiba Common project and assign the copyright of those changes to LoGeek SARL.
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
- require 'rake/testtask'
1
+ require "rake/testtask"
2
2
 
3
3
  Rake::TestTask.new(:test) do |t|
4
- t.pattern = 'test/test_*.rb'
4
+ t.pattern = "test/test_*.rb"
5
5
  end
6
6
 
7
7
  task default: :test
data/kiba-common.gemspec CHANGED
@@ -1,21 +1,25 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/kiba-common/version', __FILE__)
1
+ require File.expand_path("../lib/kiba-common/version", __FILE__)
3
2
 
4
3
  Gem::Specification.new do |gem|
5
- gem.authors = ['Thibaut Barrère']
6
- gem.email = ['thibaut.barrere@gmail.com']
7
- gem.description = gem.summary = 'Commonly used helpers for Kiba ETL'
8
- gem.homepage = 'https://github.com/thbar/kiba-common'
9
- gem.license = 'LGPL-3.0'
10
- gem.files = `git ls-files | grep -Ev '^(examples)'`.split("\n")
11
- gem.test_files = `git ls-files -- test/*`.split("\n")
12
- gem.name = 'kiba-common'
13
- gem.require_paths = ['lib']
14
- gem.version = Kiba::Common::VERSION
4
+ gem.authors = ["Thibaut Barrère"]
5
+ gem.email = ["thibaut.barrere@gmail.com"]
6
+ gem.description = gem.summary = "Commonly used helpers for Kiba ETL"
7
+ gem.homepage = "https://github.com/thbar/kiba-common"
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-common"
12
+ gem.require_paths = ["lib"]
13
+ gem.version = Kiba::Common::VERSION
14
+ gem.metadata = {
15
+ "source_code_uri" => "https://github.com/thbar/kiba-common",
16
+ "documentation_uri" => "https://github.com/thbar/kiba-common/blob/master/README.md"
17
+ }
15
18
 
16
- gem.add_dependency 'kiba', '>= 1.0.0', '< 3'
17
- gem.add_development_dependency 'rake'
18
- gem.add_development_dependency 'minitest'
19
- gem.add_development_dependency 'awesome_print'
20
- gem.add_development_dependency 'minitest-focus'
19
+ gem.add_dependency "kiba", ">= 3.0.0", "< 5"
20
+ gem.add_development_dependency "rake"
21
+ gem.add_development_dependency "minitest"
22
+ gem.add_development_dependency "amazing_print"
23
+ gem.add_development_dependency "minitest-focus"
24
+ gem.add_development_dependency "standard"
21
25
  end
@@ -1,28 +1,31 @@
1
- require 'csv'
1
+ require "csv"
2
2
 
3
3
  module Kiba
4
4
  module Common
5
5
  module Destinations
6
6
  class CSV
7
7
  attr_reader :filename, :csv_options, :csv, :headers
8
-
8
+
9
9
  def initialize(filename:, csv_options: nil, headers: nil)
10
10
  @filename = filename
11
11
  @csv_options = csv_options || {}
12
12
  @headers = headers
13
13
  end
14
-
14
+
15
15
  def write(row)
16
- @csv ||= ::CSV.open(filename, 'wb', csv_options)
16
+ @csv ||= ::CSV.open(filename, "wb", **csv_options)
17
17
  @headers ||= row.keys
18
- @headers_written ||= (csv << headers ; true)
18
+ @headers_written ||= begin
19
+ csv << headers
20
+ true
21
+ end
19
22
  csv << row.fetch_values(*@headers)
20
23
  end
21
-
24
+
22
25
  def close
23
26
  csv&.close
24
27
  end
25
28
  end
26
29
  end
27
30
  end
28
- end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Kiba
2
+ module Common
3
+ module Destinations
4
+ class Lambda
5
+ attr_reader :on_write, :on_close
6
+
7
+ def initialize(on_init: nil, on_write: nil, on_close: nil)
8
+ @on_write = on_write
9
+ @on_close = on_close
10
+ on_init&.call
11
+ end
12
+
13
+ def write(row)
14
+ on_write&.call(row)
15
+ end
16
+
17
+ def close
18
+ on_close&.call
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,4 +1,4 @@
1
- require 'logger'
1
+ require "logger"
2
2
 
3
3
  module Kiba
4
4
  module Common
@@ -10,7 +10,7 @@ module Kiba
10
10
  end
11
11
 
12
12
  def logger
13
- @logger ||= self.logger = ::Logger.new(STDOUT)
13
+ @logger ||= self.logger = ::Logger.new($stdout)
14
14
  end
15
15
  end
16
16
  end
@@ -1,17 +1,15 @@
1
- require 'awesome_print'
2
-
3
1
  module Kiba
4
2
  module Common
5
3
  module DSLExtensions
6
4
  # Color print your row.
7
5
  module ShowMe
8
6
  def show_me!(&pre_process)
9
- transform do |row|
10
- row = pre_process ? pre_process.call(row) : row
7
+ transform do |original_row|
8
+ row = pre_process ? pre_process.call(original_row) : original_row
11
9
  # NOTE: invoking Kernel.ap for testing since
12
10
  # ap itself is harder to mock (Kiba Context)
13
11
  Kernel.ap(row)
14
- row
12
+ original_row
15
13
  end
16
14
  end
17
15
  end
@@ -0,0 +1,22 @@
1
+ require "csv"
2
+
3
+ module Kiba
4
+ module Common
5
+ module Sources
6
+ class CSV
7
+ attr_reader :filename, :csv_options
8
+
9
+ def initialize(filename:, csv_options: {})
10
+ @filename = filename
11
+ @csv_options = csv_options
12
+ end
13
+
14
+ def each
15
+ ::CSV.foreach(filename, **csv_options) do |row|
16
+ yield row
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -7,7 +7,7 @@ module Kiba
7
7
  def initialize(enumerable)
8
8
  @enumerable = enumerable
9
9
  end
10
-
10
+
11
11
  def unwrap_enumerable
12
12
  enumerable.respond_to?(:call) ? enumerable.call : enumerable
13
13
  end
@@ -9,4 +9,4 @@ module Kiba
9
9
  end
10
10
  end
11
11
  end
12
- end
12
+ end
@@ -1,5 +1,5 @@
1
1
  module Kiba
2
2
  module Common
3
- VERSION = '0.7.0'
3
+ VERSION = "1.5.0"
4
4
  end
5
5
  end
data/test/helper.rb CHANGED
@@ -1,6 +1,6 @@
1
- require 'minitest/autorun'
2
- require 'minitest/pride'
3
- require 'minitest/focus'
1
+ require "minitest/autorun"
2
+ require "minitest/pride"
3
+ require "minitest/focus"
4
4
 
5
- require 'kiba-common/sources/enumerable'
6
- require_relative 'support/assert_called'
5
+ require "kiba-common/sources/enumerable"
6
+ require_relative "support/assert_called"
@@ -7,4 +7,4 @@ module AssertCalled
7
7
  end
8
8
  mock.verify
9
9
  end
10
- end
10
+ end
@@ -2,8 +2,8 @@ class TestArrayDestination
2
2
  def initialize(array)
3
3
  @array = array
4
4
  end
5
-
5
+
6
6
  def write(row)
7
7
  @array << row
8
8
  end
9
- end
9
+ end
@@ -0,0 +1,9 @@
1
+ class TestHashConfiguredObject
2
+ def initialize(config)
3
+ @config = config
4
+ end
5
+
6
+ def each
7
+ yield(@config)
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class TestKeywordProxySource
2
+ def initialize(mandatory:, optional: nil)
3
+ @mandatory = mandatory
4
+ @optional = optional
5
+ end
6
+
7
+ def each
8
+ yield({
9
+ mandatory: @mandatory,
10
+ optional: @optional
11
+ })
12
+ end
13
+ end
@@ -1,10 +1,10 @@
1
- require_relative 'helper'
2
- require 'kiba'
3
- require 'kiba-common/destinations/csv'
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require "kiba-common/destinations/csv"
4
4
 
5
5
  class TestCSVDestination < Minitest::Test
6
- TEST_FILENAME = 'output.csv'
7
-
6
+ TEST_FILENAME = "output.csv"
7
+
8
8
  def teardown
9
9
  File.delete(TEST_FILENAME) if File.exist?(TEST_FILENAME)
10
10
  end
@@ -21,24 +21,24 @@ class TestCSVDestination < Minitest::Test
21
21
  end
22
22
 
23
23
  Kiba.run(job)
24
-
24
+
25
25
  IO.read(TEST_FILENAME)
26
26
  end
27
-
27
+
28
28
  def test_classic
29
29
  assert_equal <<~CSV, run_etl
30
30
  name,age
31
31
  world,999
32
32
  CSV
33
33
  end
34
-
34
+
35
35
  def test_csv_options
36
- assert_equal <<~CSV, run_etl(csv_options: {col_sep: ';'})
36
+ assert_equal <<~CSV, run_etl(csv_options: {col_sep: ";"})
37
37
  name;age
38
38
  world;999
39
39
  CSV
40
40
  end
41
-
41
+
42
42
  def test_headers_provided
43
43
  assert_equal <<~CSV, run_etl(headers: [:age])
44
44
  age
@@ -0,0 +1,51 @@
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require "kiba-common/sources/csv"
4
+ require_relative "support/test_array_destination"
5
+
6
+ class TestCSVSource < MiniTest::Test
7
+ TEST_FILENAME = "input.csv"
8
+
9
+ def setup
10
+ CSV.open(TEST_FILENAME, "wb") do |csv|
11
+ csv << %w[first_name last_name]
12
+ csv << %w[John Barry]
13
+ csv << %w[Kate Bush]
14
+ end
15
+ end
16
+
17
+ def teardown
18
+ FileUtils.rm(TEST_FILENAME) if File.exist?(TEST_FILENAME)
19
+ end
20
+
21
+ def run_job(args)
22
+ rows = []
23
+ job = Kiba.parse do
24
+ source Kiba::Common::Sources::CSV, **args
25
+ destination TestArrayDestination, rows
26
+ end
27
+ Kiba.run(job)
28
+ rows
29
+ end
30
+
31
+ def test_with_csv_options
32
+ rows = run_job filename: TEST_FILENAME,
33
+ csv_options: {headers: true, header_converters: :symbol}
34
+
35
+ assert_equal [CSV::Row], rows.map(&:class).uniq
36
+ assert_equal([
37
+ {first_name: "John", last_name: "Barry"},
38
+ {first_name: "Kate", last_name: "Bush"}
39
+ ], rows.map(&:to_h))
40
+ end
41
+
42
+ def test_without_csv_options
43
+ rows = run_job(filename: TEST_FILENAME)
44
+
45
+ assert_equal [
46
+ %w[first_name last_name],
47
+ %w[John Barry],
48
+ %w[Kate Bush]
49
+ ], rows
50
+ end
51
+ end
@@ -1,13 +1,13 @@
1
- require_relative 'helper'
2
- require 'kiba'
3
- require_relative 'support/test_array_destination'
4
- require 'kiba-common/transforms/enumerable_exploder'
5
- require 'kiba/dsl_extensions/config'
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require_relative "support/test_array_destination"
4
+ require "kiba-common/transforms/enumerable_exploder"
5
+ require "kiba/dsl_extensions/config"
6
6
 
7
7
  class TestEnumerableExploderTransform < Minitest::Test
8
8
  def test_exploder
9
9
  output = []
10
- input = [[1,2],[3,4,5]]
10
+ input = [[1, 2], [3, 4, 5]]
11
11
 
12
12
  job = Kiba.parse do
13
13
  extend Kiba::DSLExtensions::Config
@@ -18,7 +18,7 @@ class TestEnumerableExploderTransform < Minitest::Test
18
18
  destination TestArrayDestination, output
19
19
  end
20
20
  Kiba.run(job)
21
-
21
+
22
22
  assert_equal input.flatten, output
23
23
  end
24
- end
24
+ end
@@ -1,6 +1,6 @@
1
- require_relative 'helper'
2
- require 'kiba'
3
- require_relative 'support/test_array_destination'
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require_relative "support/test_array_destination"
4
4
 
5
5
  class TestEnumerableSource < Minitest::Test
6
6
  def assert_enumerable_source(input:, expected_output:)
@@ -16,12 +16,12 @@ class TestEnumerableSource < Minitest::Test
16
16
  end
17
17
  Kiba.run(job)
18
18
  end
19
-
19
+
20
20
  def test_source_as_enumerable
21
21
  assert_enumerable_source(input: (1..10), expected_output: (2..20).step(2).to_a)
22
22
  end
23
-
23
+
24
24
  def test_source_as_callable
25
25
  assert_enumerable_source(input: -> { (1..10) }, expected_output: (2..20).step(2).to_a)
26
26
  end
27
- end
27
+ end
@@ -0,0 +1,57 @@
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require_relative "support/test_array_destination"
4
+ require "kiba-common/sources/csv"
5
+ require "kiba-common/destinations/csv"
6
+
7
+ # a testbed to verify & showcase how you can chain multiple components
8
+ class TestIntegration < Minitest::Test
9
+ def write_csv(filename, data)
10
+ d = Kiba::Common::Destinations::CSV.new(filename: filename)
11
+ data.each { |r| d.write(r) }
12
+ d.close
13
+ end
14
+
15
+ def test_multiple_csv_inputs
16
+ Dir.mktmpdir do |dir|
17
+ write_csv File.join(dir, "001.csv"), [first_name: "John"]
18
+ write_csv File.join(dir, "002.csv"), [first_name: "Kate"]
19
+
20
+ rows = []
21
+ job = Kiba.parse do
22
+ # enable the new streaming-runner (for SourceTransformAdapter support)
23
+ extend Kiba::DSLExtensions::Config
24
+ config :kiba, runner: Kiba::StreamingRunner
25
+
26
+ # create one row per input file
27
+ source Kiba::Common::Sources::Enumerable, -> { Dir[File.join(dir, "*.csv")].sort }
28
+
29
+ # out of that row, create configuration for a CSV source
30
+ transform do |r|
31
+ [
32
+ Kiba::Common::Sources::CSV,
33
+ filename: r,
34
+ csv_options: {headers: true, header_converters: :symbol}
35
+ ]
36
+ end
37
+
38
+ transform do |klass, args|
39
+ Enumerator.new do |y|
40
+ klass.new(**args).each do |r|
41
+ y << r
42
+ end
43
+ end
44
+ end
45
+ transform Kiba::Common::Transforms::EnumerableExploder
46
+
47
+ destination TestArrayDestination, rows
48
+ end
49
+ Kiba.run(job)
50
+
51
+ assert_equal([
52
+ {first_name: "John"},
53
+ {first_name: "Kate"}
54
+ ], rows.map(&:to_h))
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require "kiba-common/destinations/lambda"
4
+
5
+ class TestLambdaDestination < MiniTest::Test
6
+ def test_lambda
7
+ accumulator = []
8
+ on_init_called = false
9
+ on_close_called = false
10
+ job = Kiba.parse do
11
+ source Kiba::Common::Sources::Enumerable, ["one", "two"]
12
+ destination Kiba::Common::Destinations::Lambda,
13
+ on_init: -> { on_init_called = true },
14
+ on_write: ->(r) { accumulator << r },
15
+ on_close: -> { on_close_called = true }
16
+ end
17
+ Kiba.run(job)
18
+ assert_equal ["one", "two"], accumulator
19
+ assert_equal true, on_init_called
20
+ assert_equal true, on_close_called
21
+ end
22
+ end
data/test/test_logger.rb CHANGED
@@ -1,6 +1,6 @@
1
- require_relative 'helper'
2
- require 'kiba'
3
- require 'kiba-common/dsl_extensions/logger'
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require "kiba-common/dsl_extensions/logger"
4
4
 
5
5
  class TestLogger < Minitest::Test
6
6
  def test_default_logger
@@ -20,11 +20,11 @@ class TestLogger < Minitest::Test
20
20
  logger = Logger.new(buffer)
21
21
 
22
22
  pre_process do
23
- logger.info 'Logging from pre_process'
23
+ logger.info "Logging from pre_process"
24
24
  end
25
25
  end
26
26
  Kiba.run(job)
27
27
 
28
- assert_includes buffer.string, 'Logging from pre_process'
28
+ assert_includes buffer.string, "Logging from pre_process"
29
29
  end
30
30
  end
data/test/test_show_me.rb CHANGED
@@ -1,6 +1,7 @@
1
- require_relative 'helper'
2
- require 'kiba'
3
- require 'kiba-common/dsl_extensions/show_me'
1
+ require_relative "helper"
2
+ require "kiba"
3
+ require "amazing_print"
4
+ require "kiba-common/dsl_extensions/show_me"
4
5
 
5
6
  class TestShowMe < Minitest::Test
6
7
  include AssertCalled
@@ -8,24 +9,28 @@ class TestShowMe < Minitest::Test
8
9
  def test_show_me
9
10
  job = Kiba.parse do
10
11
  extend Kiba::Common::DSLExtensions::ShowMe
11
- source Kiba::Common::Sources::Enumerable, ['row']
12
+ source Kiba::Common::Sources::Enumerable, ["row"]
12
13
  show_me!
13
14
  end
14
-
15
- assert_called(Kernel, :ap, ['row']) do
15
+
16
+ assert_called(Kernel, :ap, ["row"]) do
16
17
  Kiba.run(job)
17
18
  end
18
19
  end
19
-
20
+
20
21
  def test_show_me_pre_process
22
+ output = []
21
23
  job = Kiba.parse do
22
24
  extend Kiba::Common::DSLExtensions::ShowMe
23
25
  source Kiba::Common::Sources::Enumerable, [{this: "OK", not_this: "KO"}]
24
26
  show_me! { |r| r.fetch(:this) }
27
+ destination TestArrayDestination, output
25
28
  end
26
29
 
27
- assert_called(Kernel, :ap, ['OK']) do
30
+ assert_called(Kernel, :ap, ["OK"]) do
28
31
  Kiba.run(job)
29
32
  end
33
+
34
+ assert_equal [{this: "OK", not_this: "KO"}], output
30
35
  end
31
36
  end
@@ -1,6 +1,11 @@
1
- require_relative 'helper'
2
- require 'kiba-common/transforms/source_transform_adapter'
1
+ require_relative "helper"
2
+ require_relative "support/test_keyword_proxy_source"
3
+ require_relative "support/test_hash_configured_object"
3
4
 
5
+ # NOTE: the SourceTransformAdapter has been removed,
6
+ # but I'm keeping these tests, patched to instead use
7
+ # Enumerator, as a way to verify that the alternative
8
+ # I provided in the change log still works.
4
9
  class TestSourceTransformAdapter < Minitest::Test
5
10
  include Kiba::Common::Sources
6
11
  include Kiba::DSLExtensions
@@ -12,13 +17,72 @@ class TestSourceTransformAdapter < Minitest::Test
12
17
  config :kiba, runner: Kiba::StreamingRunner
13
18
 
14
19
  source Enumerable, [
15
- [ Enumerable, (1..10) ],
16
- [ Enumerable, (11..20) ]
20
+ [Enumerable, (1..10)],
21
+ [Enumerable, (11..20)]
17
22
  ]
18
- transform Kiba::Common::Transforms::SourceTransformAdapter
23
+
24
+ transform do |klass, args|
25
+ Enumerator.new do |y|
26
+ klass.new(args).each do |r|
27
+ y << r
28
+ end
29
+ end
30
+ end
31
+ transform Kiba::Common::Transforms::EnumerableExploder
32
+
19
33
  destination TestArrayDestination, rows
20
34
  end
21
35
  Kiba.run(job)
22
36
  assert_equal (1..20).to_a, rows
23
37
  end
24
- end
38
+
39
+ def test_instantiation_keyword_arguments
40
+ rows = []
41
+ job = Kiba.parse do
42
+ source Enumerable, [
43
+ # Test against a class that expects explicit keyword arguments
44
+ [TestKeywordProxySource, {mandatory: "some value"}]
45
+ ]
46
+
47
+ transform do |klass, args|
48
+ Enumerator.new do |y|
49
+ klass.new(**args).each do |r|
50
+ y << r
51
+ end
52
+ end
53
+ end
54
+ transform Kiba::Common::Transforms::EnumerableExploder
55
+
56
+ destination TestArrayDestination, rows
57
+ end
58
+ Kiba.run(job)
59
+ assert_equal([
60
+ {mandatory: "some value", optional: nil}
61
+ ], rows)
62
+ end
63
+
64
+ def test_hash_configured_object
65
+ rows = []
66
+ job = Kiba.parse do
67
+ source Enumerable, [
68
+ # Test against a class that takes a single Hash argument
69
+ [TestHashConfiguredObject, {mandatory: "some value"}]
70
+ ]
71
+
72
+ transform do |klass, args|
73
+ Enumerator.new do |y|
74
+ klass.new(**args).each do |r|
75
+ y << r
76
+ end
77
+ end
78
+ end
79
+ transform Kiba::Common::Transforms::EnumerableExploder
80
+
81
+ destination TestArrayDestination, rows
82
+ end
83
+ Kiba.run(job)
84
+ assert_equal([
85
+ {mandatory: "some value"}
86
+ ], rows)
87
+ end
88
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kiba-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibaut Barrère
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-06 00:00:00.000000000 Z
11
+ date: 2021-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kiba
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0
19
+ version: 3.0.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '3'
22
+ version: '5'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 1.0.0
29
+ version: 3.0.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '3'
32
+ version: '5'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rake
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -59,7 +59,7 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
- name: awesome_print
62
+ name: amazing_print
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: standard
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
89
103
  description: Commonly used helpers for Kiba ETL
90
104
  email:
91
105
  - thibaut.barrere@gmail.com
@@ -93,8 +107,9 @@ executables: []
93
107
  extensions: []
94
108
  extra_rdoc_files: []
95
109
  files:
110
+ - ".github/FUNDING.yml"
111
+ - ".github/workflows/ci.yml"
96
112
  - ".gitignore"
97
- - ".travis.yml"
98
113
  - Changes.md
99
114
  - Gemfile
100
115
  - LICENSE
@@ -102,26 +117,34 @@ files:
102
117
  - Rakefile
103
118
  - kiba-common.gemspec
104
119
  - lib/kiba-common/destinations/csv.rb
120
+ - lib/kiba-common/destinations/lambda.rb
105
121
  - lib/kiba-common/dsl_extensions/logger.rb
106
122
  - lib/kiba-common/dsl_extensions/show_me.rb
123
+ - lib/kiba-common/sources/csv.rb
107
124
  - lib/kiba-common/sources/enumerable.rb
108
125
  - lib/kiba-common/transforms/enumerable_exploder.rb
109
- - lib/kiba-common/transforms/source_transform_adapter.rb
110
126
  - lib/kiba-common/version.rb
111
127
  - test/helper.rb
112
128
  - test/support/assert_called.rb
113
129
  - test/support/test_array_destination.rb
130
+ - test/support/test_hash_configured_object.rb
131
+ - test/support/test_keyword_proxy_source.rb
114
132
  - test/test_csv_destination.rb
133
+ - test/test_csv_source.rb
115
134
  - test/test_enumerable_exploder_transform.rb
116
135
  - test/test_enumerable_source.rb
136
+ - test/test_integration.rb
137
+ - test/test_lambda_destination.rb
117
138
  - test/test_logger.rb
118
139
  - test/test_show_me.rb
119
140
  - test/test_source_transform_adapter.rb
120
141
  homepage: https://github.com/thbar/kiba-common
121
142
  licenses:
122
143
  - LGPL-3.0
123
- metadata: {}
124
- post_install_message:
144
+ metadata:
145
+ source_code_uri: https://github.com/thbar/kiba-common
146
+ documentation_uri: https://github.com/thbar/kiba-common/blob/master/README.md
147
+ post_install_message:
125
148
  rdoc_options: []
126
149
  require_paths:
127
150
  - lib
@@ -136,18 +159,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
159
  - !ruby/object:Gem::Version
137
160
  version: '0'
138
161
  requirements: []
139
- rubyforge_project:
140
- rubygems_version: 2.7.3
141
- signing_key:
162
+ rubygems_version: 3.2.3
163
+ signing_key:
142
164
  specification_version: 4
143
165
  summary: Commonly used helpers for Kiba ETL
144
166
  test_files:
145
167
  - test/helper.rb
146
168
  - test/support/assert_called.rb
147
169
  - test/support/test_array_destination.rb
170
+ - test/support/test_hash_configured_object.rb
171
+ - test/support/test_keyword_proxy_source.rb
148
172
  - test/test_csv_destination.rb
173
+ - test/test_csv_source.rb
149
174
  - test/test_enumerable_exploder_transform.rb
150
175
  - test/test_enumerable_source.rb
176
+ - test/test_integration.rb
177
+ - test/test_lambda_destination.rb
151
178
  - test/test_logger.rb
152
179
  - test/test_show_me.rb
153
180
  - test/test_source_transform_adapter.rb
data/.travis.yml DELETED
@@ -1,11 +0,0 @@
1
- language: ruby
2
- before_install:
3
- # https://stackoverflow.com/a/47972768
4
- - gem update --system
5
- - gem update bundler
6
- rvm:
7
- - ruby-head
8
- - 2.5.0
9
- - 2.4.3
10
- - 2.3.6
11
- - jruby-9.1.15.0
@@ -1,14 +0,0 @@
1
- module Kiba
2
- module Common
3
- module Transforms
4
- class SourceTransformAdapter
5
- def process(args)
6
- args.shift.new(*args).each do |row|
7
- yield(row)
8
- end
9
- nil
10
- end
11
- end
12
- end
13
- end
14
- end