dwf 0.1.2 → 0.1.6

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: 318788f2a1f0820af97211b73ee08e771e23d986073b470858f752005b4cab8b
4
- data.tar.gz: e7c8ae57c3cd2180e890077cf8acc8c63ea93fab73c4bddf62374cc7f98a96be
3
+ metadata.gz: a08560cdfefa1c9f8e1f42416599e94550de0f0e1492bb5b05424e2bf94a482f
4
+ data.tar.gz: 84a83b6849b64e7fe5da74f5734e2d8faa96df25eef63a5d0de78229fcc733ba
5
5
  SHA512:
6
- metadata.gz: c564de1939d9b93f5ee7fd1c65bec7ac166c7d0997792a6d1031ec6beb7541e2fb2d94935df29948ff2e7e0ac45a962dee8e47ec524192f5c406748d4ca48af7
7
- data.tar.gz: '079decbb4e369b9518d6de5ffd3a37f76ae1df1628ba46bac239fd05c1d30e40dfa203593faee106913eea1ac33a010ce4c895e80e19f17f504374c7ae17941b'
6
+ metadata.gz: 6eb847d86872dfa70c1a602a3ae8ef0e0ca166cfa22d0a5e3706454ef0144ac434b48489a916d811e9dc66ebb9ef4979b00b63dee8da4d08c44af6d1bd714dad
7
+ data.tar.gz: cda011bc87919531f5de78721c3640c2460119cb4dd5668bd4ebb8093e19d46e848d27cfc2112c10021bd41e52e2365ced092f779a25a1509086fdf7095221a9
@@ -0,0 +1,41 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ # Manually publish
5
+ workflow_dispatch:
6
+ # Alternatively, publish whenever changes are merged to the `main` branch.
7
+ push:
8
+ branches: [ master ]
9
+ paths:
10
+ - 'dwf.gemspec'
11
+ pull_request:
12
+ branches: [ master ]
13
+ paths:
14
+ - 'dwf.gemspec'
15
+
16
+ jobs:
17
+ build:
18
+ name: Build + Publish
19
+ runs-on: ubuntu-latest
20
+ permissions:
21
+ packages: write
22
+ contents: read
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby 3.0.0
27
+ uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
28
+ with:
29
+ ruby-version: 3.0.0
30
+ - run: bundle install
31
+
32
+ - name: Publish to RubyGems
33
+ run: |
34
+ mkdir -p $HOME/.gem
35
+ touch $HOME/.gem/credentials
36
+ chmod 0600 $HOME/.gem/credentials
37
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
38
+ gem build *.gemspec
39
+ gem push *.gem
40
+ env:
41
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,25 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '**'
7
+ pull_request:
8
+ branches:
9
+ - '**'
10
+
11
+ jobs:
12
+ test:
13
+
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
20
+ with:
21
+ ruby-version: 3.0.0
22
+ - name: Install dependencies
23
+ run: bundle install
24
+ - name: Run tests
25
+ run: bundle exec rspec --require spec_helper
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
data/CHANGELOG.md ADDED
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+ ## 0.1.6
4
+ ### Added
5
+ - Sidekiq batch callback: separate batches
6
+
7
+ ## 0.1.5
8
+ ### Added
9
+ - add github action with build and public gem flow
10
+
11
+ ## 0.1.4
12
+ ### Added
13
+ - Add testes
14
+ - add github action
15
+
16
+ ### Fixed
17
+ - Remove Sidekiq pro by default
18
+
19
+ ---
20
+ ## 0.1.3
21
+ ### Added
22
+ - Support both build in and [Sidekiq batches](https://github.com/mperham/sidekiq/wiki/Batches) callback
23
+ - Update readme
24
+
25
+ ### Fixed
26
+ - Fix bug require development gem
27
+
28
+ ---
29
+ ## 0.1.2
30
+ ### Added
31
+ - Support [Sidekiq batches](https://github.com/mperham/sidekiq/wiki/Batches) callback
32
+ - Update readme
33
+
34
+ ### Fixed
35
+ - fix typo and remove development gem
36
+
37
+ ---
38
+ ## 0.1.0
39
+ ### Added
40
+ - init app with basic idea following [Gush](https://github.com/chaps-io/gush) concept
41
+ - Support build in callback
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- source "https://gems.contribsys.com/" do
6
- gem 'sidekiq-pro'
7
- end
5
+ # source "https://gems.contribsys.com/" do
6
+ # gem 'sidekiq-pro'
7
+ # end
8
8
 
data/README.md CHANGED
@@ -2,11 +2,12 @@
2
2
  [Gush](https://github.com/chaps-io/gush) cloned without [ActiveJob](https://guides.rubyonrails.org/active_job_basics.html) but requried [Sidekiq](https://github.com/mperham/sidekiq). This project is for researching DSL purpose
3
3
 
4
4
  # Installation
5
+ ## 1. Add `dwf` to Gemfile
5
6
  ```ruby
6
- gem 'dwf', '~> 0.1.1'
7
+ gem 'dwf', '~> 0.1.5'
7
8
  ```
8
- # Execute flow
9
- ## Declare jobs
9
+ ## 2. Execute flow
10
+ ### Declare jobs
10
11
 
11
12
  ```ruby
12
13
  require 'dwf'
@@ -15,17 +16,13 @@ class A < Dwf::Item
15
16
  def perform
16
17
  puts "#{self.class.name} Working"
17
18
  sleep 2
19
+ puts params
18
20
  puts "#{self.class.name} Finished"
19
21
  end
20
22
  end
21
-
22
- class E < A; end
23
- class B < A; end
24
- class C < E; end
25
- class D < E; end
26
23
  ```
27
24
 
28
- ## Declare flow
25
+ ### Declare flow
29
26
  ```ruby
30
27
  require 'dwf'
31
28
 
@@ -34,33 +31,54 @@ class TestWf < Dwf::Workflow
34
31
  run A
35
32
  run B, after: A
36
33
  run C, after: A
37
- run E, after: [B, C]
38
- run D, after: [E]
34
+ run E, after: [B, C], params: 'E say hello'
35
+ run D, after: [E], params: 'D say hello'
36
+ run F, params: 'F say hello'
39
37
  end
40
38
  end
41
-
42
39
  ```
43
40
 
41
+ #### Note
42
+ `dwf` supports 2 callback types `Dwf::Workflow::BUILD_IN` and `Dwf::Workflow::SK_BATCH`
43
+ - `Dwf::Workflow::BUILD_IN` is a build-in callback
44
+ - `Dwf::Workflow::SK_BATCH` is [sidekiq batch](https://github.com/mperham/sidekiq/wiki/Batches) callback which required [`sidekiq-pro`](https://sidekiq.org/products/pro.html)
45
+
46
+ By default `dwf` will use `Dwf::Workflow::BUILD_IN` callback.
47
+
44
48
  ### Execute flow
45
49
  ```ruby
46
- wf = TestWf.create
50
+ wf = TestWf.create(callback_type: Dwf::Workflow::SK_BATCH)
47
51
  wf.start!
48
52
  ```
49
53
 
50
54
  ### Output
51
55
  ```
52
56
  A Working
57
+ F Working
53
58
  A Finished
54
- B Working
59
+ F say hello
60
+ F Finished
55
61
  C Working
56
- B Finished
62
+ B Working
57
63
  C Finished
64
+ B Finished
58
65
  E Working
66
+ E say hello
59
67
  E Finished
60
68
  D Working
69
+ D say hello
61
70
  D Finished
62
71
  ```
63
72
 
73
+ # Todo
74
+ - [x] Make it work
75
+ - [x] Support pass params
76
+ - [x] Support with build-in callback
77
+ - [x] Add github workflow
78
+ - [ ] [WIP] Test
79
+ - [ ] Transfer output through each node
80
+ - [ ] Support [Resque](https://github.com/resque/resque)
81
+
64
82
  # References
65
83
  - https://github.com/chaps-io/gush
66
84
  - https://github.com/mperham/sidekiq
data/dwf.gemspec CHANGED
@@ -6,7 +6,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = "dwf"
9
- spec.version = '0.1.2'
9
+ spec.version = '0.1.6'
10
10
  spec.authors = ["dthtien"]
11
11
  spec.email = ["tiendt2311@gmail.com"]
12
12
 
data/lib/dwf/callback.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'sidekiq-pro'
2
1
  require_relative 'client'
3
2
 
4
3
  module Dwf
@@ -23,19 +22,48 @@ module Dwf
23
22
  private
24
23
 
25
24
  def setup_batch(processing_job_names, workflow_id)
26
- batch = Sidekiq::Batch.new
27
- batch.on(
28
- :success,
29
- 'Dwf::Callback#process_next_step',
30
- names: processing_job_names,
31
- workflow_id: workflow_id
32
- )
25
+ jobs = fetch_jobs(processing_job_names, workflow_id)
26
+ jobs_classification = classify_jobs jobs
27
+
28
+ jobs_classification.values.each do |batch_jobs|
29
+ batch = Sidekiq::Batch.new
30
+ batch.on(
31
+ :success,
32
+ 'Dwf::Callback#process_next_step',
33
+ names: batch_jobs.map(&:klass),
34
+ workflow_id: workflow_id
35
+ )
33
36
 
34
- batch.jobs do
35
- processing_job_names.each { |job_name| perform_job(job_name, workflow_id) }
37
+ batch.jobs do
38
+ batch_jobs.each do |job|
39
+ job.persist_and_perform_async! if job.ready_to_start?
40
+ end
41
+ end
36
42
  end
37
43
  end
38
44
 
45
+ def classify_jobs(jobs)
46
+ hash = {}
47
+ jobs.each do |job|
48
+ outgoing_jobs = job.outgoing
49
+ key = outgoing_jobs.empty? ? 'default_key' : outgoing_jobs.join
50
+
51
+ if hash[key].nil?
52
+ hash[key] = [job]
53
+ else
54
+ hash[key] = hash[key].push(job)
55
+ end
56
+ end
57
+
58
+ hash
59
+ end
60
+
61
+ def fetch_jobs(processing_job_names, workflow_id)
62
+ processing_job_names.map do |job_name|
63
+ client.find_job(workflow_id, job_name)
64
+ end.compact
65
+ end
66
+
39
67
  def perform_job(job_name, workflow_id)
40
68
  with_lock workflow_id, job_name do
41
69
  job = client.find_job(workflow_id, job_name)
data/lib/dwf/item.rb CHANGED
@@ -1,22 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  require_relative 'client'
2
3
 
3
4
  module Dwf
4
5
  class Item
6
+ DEFAULT_QUEUE = 'default'
7
+
5
8
  attr_reader :workflow_id, :id, :params, :queue, :klass, :started_at,
6
- :enqueued_at, :finished_at, :failed_at
7
- attr_accessor :incomming, :outgoing
9
+ :enqueued_at, :finished_at, :failed_at, :callback_type
10
+ attr_accessor :incoming, :outgoing
8
11
 
9
12
  def initialize(options = {})
10
13
  @workflow_id = options[:workflow_id]
11
14
  @id = options[:id]
12
15
  @params = options[:params]
13
- @queue = options[:queue] || 'default'
14
- @incomming = options[:incoming] || []
16
+ @queue = options[:queue] || DEFAULT_QUEUE
17
+ @incoming = options[:incoming] || []
15
18
  @outgoing = options[:outgoing] || []
16
19
  @klass = options[:klass] || self.class
20
+ @failed_at = options[:failed_at]
17
21
  @finished_at = options[:finished_at]
18
22
  @enqueued_at = options[:enqueued_at]
19
23
  @started_at = options[:started_at]
24
+ @callback_type = options[:callback_type]
20
25
  end
21
26
 
22
27
  def self.from_hash(hash)
@@ -31,6 +36,10 @@ module Dwf
31
36
 
32
37
  def perform; end
33
38
 
39
+ def cb_build_in?
40
+ callback_type == Dwf::Workflow::BUILD_IN
41
+ end
42
+
34
43
  def perform_async
35
44
  Dwf::Worker.set(queue: queue).perform_async(workflow_id, name)
36
45
  end
@@ -40,11 +49,11 @@ module Dwf
40
49
  end
41
50
 
42
51
  def no_dependencies?
43
- incomming.empty?
52
+ incoming.empty?
44
53
  end
45
54
 
46
55
  def parents_succeeded?
47
- incomming.all? do |name|
56
+ incoming.all? do |name|
48
57
  client.find_job(workflow_id, name).succeeded?
49
58
  end
50
59
  end
@@ -125,14 +134,15 @@ module Dwf
125
134
  id: id,
126
135
  klass: klass.to_s,
127
136
  queue: queue,
128
- incoming: incomming,
137
+ incoming: incoming,
129
138
  outgoing: outgoing,
130
139
  finished_at: finished_at,
131
140
  enqueued_at: enqueued_at,
132
141
  started_at: started_at,
133
142
  failed_at: failed_at,
134
143
  params: params,
135
- workflow_id: workflow_id
144
+ workflow_id: workflow_id,
145
+ callback_type: callback_type
136
146
  }
137
147
  end
138
148
 
data/lib/dwf/worker.rb CHANGED
@@ -12,7 +12,7 @@ module Dwf
12
12
  job.mark_as_started
13
13
  job.perform
14
14
  job.mark_as_finished
15
- # job.enqueue_outgoing_jobs
15
+ job.enqueue_outgoing_jobs if job.cb_build_in?
16
16
  end
17
17
 
18
18
  private
data/lib/dwf/workflow.rb CHANGED
@@ -1,32 +1,40 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'client'
2
4
  require_relative 'worker'
3
5
  require_relative 'callback'
4
6
 
5
7
  module Dwf
6
8
  class Workflow
7
- attr_reader :dependencies, :jobs, :started_at, :finished_at, :persisted, :stopped
9
+ CALLBACK_TYPES = [
10
+ BUILD_IN = 'build-in',
11
+ SK_BATCH = 'sk-batch'
12
+ ].freeze
13
+ attr_reader :dependencies, :jobs, :started_at, :finished_at, :persisted, :stopped,
14
+ :callback_type
8
15
 
9
16
  class << self
10
- def create
11
- flow = new
17
+ def create(*args)
18
+ flow = new(*args)
12
19
  flow.save
13
20
  flow
14
21
  end
15
22
  end
16
23
 
17
- def initialize
24
+ def initialize(options = {})
18
25
  @dependencies = []
19
26
  @id = id
20
27
  @jobs = []
21
28
  @persisted = false
22
29
  @stopped = false
30
+ @callback_type = options[:callback_type] || BUILD_IN
23
31
 
24
32
  setup
25
33
  end
26
34
 
27
35
  def start!
28
36
  initial_jobs.each do |job|
29
- Dwf::Callback.new.start(job)
37
+ cb_build_in? ? job.persist_and_perform_async! : Dwf::Callback.new.start(job)
30
38
  end
31
39
  end
32
40
 
@@ -37,6 +45,10 @@ module Dwf
37
45
  true
38
46
  end
39
47
 
48
+ def cb_build_in?
49
+ callback_type == BUILD_IN
50
+ end
51
+
40
52
  def id
41
53
  @id ||= client.build_workflow_id
42
54
  end
@@ -49,6 +61,7 @@ module Dwf
49
61
  id: client.build_job_id(id, klass.to_s),
50
62
  params: options.fetch(:params, {}),
51
63
  queue: options[:queue],
64
+ callback_type: callback_type
52
65
  )
53
66
 
54
67
  jobs << node
@@ -81,7 +94,8 @@ module Dwf
81
94
  status: status,
82
95
  stopped: stopped,
83
96
  started_at: started_at,
84
- finished_at: finished_at
97
+ finished_at: finished_at,
98
+ callback_type: callback_type
85
99
  }
86
100
  end
87
101
 
@@ -143,7 +157,7 @@ module Dwf
143
157
  from = find_job(dependency[:from])
144
158
  to = find_job(dependency[:to])
145
159
 
146
- to.incomming << dependency[:from]
160
+ to.incoming << dependency[:from]
147
161
  from.outgoing << dependency[:to]
148
162
  end
149
163
  end
data/lib/dwf.rb CHANGED
@@ -4,6 +4,7 @@ require "bundler/setup"
4
4
  require 'sidekiq'
5
5
  require 'json'
6
6
  require 'redis'
7
+ # require 'sidekiq-pro'
7
8
 
8
9
  require_relative 'dwf/utils'
9
10
  require_relative 'dwf/workflow'
@@ -13,6 +14,6 @@ require_relative 'dwf/worker'
13
14
  require_relative 'dwf/callback'
14
15
 
15
16
  module Dwf
16
- VERSION = '0.1.0'
17
+ VERSION = '0.1.6'
17
18
  end
18
19
 
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Dwf::Item, item: true do
6
+ let!(:id) { SecureRandom.uuid }
7
+ let!(:workflow_id) { SecureRandom.uuid }
8
+ let(:incoming) { [] }
9
+ let(:outgoing) { [] }
10
+ let(:started_at) { nil }
11
+ let(:finished_at) { nil }
12
+ let(:options) do
13
+ {
14
+ workflow_id: workflow_id,
15
+ id: id,
16
+ params: {},
17
+ incoming: incoming,
18
+ outgoing: outgoing,
19
+ queue: Dwf::Item::DEFAULT_QUEUE,
20
+ klass: 'Dwf::Item',
21
+ started_at: started_at,
22
+ finished_at: finished_at,
23
+ callback_type: Dwf::Workflow::BUILD_IN
24
+ }
25
+ end
26
+ let!(:item) { described_class.new(options) }
27
+
28
+ describe 'self.from_hash' do
29
+ let!(:item) { described_class.from_hash(options) }
30
+ it { expect(item.to_hash.compact).to eq options.compact }
31
+ end
32
+
33
+ describe '#persist_and_perform_async!' do
34
+ let(:worker_double) { double(perform_async: nil) }
35
+ let(:client_double) { double(persist_job: nil) }
36
+
37
+ before do
38
+ allow(Dwf::Client).to receive(:new).and_return client_double
39
+ allow(Dwf::Worker).to receive(:set).and_return worker_double
40
+ item.persist_and_perform_async!
41
+ end
42
+
43
+ it do
44
+ expect(worker_double)
45
+ .to have_received(:perform_async)
46
+ .with(item.workflow_id, item.name)
47
+ expect(client_double).to have_received(:persist_job).with(item)
48
+ expect(item.enqueued_at).not_to be_nil
49
+ end
50
+ end
51
+
52
+ describe '#cb_build_in?' do
53
+ it { expect(item.cb_build_in?).to be_truthy }
54
+ end
55
+
56
+ describe '#perform_async' do
57
+ let(:worker_double) { double(perform_async: nil) }
58
+ before do
59
+ allow(Dwf::Worker).to receive(:set).and_return worker_double
60
+ item.perform_async
61
+ end
62
+
63
+ it do
64
+ expect(worker_double)
65
+ .to have_received(:perform_async)
66
+ .with(item.workflow_id, item.name)
67
+ end
68
+ end
69
+
70
+ describe '#name' do
71
+ it { expect(item.name).to eq "#{described_class}|#{id}" }
72
+ end
73
+
74
+ describe '#no_dependencies?' do
75
+ it { expect(item.no_dependencies?).to be_truthy }
76
+ end
77
+
78
+ describe '#parents_succeeded?' do
79
+ let(:incoming) { ["A|#{SecureRandom.uuid}"] }
80
+ let(:client_double) { double(find_job: nil) }
81
+ let(:a_item) do
82
+ described_class.new(
83
+ workflow_id: SecureRandom.uuid,
84
+ id: SecureRandom.uuid,
85
+ finished_at: finished_at
86
+ )
87
+ end
88
+
89
+ before do
90
+ allow(Dwf::Client).to receive(:new).and_return client_double
91
+ allow(client_double)
92
+ .to receive(:find_job).and_return a_item
93
+ end
94
+
95
+ context 'parent jobs already finished' do
96
+ let(:finished_at) { Time.now.to_i }
97
+
98
+ it do
99
+ expect(item.parents_succeeded?).to be_truthy
100
+ expect(client_double)
101
+ .to have_received(:find_job)
102
+ .with(workflow_id, incoming.first)
103
+ end
104
+ end
105
+
106
+ context 'parent jobs havent finished yet' do
107
+ let(:finished_at) { nil }
108
+
109
+ it do
110
+ expect(item.parents_succeeded?).to be_falsy
111
+ expect(client_double)
112
+ .to have_received(:find_job)
113
+ .with(workflow_id, incoming.first)
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '#enqueue!' do
119
+ before { item.enqueue! }
120
+
121
+ it { expect(item.enqueued_at).not_to be_nil }
122
+ end
123
+
124
+ describe '#mark_as_started' do
125
+ let(:client_double) { double(persist_job: nil) }
126
+ before do
127
+ allow(Dwf::Client).to receive(:new).and_return client_double
128
+ item.mark_as_started
129
+ end
130
+
131
+ it do
132
+ expect(client_double).to have_received(:persist_job).with item
133
+ expect(item.started_at).not_to be_nil
134
+ end
135
+ end
136
+
137
+ describe '#mark_as_finished' do
138
+ let(:client_double) { double(persist_job: nil) }
139
+ before do
140
+ allow(Dwf::Client).to receive(:new).and_return client_double
141
+ item.mark_as_finished
142
+ end
143
+
144
+ it do
145
+ expect(client_double).to have_received(:persist_job).with item
146
+ expect(item.finished_at).not_to be_nil
147
+ end
148
+ end
149
+
150
+ describe '#enqueue_outgoing_jobs' do
151
+ let(:outgoing) { ["A|#{SecureRandom.uuid}"] }
152
+ let(:client_double) do
153
+ double(
154
+ find_job: nil,
155
+ check_or_lock: nil,
156
+ release_lock: nil
157
+ )
158
+ end
159
+ let(:a_item) do
160
+ described_class.new(
161
+ workflow_id: SecureRandom.uuid,
162
+ id: SecureRandom.uuid,
163
+ started_at: started_at
164
+ )
165
+ end
166
+ before do
167
+ allow(Dwf::Client).to receive(:new).and_return client_double
168
+ allow(a_item).to receive(:persist_and_perform_async!)
169
+ allow(client_double)
170
+ .to receive(:find_job).and_return a_item
171
+ item.enqueue_outgoing_jobs
172
+ end
173
+
174
+ context 'outgoing jobs ready to start' do
175
+ let(:started_at) { nil }
176
+ it { expect(a_item).to have_received(:persist_and_perform_async!) }
177
+ end
178
+
179
+ context 'outgoing jobs havent ready to start' do
180
+ let(:started_at) { Time.now.to_i }
181
+ it { expect(a_item).not_to have_received(:persist_and_perform_async!) }
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dwf::Utils, utils: true do
4
+ describe '#symbolize_keys' do
5
+ let(:expected) do
6
+ {
7
+ incoming: ['S'],
8
+ outgoing: %w[A B],
9
+ klass: 'H'
10
+ }
11
+ end
12
+
13
+ let(:hash) do
14
+ {
15
+ 'incoming' => ['S'],
16
+ 'outgoing' => %w[A B],
17
+ 'klass' => 'H'
18
+ }
19
+ end
20
+
21
+ it { expect(described_class.symbolize_keys(hash)).to eq expected }
22
+ end
23
+ end
@@ -0,0 +1,101 @@
1
+ require 'dwf'
2
+ # This file was generated by the `rspec --init` command. Conventionally, all
3
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
4
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
5
+ # this file to always be loaded, without a need to explicitly require it in any
6
+ # files.
7
+ #
8
+ # Given that it is always loaded, you are encouraged to keep this file as
9
+ # light-weight as possible. Requiring heavyweight dependencies from this file
10
+ # will add to the boot time of your test suite on EVERY test run, even for an
11
+ # individual file that may not need all of that loaded. Instead, consider making
12
+ # a separate helper file that requires the additional dependencies and performs
13
+ # the additional setup, and require it from the spec files that actually need
14
+ # it.
15
+ #
16
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+ RSpec.configure do |config|
18
+ # rspec-expectations config goes here. You can use an alternate
19
+ # assertion/expectation library such as wrong or the stdlib/minitest
20
+ # assertions if you prefer.
21
+ config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4. It makes the `description`
23
+ # and `failure_message` of custom matchers include text for helper methods
24
+ # defined using `chain`, e.g.:
25
+ # be_bigger_than(2).and_smaller_than(4).description
26
+ # # => "be bigger than 2 and smaller than 4"
27
+ # ...rather than:
28
+ # # => "be bigger than 2"
29
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
30
+ end
31
+
32
+ # rspec-mocks config goes here. You can use an alternate test double
33
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
34
+ config.mock_with :rspec do |mocks|
35
+ # Prevents you from mocking or stubbing a method that does not exist on
36
+ # a real object. This is generally recommended, and will default to
37
+ # `true` in RSpec 4.
38
+ mocks.verify_partial_doubles = true
39
+ end
40
+
41
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
42
+ # have no way to turn it off -- the option exists only for backwards
43
+ # compatibility in RSpec 3). It causes shared context metadata to be
44
+ # inherited by the metadata hash of host groups and examples, rather than
45
+ # triggering implicit auto-inclusion in groups with matching metadata.
46
+ config.shared_context_metadata_behavior = :apply_to_host_groups
47
+
48
+ # The settings below are suggested to provide a good initial experience
49
+ # with RSpec, but feel free to customize to your heart's content.
50
+ =begin
51
+ # This allows you to limit a spec run to individual examples or groups
52
+ # you care about by tagging them with `:focus` metadata. When nothing
53
+ # is tagged with `:focus`, all examples get run. RSpec also provides
54
+ # aliases for `it`, `describe`, and `context` that include `:focus`
55
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
56
+ config.filter_run_when_matching :focus
57
+
58
+ # Allows RSpec to persist some state between runs in order to support
59
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
60
+ # you configure your source control system to ignore this file.
61
+ config.example_status_persistence_file_path = "spec/examples.txt"
62
+
63
+ # Limits the available syntax to the non-monkey patched syntax that is
64
+ # recommended. For more details, see:
65
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
66
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
67
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
68
+ config.disable_monkey_patching!
69
+
70
+ # This setting enables warnings. It's recommended, but in some cases may
71
+ # be too noisy due to issues in dependencies.
72
+ config.warnings = true
73
+
74
+ # Many RSpec users commonly either run the entire suite or an individual
75
+ # file, and it's useful to allow more verbose output when running an
76
+ # individual spec file.
77
+ if config.files_to_run.one?
78
+ # Use the documentation formatter for detailed output,
79
+ # unless a formatter has already been configured
80
+ # (e.g. via a command-line flag).
81
+ config.default_formatter = "doc"
82
+ end
83
+
84
+ # Print the 10 slowest examples and example groups at the
85
+ # end of the spec run, to help surface which specs are running
86
+ # particularly slow.
87
+ config.profile_examples = 10
88
+
89
+ # Run specs in random order to surface order dependencies. If you find an
90
+ # order dependency and want to debug it, you can fix the order by providing
91
+ # the seed, which is printed after each run.
92
+ # --seed 1234
93
+ config.order = :random
94
+
95
+ # Seed global randomization in this process using the `--seed` CLI option.
96
+ # Setting this allows you to use `--seed` to deterministically reproduce
97
+ # test failures related to randomization by passing the same `--seed` value
98
+ # as the one that triggered the failure.
99
+ Kernel.srand config.seed
100
+ =end
101
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dwf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - dthtien
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-04 00:00:00.000000000 Z
11
+ date: 2021-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -73,12 +73,15 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".github/workflows/build_gem.yaml"
77
+ - ".github/workflows/test.yaml"
76
78
  - ".gitignore"
79
+ - ".rspec"
77
80
  - ".ruby-version"
81
+ - CHANGELOG.md
78
82
  - Gemfile
79
83
  - LICENSE.txt
80
84
  - README.md
81
- - dwf-0.1.0.gem
82
85
  - dwf.gemspec
83
86
  - lib/dwf.rb
84
87
  - lib/dwf/callback.rb
@@ -87,11 +90,14 @@ files:
87
90
  - lib/dwf/utils.rb
88
91
  - lib/dwf/worker.rb
89
92
  - lib/dwf/workflow.rb
93
+ - spec/dwf/item_spec.rb
94
+ - spec/dwf/utils_spec.rb
95
+ - spec/spec_helper.rb
90
96
  homepage: https://github.com/dthtien/wf
91
97
  licenses:
92
98
  - MIT
93
99
  metadata: {}
94
- post_install_message:
100
+ post_install_message:
95
101
  rdoc_options: []
96
102
  require_paths:
97
103
  - lib
@@ -107,8 +113,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
113
  version: '0'
108
114
  requirements: []
109
115
  rubygems_version: 3.2.3
110
- signing_key:
116
+ signing_key:
111
117
  specification_version: 4
112
118
  summary: Gush cloned without ActiveJob but requried Sidekiq. This project is for researching
113
119
  DSL purpose
114
- test_files: []
120
+ test_files:
121
+ - spec/dwf/item_spec.rb
122
+ - spec/dwf/utils_spec.rb
123
+ - spec/spec_helper.rb
data/dwf-0.1.0.gem DELETED
Binary file