carbon 2.2.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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