fetch 0.0.4 → 0.0.5

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
  SHA1:
3
- metadata.gz: a10520fb3d8cc9508aef80fe19c88dd4b5b72a71
4
- data.tar.gz: cc19fba644b2236f5833f312bf002b495258caf7
3
+ metadata.gz: 538eaf280947e75a0999edfea670488a353d6c0d
4
+ data.tar.gz: 39ebdb1b870ef7afd28d278ada14f84bb338f859
5
5
  SHA512:
6
- metadata.gz: 4b23e3bb9c6e49e85d07e37791d46343d5f36467dc279498a9da855ff8580ce3e0df3515bbf58b17222b7b013ee1be5619ec6af746fc7607c573ced140abc07b
7
- data.tar.gz: 3239bdfb8eb3ce1855efcad29227fa59ff0c23893781da47b85cae867440edc1e99d35188777e482b3764ec5853b81313b0d604a61e0324d0dae52dc2b192111
6
+ metadata.gz: dd5d3fe051dcdf0582ac359c3865e40a048bca131e1479070491c2a93b28f23aa18be31a126fca6a4d94c340a82a2b6ea14f3596b93bb66c870d4d2151b3510e
7
+ data.tar.gz: e75ed279223063297541ef88f4feedd8cb805c4ec50c7c2f6fba9bc59157d5366cd73b674369299717e8833016367202a078c9d0fde6efd3238c4ffe0f6f605f
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.0.5
4
+
5
+ * The `after_fetch` callbacks are run in the reverse order of which they were
6
+ defined.
7
+
3
8
  ## Version 0.0.4
4
9
 
5
10
  * Exceptions are raised after the general `Fetch::Base` `error` callback is
data/README.md CHANGED
@@ -107,6 +107,52 @@ repos.
107
107
 
108
108
  ## Good to know
109
109
 
110
+ ### Doing something before a fetch
111
+
112
+ If you need to run something before a fetch is started, you can do it using the
113
+ `before_fetch` callback.
114
+
115
+ ```ruby
116
+ class UserFetcher < Fetch::Module
117
+ modules Facebook::UserInfoFetch,
118
+ Github::UserInfoFetch
119
+
120
+ before_fetch do
121
+ # Do something before the fetch.
122
+ end
123
+ end
124
+
125
+ user = User.find(123)
126
+ UserFetcher.new(user).fetch
127
+ # => `before_fetch` is run before fetching
128
+ ```
129
+
130
+ **Note:** If you define more than one `before_fetch` callback, they are run in the order
131
+ in which they were defined.
132
+
133
+ ### Doing something after a fetch
134
+
135
+ If you need to run something after a fetch is completed, you can do it using
136
+ the `after_fetch` callback.
137
+
138
+ ```ruby
139
+ class UserFetcher < Fetch::Module
140
+ modules Facebook::UserInfoFetch,
141
+ Github::UserInfoFetch
142
+
143
+ after_fetch do
144
+ # Do something after the fetch has completed.
145
+ end
146
+ end
147
+
148
+ user = User.find(123)
149
+ UserFetcher.new(user).fetch
150
+ # => `after_fetch` is run after fetching
151
+ ```
152
+
153
+ **Note:** If you define more than one `after_fetch` callback, they are run in
154
+ the *reverse* order of which they were defined.
155
+
110
156
  ### Adding defaults to your requests
111
157
 
112
158
  Each fetch module has a `defaults` callback that you can use to set up defaults
@@ -20,10 +20,11 @@ module Fetch
20
20
  :load,
21
21
  :init,
22
22
  :before_fetch,
23
- :after_fetch,
24
23
  :progress,
25
24
  :error
26
25
 
26
+ define_callback :after_fetch, reverse: true
27
+
27
28
  def initialize(fetchable = nil)
28
29
  @fetchable = fetchable
29
30
  end
@@ -15,19 +15,25 @@ module Fetch
15
15
  #
16
16
  # run_callbacks_for(:before_fetch)
17
17
  # run_callbacks_for(:progress, 12) # 12 percent done
18
- def run_callbacks_for(name, *args)
19
- self.class.callbacks[name].map do |block|
20
- run_callback(*args, &block)
18
+ def run_callbacks_for(name, args, reverse)
19
+ callbacks_for(name, reverse).map do |block|
20
+ run_callback(block, args)
21
21
  end
22
22
  end
23
23
 
24
- def run_last_callback_for(name, *args)
25
- if callback = self.class.callbacks[name].last
26
- run_callback(*args, &callback)
24
+ def run_last_callback_for(name, args, reverse)
25
+ if block = callbacks_for(name, reverse).last
26
+ run_callback(block, args)
27
27
  end
28
28
  end
29
29
 
30
- def run_callback(*args, &block)
30
+ def callbacks_for(name, reverse)
31
+ callbacks = self.class.callbacks[name]
32
+ callbacks = callbacks.reverse if reverse
33
+ callbacks
34
+ end
35
+
36
+ def run_callback(block, args)
31
37
  instance_exec(*args, &block)
32
38
  end
33
39
 
@@ -39,17 +45,20 @@ module Fetch
39
45
 
40
46
  # Defines callback methods on the class level.
41
47
  def define_callback(*names)
48
+ options = names.last.is_a?(Hash) ? names.pop : {}
49
+ reverse = !!options[:reverse]
50
+
42
51
  names.each do |name|
43
52
  define_singleton_method name do |*values, &block|
44
- create_callback_for(name, *values, &block)
53
+ create_callback_for(name, values, block)
45
54
  end
46
55
 
47
56
  define_method name do |*args|
48
- run_callbacks_for(name, *args).last
57
+ run_callbacks_for(name, args, reverse).last
49
58
  end
50
59
 
51
60
  define_method "#{name}!" do |*args|
52
- run_last_callback_for(name, *args)
61
+ run_last_callback_for(name, args, reverse)
53
62
  end
54
63
  end
55
64
  end
@@ -63,12 +72,12 @@ module Fetch
63
72
 
64
73
  private
65
74
 
66
- def create_callback_for(name, *values, &block)
67
- add_callback(name) { values } if values.any?
68
- add_callback(name, &block) if block
75
+ def create_callback_for(name, values, block)
76
+ add_callback(name, ->{ values }) if values.any?
77
+ add_callback(name, block) if block
69
78
  end
70
79
 
71
- def add_callback(name, &block)
80
+ def add_callback(name, block)
72
81
  callbacks[name] << block
73
82
  end
74
83
  end
@@ -1,3 +1,3 @@
1
1
  module Fetch
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,13 @@
1
+ require "test_helper"
2
+
3
+ class AfterFetchTest < Minitest::Test
4
+ def test_after_fetch_runs_when_fetching
5
+ actions = []
6
+ klass = Class.new(Fetch::Base) do
7
+ after_fetch { actions << "first after" }
8
+ after_fetch { actions << "second after" }
9
+ end
10
+ klass.new.fetch
11
+ assert_equal ["second after", "first after"], actions
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require "test_helper"
2
+
3
+ class BaseTest < Minitest::Test
4
+ def test_sends_fetchable_to_modules
5
+ stub_request(:get, "https://api.github.com/users/lassebunk").to_return(body: "id: 1234")
6
+ actions = []
7
+ mod = Class.new(Fetch::Module) do
8
+ request do |req|
9
+ req.url = "https://api.github.com/users/#{fetchable.login}"
10
+ req.process do |body|
11
+ actions << "process: #{body}"
12
+ end
13
+ end
14
+ end
15
+ user = OpenStruct.new(login: "lassebunk")
16
+ MockFetcher(mod).new(user).fetch
17
+ assert_equal ["process: id: 1234"], actions
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require "test_helper"
2
+
3
+ class BeforeFetchTest < Minitest::Test
4
+ def test_before_fetch_runs_when_fetching
5
+ actions = []
6
+ klass = Class.new(Fetch::Base) do
7
+ before_fetch { actions << "first before" }
8
+ before_fetch { actions << "second before" }
9
+ end
10
+ klass.new.fetch
11
+ assert_equal ["first before", "second before"], actions
12
+ end
13
+ end
File without changes
File without changes
@@ -0,0 +1,95 @@
1
+ require "test_helper"
2
+
3
+ class ProgressTest < Minitest::Test
4
+ def test_progress_with_single_module
5
+ stub_request(:get, "http://test.com/one").to_return(body: "got one")
6
+
7
+ mod = Class.new(Fetch::Module) do
8
+ 3.times do
9
+ request do |req|
10
+ req.url = "http://test.com/one"
11
+ end
12
+ end
13
+ end
14
+
15
+ updates = []
16
+
17
+ klass = Class.new(MockFetcher(mod)) do
18
+ progress do |percent|
19
+ updates << percent
20
+ end
21
+ end
22
+
23
+ klass.new.fetch
24
+ assert_equal [0, 33, 66, 100], updates
25
+ end
26
+
27
+ def test_progress_with_multiple_modules
28
+ stub_request(:get, "http://test.com/one").to_return(body: "got one")
29
+
30
+ mods = 3.times.map do
31
+ Class.new(Fetch::Module) do
32
+ 2.times do
33
+ request do |req|
34
+ req.url = "http://test.com/one"
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ updates = []
41
+
42
+ klass = Class.new(MockFetcher(mods)) do
43
+ progress do |percent|
44
+ updates << percent
45
+ end
46
+ end
47
+
48
+ klass.new.fetch
49
+ assert_equal [0, 16, 33, 50, 66, 83, 100], updates
50
+ end
51
+
52
+ def test_progress_with_http_failure
53
+ stub_request(:get, "http://test.com/one").to_return(body: "something went wrong", status: 500)
54
+ updates = []
55
+ mods = 3.times.map do
56
+ Class.new(Fetch::Module) do
57
+ request do |req|
58
+ req.url = "http://test.com/one"
59
+ end
60
+ end
61
+ end
62
+ klass = Class.new(MockFetcher(mods)) do
63
+ progress do |percent|
64
+ updates << percent
65
+ end
66
+ end
67
+
68
+ klass.new.fetch
69
+ assert_equal [0, 33, 66, 100], updates
70
+ end
71
+
72
+ def test_progress_with_handled_process_error
73
+ stub_request(:get, "http://test.com/one").to_return(body: "ok")
74
+ updates = []
75
+ mods = 3.times.map do
76
+ Class.new(Fetch::Module) do
77
+ request do |req|
78
+ req.url = "http://test.com/one"
79
+ req.process do |body|
80
+ wont_work
81
+ end
82
+ req.error { }
83
+ end
84
+ end
85
+ end
86
+ klass = Class.new(MockFetcher(mods)) do
87
+ progress do |percent|
88
+ updates << percent
89
+ end
90
+ end
91
+
92
+ klass.new.fetch
93
+ assert_equal [0, 33, 66, 100], updates
94
+ end
95
+ end
@@ -1,6 +1,6 @@
1
1
  require "test_helper"
2
2
 
3
- class CallbackTest < Minitest::Test
3
+ class Test < Minitest::Test
4
4
  def test_callbacks
5
5
  actions = []
6
6
  klass = Class.new do
@@ -42,6 +42,38 @@ class CallbackTest < Minitest::Test
42
42
  assert_equal "second", klass.new.before
43
43
  end
44
44
 
45
+ def test_bang_method_only_runs_last_callback
46
+ klass = Class.new do
47
+ include Fetch::Callbacks
48
+ define_callback :before
49
+ before { this_shouldnt_be_run! }
50
+ before { "ok" }
51
+ end
52
+ assert_equal "ok", klass.new.before!
53
+ end
54
+
55
+ def test_callbacks_can_run_in_reverse_order
56
+ actions = []
57
+ klass = Class.new do
58
+ include Fetch::Callbacks
59
+ define_callback :after, reverse: true
60
+ after { actions << "first after" }
61
+ after { actions << "second after" }
62
+ end
63
+ klass.new.after
64
+ assert_equal ["second after", "first after"], actions
65
+ end
66
+
67
+ def test_reversed_bang_method_runs_only_first_callback
68
+ klass = Class.new do
69
+ include Fetch::Callbacks
70
+ define_callback :after, reverse: true
71
+ after { "first one defined" }
72
+ after { this_cant_run! }
73
+ end
74
+ assert_equal "first one defined", klass.new.after!
75
+ end
76
+
45
77
  def test_callbacks_take_optional_arguments
46
78
  actions = []
47
79
  klass = Class.new do
@@ -0,0 +1,104 @@
1
+ require "test_helper"
2
+
3
+ class AfterProcessTest < Minitest::Test
4
+ def test_after_process_callback_set_in_request
5
+ words = %w{one two}
6
+ words.each { |w| stub_request(:get, "http://test.com/#{w}").to_return(body: "got #{w}") }
7
+
8
+ stub_request(:get, "http://test.com/two").to_return(body: "got two")
9
+ actions = []
10
+ mod = Class.new(Fetch::Module) do
11
+ words.each do |word|
12
+ request do |req|
13
+ req.url = "http://test.com/#{word}"
14
+ req.after_process do
15
+ actions << "after process #{word}"
16
+ end
17
+ req.process do |body|
18
+ actions << "process #{word}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ MockFetcher(mod).new.fetch
24
+ assert_equal ["process one", "after process one", "process two", "after process two"], actions
25
+ end
26
+
27
+ def test_after_process_callback_scope_set_in_request
28
+ words = %w{one two}
29
+ words.each { |w| stub_request(:get, "http://test.com/#{w}").to_return(body: "got #{w}") }
30
+
31
+ stub_request(:get, "http://test.com/two").to_return(body: "got two")
32
+ actions = []
33
+ mod = Class.new(Fetch::Module) do
34
+ words.each do |word|
35
+ request do |req|
36
+ req.url = "http://test.com/#{word}"
37
+ req.after_process do
38
+ actions << "after process #{word} (#{some_instance_method})"
39
+ end
40
+ req.process do |body|
41
+ actions << "process #{word}"
42
+ end
43
+ end
44
+ end
45
+ def some_instance_method
46
+ "ok"
47
+ end
48
+ end
49
+ MockFetcher(mod).new.fetch
50
+ assert_equal ["process one", "after process one (ok)", "process two", "after process two (ok)"], actions
51
+ end
52
+
53
+ def test_after_process_callback_set_in_module
54
+ words = %w{one two}
55
+ words.each { |w| stub_request(:get, "http://test.com/#{w}").to_return(body: "got #{w}") }
56
+
57
+ stub_request(:get, "http://test.com/two").to_return(body: "got two")
58
+ actions = []
59
+ mod = Class.new(Fetch::Module) do
60
+ words.each do |word|
61
+ request do |req|
62
+ req.url = "http://test.com/#{word}"
63
+ req.process do |body|
64
+ actions << "process #{word}"
65
+ end
66
+ end
67
+ end
68
+
69
+ after_process do
70
+ actions << "after process"
71
+ end
72
+ end
73
+ MockFetcher(mod).new.fetch
74
+ assert_equal ["process one", "after process", "process two", "after process"], actions
75
+ end
76
+
77
+ def test_after_process_callback_scope_set_in_module
78
+ words = %w{one two}
79
+ words.each { |w| stub_request(:get, "http://test.com/#{w}").to_return(body: "got #{w}") }
80
+
81
+ stub_request(:get, "http://test.com/two").to_return(body: "got two")
82
+ actions = []
83
+ mod = Class.new(Fetch::Module) do
84
+ words.each do |word|
85
+ request do |req|
86
+ req.url = "http://test.com/#{word}"
87
+ req.process do |body|
88
+ actions << "process #{word}"
89
+ end
90
+ end
91
+ end
92
+
93
+ after_process do
94
+ actions << "after process (#{some_instance_method})"
95
+ end
96
+
97
+ def some_instance_method
98
+ "ok"
99
+ end
100
+ end
101
+ MockFetcher(mod).new.fetch
102
+ assert_equal ["process one", "after process (ok)", "process two", "after process (ok)"], actions
103
+ end
104
+ end