kiba-common 0.7.0 → 1.5.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 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