carbon 2.2.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,302 +0,0 @@
1
- require File.expand_path("../helper", __FILE__)
2
-
3
- Thread.abort_on_exception = true
4
- Carbon.key = 'carbon_test'
5
-
6
- class MyNissan
7
- def name
8
- 'Nissan'
9
- end
10
- def to_s
11
- raise "Not fair!"
12
- end
13
- alias :inspect :to_s
14
- end
15
-
16
- class MyNissanAltima
17
- class << self
18
- def all(options)
19
- raise unless options == { :order => :year }
20
- [ new(2000), new(2001), new(2002), new(2003), new(2004) ]
21
- end
22
- end
23
- def initialize(model_year)
24
- @model_year = model_year
25
- end
26
- def make; MyNissan.new end
27
- def model; 'Altima' end
28
- def model_year; @model_year end # what BP knows as "year"
29
- def fuel_type; 'R' end # what BP knows as "automobile_fuel" and keys on "code"
30
- def nil_make; nil end
31
- def nil_model; nil end
32
- include Carbon
33
- emit_as 'Automobile' do
34
- provide(:make) { |my_nissan_altima| my_nissan_altima.make.try(:name) }
35
- provide :model
36
- provide :model_year, :as => :year
37
- provide :fuel_type, :as => :automobile_fuel, :key => :code
38
- provide(:nil_make) { |my_nissan_altima| my_nissan_altima.nil_make.try(:blam!) }
39
- provide :nil_model
40
- end
41
- end
42
-
43
- describe Carbon do
44
- before do
45
- flush_cache!
46
- end
47
-
48
- describe :query do
49
- describe '(one at a time)' do
50
- it "calculates flight impact" do
51
- result = Carbon.query('Flight', :origin_airport => 'LAX', :destination_airport => 'SFO', :segments_per_trip => 1, :trips => 1)
52
- result.decisions.carbon.object.value.must_be_close_to 200, 50
53
- end
54
- it "can be used on an object that response to #as_impact_query" do
55
- Carbon.query(MyNissanAltima.new(2006)).decisions.must_equal MyNissanAltima.new(2006).impact.decisions
56
- end
57
- it "gets back characteristics" do
58
- result = Carbon.query('Flight', :origin_airport => 'LAX', :destination_airport => 'SFO', :segments_per_trip => 1, :trips => 1)
59
- result.characteristics.origin_airport.description.must_match %r{lax}i
60
- end
61
- it "tells you if the query is successful" do
62
- result = Carbon.query('Flight')
63
- result.success.must_equal true
64
- end
65
- it "is gentle about errors" do
66
- result = Carbon.query('Monkey')
67
- result.success.must_equal false
68
- end
69
- it "sends timeframe properly" do
70
- result = Carbon.query('Flight', :timeframe => Timeframe.new(:year => 2009))
71
- result.timeframe.startDate.must_equal '2009-01-01'
72
- result.timeframe.endDate.must_equal '2010-01-01'
73
- end
74
- it "sends key properly" do
75
- with_web_mock do
76
- WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:body => hash_including(:key => 'carbon_test')).to_return(:status => 500, :body => 'default')
77
- WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:body => hash_including(:key => 'carbon_test1')).to_return(:status => 500, :body => 'A')
78
- WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').with(:body => hash_including(:key => 'carbon_test2')).to_return(:status => 500, :body => 'B')
79
- Carbon.query('Flight', :key => 'carbon_test2').errors.first.must_equal 'B'
80
- Carbon.query('Flight').errors.first.must_equal 'default'
81
- Carbon.query('Flight', :key => 'carbon_test1').errors.first.must_equal 'A'
82
- end
83
- end
84
- it "allows choosing domain" do
85
- with_web_mock do
86
- WebMock.stub_request(:post, 'http://impact.brighterplanet.com/flights.json').to_return(:status => 500, :body => 'used impact')
87
- WebMock.stub_request(:post, 'http://foo.brighterplanet.com/flights.json').to_return(:status => 500, :body => 'used foo')
88
- Carbon.query('Flight', :domain => 'http://foo.brighterplanet.com').errors.first.must_equal 'used foo'
89
- Carbon.query('Flight').errors.first.must_equal 'used impact'
90
- end
91
- end
92
- it "raises ArgumentError if args are bad" do
93
- lambda {
94
- Carbon.query(['Flight'])
95
- }.must_raise ArgumentError
96
- end
97
- end
98
- describe '(in parallel)' do
99
- before do
100
- flunk if ENV['SKIP_MULTI'] == 'true'
101
- @queries = []
102
- @queries << ['Flight', {:origin_airport => 'LAX', :destination_airport => 'SFO', :segments_per_trip => 1, :trips => 1}]
103
- @queries << ['Flight', {:origin_airport => 'MSN', :destination_airport => 'ORD', :segments_per_trip => 1, :trips => 1}]
104
- @queries << ['Flight', {:origin_airport => 'IAH', :destination_airport => 'DEN', :segments_per_trip => 1, :trips => 1}]
105
- @queries << ['RailTrip', {:distance => 25}]
106
- @queries << ['RailTrip', {:rail_class => 'commuter'}]
107
- @queries << ['RailTrip', {:rail_traction => 'electric'}]
108
- @queries << ['AutomobileTrip', {:make => 'Nissan', :model => 'Altima'}]
109
- @queries << ['AutomobileTrip', {:make => 'Toyota', :model => 'Prius'}]
110
- @queries << ['AutomobileTrip', {:make => 'Ford', :model => 'Taurus'}]
111
- @queries << ['Residence', {:urbanity => 'City'}]
112
- @queries << ['Residence', {:zip_code => '53703'}]
113
- @queries << ['Residence', {:bathrooms => 4}]
114
- @queries << ['Monkey', {:bananas => '1'}]
115
- @queries << ['Monkey', {:bananas => '2'}]
116
- @queries << ['Monkey', {:bananas => '3'}]
117
- @queries = @queries.sort_by { rand }
118
- end
119
- it "is easy to use" do
120
- flight = ['Flight']
121
- rail_trip = ['RailTrip']
122
- results = Carbon.query([flight, rail_trip])
123
- results[flight].decisions.must_equal Carbon.query('Flight').decisions
124
- results[rail_trip].decisions.must_equal Carbon.query('RailTrip').decisions
125
- end
126
- it "doesn't hang up on 0 queries" do
127
- Timeout.timeout(0.5) { Carbon.query([]) }.must_equal(Hash.new)
128
- end
129
- it "raises if you pass it a block directly" do
130
- lambda {
131
- Carbon.query([]) { }
132
- }.must_raise(ArgumentError)
133
- end
134
- it "can be used on objects that respond to #as_impact_query" do
135
- a = MyNissanAltima.new(2001)
136
- b = MyNissanAltima.new(2006)
137
- ab1 = Carbon.query([a, b])
138
- ab2 = Carbon.query([a.as_impact_query, b.as_impact_query])
139
- ab1.each do |k, v|
140
- ab2[k.as_impact_query].must_equal v
141
- end
142
- end
143
- it "runs multiple queries at once" do
144
- reference_results = @queries.inject({}) do |memo, query|
145
- memo[query] = Carbon.query(*query)
146
- memo
147
- end
148
- ts = []
149
- 3.times do
150
- ts << Thread.new do
151
- flush_cache! # important!
152
- multi_results = Carbon.query(@queries)
153
- error_count = 0
154
- multi_results.each do |query, result|
155
- if result.success
156
- result.decisions.carbon.object.value.must_be :>, 0
157
- result.decisions.carbon.object.value.must_be :<, 10_000
158
- else
159
- error_count += 1
160
- end
161
- end
162
- error_count.must_equal 3
163
- reference_results.each do |query, reference_result|
164
- if reference_result.success
165
- multi_results[query].decisions.must_equal reference_result.decisions
166
- else
167
- multi_results[query].must_equal reference_result
168
- end
169
- end
170
- end
171
- end
172
- ts.each do |t|
173
- t.join
174
- end
175
- end
176
- it "is faster than single threaded" do
177
- # warm up the cache on the other end
178
- @queries.each { |query| Carbon.query(*query) }
179
- flush_cache! # important!
180
- single_threaded_time = ::Benchmark.realtime do
181
- @queries.each { |query| Carbon.query(*query) }
182
- end
183
- flush_cache! # important!
184
- multi_threaded_time = ::Benchmark.realtime do
185
- Carbon.query(@queries)
186
- end
187
- cached_single_threaded_time = ::Benchmark.realtime do
188
- @queries.each { |query| Carbon.query(*query) }
189
- end
190
- cached_multi_threaded_time = ::Benchmark.realtime do
191
- Carbon.query(@queries)
192
- end
193
- multi_threaded_time.must_be :<, single_threaded_time
194
- cached_single_threaded_time.must_be :<, multi_threaded_time
195
- cached_multi_threaded_time.must_be :<, multi_threaded_time
196
- $stderr.puts " Multi-threaded was #{((single_threaded_time - multi_threaded_time) / single_threaded_time * 100).round}% faster than single-threaded"
197
- $stderr.puts " Cached single-threaded was #{((multi_threaded_time - cached_single_threaded_time) / multi_threaded_time * 100).round}% faster than uncached multi-threaded"
198
- $stderr.puts " Cached multi-threaded was #{((multi_threaded_time - cached_multi_threaded_time) / multi_threaded_time * 100).round}% faster than uncached multi-threaded"
199
- end
200
- it "safely uniq's and caches queries" do
201
- reference_results = @queries.inject({}) do |memo, query|
202
- memo[query] = Carbon.query(*query)
203
- memo
204
- end
205
- flush_cache! # important!
206
- 3.times do
207
- multi_results = Carbon.query(@queries)
208
- reference_results.each do |query, reference_result|
209
- if reference_result.success
210
- multi_results[query].decisions.must_equal reference_result.decisions
211
- else
212
- multi_results[query].must_equal reference_result
213
- end
214
- end
215
- end
216
- end
217
- end
218
- end
219
-
220
- describe :method_signature do
221
- it "recognizes emitter_param" do
222
- Carbon.method_signature('Flight').must_equal :plain_query
223
- Carbon.method_signature('Flight', :origin_airport => 'LAX').must_equal :plain_query
224
- Carbon.method_signature(:flight).must_equal :plain_query
225
- Carbon.method_signature(:flight, :origin_airport => 'LAX').must_equal :plain_query
226
- end
227
- it "recognizes obj" do
228
- Carbon.method_signature(MyNissanAltima.new(2006)).must_equal :obj
229
- end
230
- it "recognizes array" do
231
- Carbon.method_signature([MyNissanAltima.new(2001)]).must_equal :array
232
- Carbon.method_signature([['Flight']]).must_equal :array
233
- Carbon.method_signature([['Flight', {:origin_airport => 'LAX'}]]).must_equal :array
234
- Carbon.method_signature([['Flight'], ['Flight']]).must_equal :array
235
- Carbon.method_signature([['Flight', {:origin_airport => 'LAX'}], ['Flight', {:origin_airport => 'LAX'}]]).must_equal :array
236
- [MyNissanAltima.new(2006), ['Flight'], ['Flight', {:origin_airport => 'LAX'}]].permutation.each do |p|
237
- Carbon.method_signature(p).must_equal :array
238
- end
239
- end
240
- it "does not want splats for concurrent queries" do
241
- Carbon.method_signature(['Flight'], ['Flight']).must_be_nil
242
- Carbon.method_signature(MyNissanAltima.new(2001), MyNissanAltima.new(2001)).must_be_nil
243
- [MyNissanAltima.new(2006), ['Flight'], ['Flight', {:origin_airport => 'LAX'}]].permutation.each do |p|
244
- Carbon.method_signature(*p).must_be_nil
245
- end
246
- end
247
- it "does not like weirdness" do
248
- Carbon.method_signature('Flight', 'Flight').must_be_nil
249
- Carbon.method_signature('Flight', ['Flight']).must_be_nil
250
- Carbon.method_signature(['Flight'], 'Flight').must_be_nil
251
- Carbon.method_signature(['Flight', 'Flight']).must_be_nil
252
- Carbon.method_signature(['Flight', ['Flight']]).must_be_nil
253
- Carbon.method_signature([['Flight'], 'Flight']).must_be_nil
254
- Carbon.method_signature(MyNissanAltima.new(2001), [MyNissanAltima.new(2001)]).must_be_nil
255
- Carbon.method_signature([MyNissanAltima.new(2001)], MyNissanAltima.new(2001)).must_be_nil
256
- Carbon.method_signature([MyNissanAltima.new(2001)], [MyNissanAltima.new(2001)]).must_be_nil
257
- Carbon.method_signature([MyNissanAltima.new(2001), [MyNissanAltima.new(2001)]]).must_be_nil
258
- Carbon.method_signature([[MyNissanAltima.new(2001)], MyNissanAltima.new(2001)]).must_be_nil
259
- Carbon.method_signature([[MyNissanAltima.new(2001)], [MyNissanAltima.new(2001)]]).must_be_nil
260
- end
261
- end
262
-
263
- describe "mixin" do
264
- describe :emit_as do
265
- it "overwrites old emit_as blocks" do
266
- eval %{class MyFoo; include Carbon; end}
267
- MyFoo.emit_as('Automobile') { provide(:make) }
268
- Carbon::Registry.instance['MyFoo'].characteristics.keys.must_equal [:make]
269
- MyFoo.emit_as('Automobile') { provide(:model) }
270
- Carbon::Registry.instance['MyFoo'].characteristics.keys.must_equal [:model]
271
- end
272
- end
273
- describe '#as_impact_query' do
274
- it "sets up an query to be run by Carbon.query" do
275
- a = MyNissanAltima.new(2006)
276
- a.as_impact_query.must_equal ["Automobile", {:make=>"Nissan", :model=>"Altima", :year=>2006, "automobile_fuel[code]"=>"R"}]
277
- end
278
- it "only includes non-nil params" do
279
- a = MyNissanAltima.new(2006)
280
- a.as_impact_query[1].keys.must_include :year
281
- a.as_impact_query[1].keys.wont_include :nil_model
282
- a.as_impact_query[1].keys.wont_include :nil_make
283
- end
284
- end
285
- describe '#impact' do
286
- it "works" do
287
- impact = MyNissanAltima.new(2006).impact
288
- impact.decisions.carbon.object.value.must_be :>, 0
289
- impact.characteristics.make.description.must_match %r{Nissan}i
290
- impact.characteristics.model.description.must_match %r{Altima}i
291
- impact.characteristics.year.description.to_i.must_equal 2006
292
- impact.characteristics.automobile_fuel.description.must_match %r{regular gasoline}
293
- end
294
- it "takes timeframe" do
295
- impact_2010 = MyNissanAltima.new(2006).impact(:timeframe => Timeframe.new(:year => 2010))
296
- impact_2011 = MyNissanAltima.new(2006).impact(:timeframe => Timeframe.new(:year => 2011))
297
- impact_2010.timeframe.startDate.must_equal '2010-01-01'
298
- impact_2011.timeframe.startDate.must_equal '2011-01-01'
299
- end
300
- end
301
- end
302
- end
@@ -1,25 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'benchmark'
4
- require 'webmock/minitest'
5
- WebMock.disable!
6
- def with_web_mock
7
- WebMock.enable!
8
- WebMock.disable_net_connect!
9
- yield
10
- ensure
11
- WebMock.disable!
12
- end
13
- require 'minitest/spec'
14
- require 'minitest/autorun'
15
- require 'minitest/reporters'
16
- MiniTest::Unit.runner = MiniTest::SuiteRunner.new
17
- MiniTest::Unit.runner.reporters << MiniTest::Reporters::SpecReporter.new
18
- require 'timeframe'
19
- require 'carbon'
20
-
21
- class MiniTest::Spec
22
- def flush_cache!
23
- CacheMethod.config.storage.flush
24
- end
25
- end