vin_exploder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ vin_exploder (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.0.8)
10
+ activesupport (= 3.0.8)
11
+ builder (~> 2.1.2)
12
+ i18n (~> 0.5.0)
13
+ activerecord (3.0.8)
14
+ activemodel (= 3.0.8)
15
+ activesupport (= 3.0.8)
16
+ arel (~> 2.0.10)
17
+ tzinfo (~> 0.3.23)
18
+ activesupport (3.0.8)
19
+ arel (2.0.10)
20
+ builder (2.1.2)
21
+ diff-lcs (1.1.2)
22
+ i18n (0.5.0)
23
+ rspec (2.6.0)
24
+ rspec-core (~> 2.6.0)
25
+ rspec-expectations (~> 2.6.0)
26
+ rspec-mocks (~> 2.6.0)
27
+ rspec-core (2.6.3)
28
+ rspec-expectations (2.6.0)
29
+ diff-lcs (~> 1.1.2)
30
+ rspec-mocks (2.6.0)
31
+ sequel (3.24.1)
32
+ simplecov (0.4.2)
33
+ simplecov-html (~> 0.4.4)
34
+ simplecov-html (0.4.5)
35
+ sqlite3 (1.3.3)
36
+ tzinfo (0.3.27)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ activerecord (>= 3.0.0)
43
+ rspec (>= 2.6.0)
44
+ sequel
45
+ simplecov
46
+ sqlite3
47
+ vin_exploder!
data/README.textile ADDED
@@ -0,0 +1,74 @@
1
+ h1. VinExploder
2
+
3
+ A ruby library for retrieving and caching Vehicle Identification Number (VIN) lookups.
4
+
5
+ h2. How to install
6
+
7
+ *Bundler*
8
+
9
+ <pre>
10
+ gem vin_exploder
11
+ </pre>
12
+
13
+ *Rubygems*
14
+
15
+ <pre>
16
+ gem install vin_exploder
17
+ </pre>
18
+
19
+ h2. How to use
20
+
21
+ Using the vin exploder will require a decoding service adapter. Thankfully one is available in the Vinquery "gem":http://github.com/tinomen/vinquery
22
+
23
+ <pre>
24
+ require 'vin_exploder'
25
+ # require the Vinquery.com adapter
26
+ require 'vinquery/vin_exploder/adapter'
27
+
28
+ # tell vin_exploder to use the Vinquery.com adapter and pass it's required config
29
+ VinExploder.config.adapter :vinquery, {:url => 'VINQUERY_URL', :access_code => 'ACCESS_CODE', :report_type => 'REPORT_TYPE'}
30
+ # request the decoded VIN data
31
+ vin_explosion = VinExploder.get('1FTWX31R19EB18840')
32
+
33
+ vin_explosion.valid? # true
34
+ vin_explosion.make # Ford
35
+ </pre>
36
+
37
+ h3. Rails use
38
+
39
+ Create an initializer for the config
40
+
41
+ <pre>
42
+ require 'vin_exploder'
43
+ require 'vinquery/vin_exploder/adapter'
44
+
45
+ VinExploder.config.adapter :vinquery, {:url => 'VINQUERY_URL', :access_code => 'ACCESS_CODE', :report_type => 'REPORT_TYPE'}
46
+ </pre>
47
+
48
+ h3. Optional Cache
49
+
50
+ To save on the cost of looking up a VIN multiple times setup a cache
51
+
52
+ <pre>
53
+ require 'vin_exploder'
54
+ # require the Sequel based cache store
55
+ require 'vin_exploder/cache/sequel_cache_store'
56
+ # require the Vinquery.com adapter
57
+ require 'vinquery/vin_exploder/adapter'
58
+
59
+ # tell vin_exploder to use the Sequel based cache store adapter and pass in the connection config
60
+ VinExploder.config.cache_store :sequel_cache_store, "mysql://localhost:3896/vin_cache"
61
+
62
+ # tell vin_exploder to use the Vinquery.com adapter and pass it's required config
63
+ VinExploder.config.adapter :vinquery, {:url => 'VINQUERY_URL', :access_code => 'ACCESS_CODE', :report_type => 'REPORT_TYPE'}
64
+
65
+ # request the decoded VIN data
66
+ vin_explosion = VinExploder.get('1FTWX31R19EB18840')
67
+
68
+ vin_explosion.valid? #=> true
69
+ vin_explosion.make #=> Ford
70
+
71
+ # decoded VIN data is retrieved from cache
72
+ vin_explosion2 = VinExploder.get('1FTWX31R19EB18840')
73
+ vin_explosion2.make #=> Ford
74
+ </pre>
@@ -0,0 +1,47 @@
1
+
2
+ module VinExploder
3
+
4
+ module Decode
5
+
6
+ class VinExploderAdapterError < StandardError; end
7
+
8
+ class AbstractAdapter
9
+
10
+ def initialize(options={})
11
+ @options = options
12
+ end
13
+
14
+ # Fetch, normalize and return the decoded data as a hash.
15
+ #
16
+ # *vin*::
17
+ # The Vehicle Identification Number
18
+ #
19
+ # == Returns:
20
+ # An array containing the decoded data hash.
21
+ #
22
+ # Should an error occur while decoding the vin the hash should
23
+ # include a key of :errors with an array of errors
24
+ # in the form of: {'error name' => 'error message'}
25
+ #
26
+ # Normalize the hash from the vendor to use keys known by VinExploder.
27
+ # All keys should be made into symbols following the ruby snake case convention.
28
+ #
29
+ # The keys that must be normalized are as follows:
30
+ # make
31
+ # model
32
+ # year => YYYY
33
+ # driveline => FWD|4WD|AWD
34
+ # body_style
35
+ # fuel_type => GAS|DIESEL|HYBRID
36
+ # trim_level
37
+ #
38
+ # All remaining keys should be symbols but can remain vendor specific
39
+ def explode(vin)
40
+ raise NotImplementedError.new("Unimplemented explode method.")
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,42 @@
1
+ require 'active_record'
2
+ require 'Base64'
3
+
4
+ module VinExploder
5
+ module Cache
6
+
7
+ # A VinExploder cache adapter using ActiveRecord for saving the decoded vin attributes.
8
+ #
9
+ # this store assumes a model with 2 attributes:
10
+ # - *key*: the first 8, 10th and 11th characters of the vin
11
+ # - *data*: A hash of the decoded vin attributes
12
+ class ActiveRecordCacheStore < Store
13
+
14
+ def initialize(options = {})
15
+ super
16
+ @model = options[:model_class]
17
+ end
18
+
19
+ def read(vin)
20
+ key = make_vin_cache_key(vin)
21
+ obj = @model.find_by_key(key)
22
+ obj.data unless obj.nil?
23
+ end
24
+
25
+ def write(vin, hash)
26
+ key = make_vin_cache_key(vin)
27
+ obj = @model.new :key => key, :data => hash
28
+ obj.save
29
+ hash
30
+ end
31
+
32
+ def delete(vin)
33
+ key = make_vin_cache_key(vin)
34
+ obj = @model.find_by_key(key)
35
+ deleted = obj.delete()
36
+ !deleted.nil?
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ require 'sequel'
2
+ require 'Base64'
3
+
4
+ module VinExploder
5
+ module Cache
6
+
7
+ # A VinExploder cache adapter using Sequel for saving the decoded vin attributes.
8
+ #
9
+ # this store assumes there are 2 columns on the table:
10
+ # - *key*: the first 8, 10th and 11th characters of the vin
11
+ # - *data*: A hash of the decoded vin attributes
12
+ class SequelCacheStore < Store
13
+
14
+ def initialize(options = {})
15
+ super
16
+ @connection = Sequel.connect(options)
17
+ end
18
+
19
+ def read(vin)
20
+ key = make_vin_cache_key(vin)
21
+ data = @connection[:vins].where(:key => key).first
22
+ Marshal.load(data[:data]) unless data.nil?
23
+ end
24
+
25
+ def write(vin, hash)
26
+ key = make_vin_cache_key(vin)
27
+ @connection[:vins].insert(:key => key, :data => Marshal.dump(hash))
28
+ hash
29
+ end
30
+
31
+ def delete(vin)
32
+ key = make_vin_cache_key(vin)
33
+ result = @connection[:vins].where(:key => key).delete
34
+ result > 0
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+
2
+ module VinExploder
3
+
4
+ module Cache
5
+
6
+
7
+ # An abstract cache store class that acts as a null cache as well
8
+ class Store
9
+
10
+ attr_reader :connection
11
+
12
+ # Create a new cache.
13
+ def initialize(options = nil)
14
+ @options = options ? options.dup : {}
15
+ end
16
+
17
+ # Fetches VIN data from the cache using the given key. If the VIN has been
18
+ # cached, then the VIN attributes are returned.
19
+ #
20
+ # If the VIN is not in the cache (a cache miss occurred),
21
+ # then nil will be returned. However, if a block has been passed, then
22
+ # that block will be run in the event of a cache miss. The return value
23
+ # of the block will be written to the cache under the given VIN,
24
+ # and that return value will be returned.
25
+ #
26
+ # cache.write("VIN_NUMBER", {:make => 'Ford', :model => 'F150'})
27
+ # cache.fetch("VIN_NUMBER") # => {:make => 'Ford', :model => 'F150'}
28
+ #
29
+ # cache.fetch("VIN_NUMBER_2") # => nil
30
+ # cache.fetch("VIN_NUMBER_2") do
31
+ # {:make => 'Dodge', :model => '1500'}
32
+ # end
33
+ # cache.fetch("VIN_NUMBER_2") # => {:make => 'Dodge', :model => '1500'}
34
+ #
35
+ def fetch(vin)
36
+ if block_given?
37
+ hash = read(vin)
38
+ if hash.nil?
39
+ hash = yield
40
+ write(vin, hash)
41
+ end
42
+ else
43
+ hash = read(vin)
44
+ end
45
+ end
46
+
47
+ # Fetches VIN data from the cache, using the given key. If VIN has
48
+ # been cached with the given key, then the VIN attributes are returned. Otherwise,
49
+ # nil is returned.
50
+ def read(vin)
51
+ nil
52
+ end
53
+
54
+ # Writes the value to the cache, with the key.
55
+ def write(vin, hash)
56
+ hash
57
+ end
58
+
59
+ # Deletes an entry in the cache. Returns +true+ if an entry is deleted.
60
+ def delete(vin)
61
+ true
62
+ end
63
+
64
+ protected
65
+
66
+ # the cache key for vins should be based on characters 0-8, 10-11.
67
+ # Position 9 is a checksum value and should not be used in the key.
68
+ def make_vin_cache_key(vin)
69
+ key = vin.slice(0,8)
70
+ key << vin.slice(10,2)
71
+ end
72
+
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,45 @@
1
+
2
+ module VinExploder
3
+
4
+ class Configuration
5
+
6
+ attr_accessor :cache_options, :adapter_options
7
+
8
+ def initialize
9
+ @cache_store = nil
10
+ @cache_options = {}
11
+ @adapter = nil
12
+ @adapter_options = {}
13
+ end
14
+
15
+ def cache_store(*args)
16
+ if args.empty?
17
+ case @cache_store
18
+ when Symbol
19
+ VinExploder::Cache.const_get(@cache_store.to_s.split('_').map{|s| s.capitalize }.join)
20
+ else
21
+ @cache_store
22
+ end
23
+ else
24
+ @cache_store = args.shift
25
+ @cache_options = args.shift || {}
26
+ end
27
+ end
28
+
29
+ def adapter(*args)
30
+ if args.empty?
31
+ case @adapter
32
+ when Symbol
33
+ VinExploder::Decode.const_get(@adapter.to_s.split('_').map{|s| s.capitalize }.join)
34
+ else
35
+ @adapter
36
+ end
37
+ else
38
+ @adapter = args.shift
39
+ @adapter_options = args.shift || {}
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,30 @@
1
+ module VinExploder
2
+
3
+ class MissingAdapter < StandardError
4
+ end
5
+
6
+ class Exploder
7
+
8
+ def initialize(adapter, cache=nil)
9
+ raise MissingAdapter.new("No vin decoding vendor adapter has been provided.") if adapter.nil?
10
+ @cache = cache ? cache : Cache::Store.new
11
+ @adapter = adapter
12
+ end
13
+
14
+ # Get vin Explosion.
15
+ #
16
+ # == Parameters
17
+ # vin:: vehicle identification number
18
+ #
19
+ # == Return
20
+ # An Explosion object containing the decoded vin attributes
21
+ def get(vin)
22
+ hash = @cache.fetch(vin) do
23
+ # get from vender adapter
24
+ @adapter.explode(vin)
25
+ end
26
+ Explosion.new vin, hash, hash.delete(:errors)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ require 'yaml'
2
+
3
+ module VinExploder
4
+
5
+ class Explosion
6
+
7
+ attr_reader :vin, :success, :errors, :make, :model, :year, :driveline, :body_style, :fuel_type, :all
8
+
9
+ def initialize(vin, vin_hash, errors={})
10
+ @vin = vin
11
+ @all = vin_hash
12
+ @make = @all[:make]
13
+ @model = @all[:model]
14
+ @year = @all[:year]
15
+ @driveline = @all[:driveline]
16
+ @body_style = @all[:body_style]
17
+ @fuel_type = @all[:fuel_type]
18
+ @trim_level = @all[:trim_level]
19
+ @errors = errors.nil? ? {} : errors
20
+ @success = @errors.empty?
21
+ end
22
+
23
+ def valid?
24
+ @success
25
+ end
26
+ alias :success? :valid?
27
+
28
+ # def _dump(level=-1)
29
+ # [@vin, @all.to_yaml].join('^')
30
+ # end
31
+ #
32
+ # def self._load(args)
33
+ # a = *args.split('^')
34
+ # hash = YAML.load(a[1])
35
+ # new(a[0], hash)
36
+ # end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,3 @@
1
+ module VinExploder
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module VinExploder
3
+
4
+ def self.explode(vin)
5
+ cache = VinExploder.config.cache_store ? VinExploder.config.cache_store.new(VinExploder.config.cache_options) : nil
6
+ adapter = VinExploder.config.adapter.new(VinExploder.config.adapter_options)
7
+ exploder = Exploder.new(adapter, cache)
8
+ explosion = exploder.get(vin)
9
+ end
10
+
11
+ def self.config
12
+ @@config ||= VinExploder::Configuration.new()
13
+ end
14
+
15
+ end
16
+
17
+ require 'vin_exploder/cache'
18
+ require 'vin_exploder/explosion'
19
+ require 'vin_exploder/exploder'
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'vin_exploder/adapter'
3
+
4
+ module VinExploder
5
+ module Decode
6
+
7
+ describe AbstractAdapter do
8
+
9
+ it "should raise an NotImplementedError on explode" do
10
+ expect { AbstractAdapter.new.explode("VIN") }.to raise_error(NotImplementedError)
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'sqlite3'
3
+ require 'vin_exploder/cache'
4
+ require 'vin_exploder/cache/activerecord_cache_store'
5
+
6
+ module VinExploder
7
+ module Cache
8
+
9
+ class TestArCacheStore < ActiveRecord::Base
10
+ attr_accessor :vin, :make
11
+ serialize :data
12
+ def initialize(attributes={})
13
+ super attributes
14
+ key = attributes.delete(:key)
15
+ # @data = attributes[:data]
16
+ @attributes = {'key' => key, 'vin' => attributes[:vin], 'make' => attributes[:make], 'data' => attributes[:data]}
17
+ end
18
+ end
19
+
20
+ describe ActiveRecordCacheStore do
21
+
22
+ before(:all) do
23
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ':memory:')
24
+ ActiveRecord::Schema.define do
25
+ create_table :test_ar_cache_stores, :force => true do |t|
26
+ t.column :key, :string
27
+ t.column :vin, :string
28
+ t.column :make, :string
29
+ t.column :data, :text
30
+ end
31
+ end
32
+
33
+ @store = ActiveRecordCacheStore.new :model_class => TestArCacheStore
34
+
35
+ end
36
+
37
+ after(:each) do
38
+ TestArCacheStore.delete_all
39
+ end
40
+
41
+ it "should read and write a hash" do
42
+ hash = @store.read("fake_vin_number")
43
+ hash.should be_nil
44
+ @store.write("fake_vin_number", {:vin => 'fake_vin_number', :make => 'Ford'})
45
+ hash = @store.read("fake_vin_number")
46
+ hash.should_not be_nil
47
+ hash[:make].should == 'Ford'
48
+ end
49
+
50
+ it "should fetch and cache new vins" do
51
+ hash = @store.fetch("fake_vin_number") do
52
+ {:vin => 'fake_vin_number', :make => 'Ford'}
53
+ end
54
+ hash2 = @store.read("fake_vin_number")
55
+ hash[:vin].should == hash2[:vin]
56
+ end
57
+
58
+ it "should delete a vin from the cache" do
59
+ hash = @store.read("fake_vin_number")
60
+ hash.should be_nil
61
+ @store.write(:fake_vin_number, {:vin => 'fake_vin_number', :make => 'Ford'})
62
+ hash = @store.read("fake_vin_number")
63
+ hash.should_not be_nil
64
+ hash[:make].should == 'Ford'
65
+ deleted = @store.delete("fake_vin_number")
66
+ deleted.should == true
67
+ hash = @store.read("fake_vin_number")
68
+ hash.should be_nil
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ module VinExploder
4
+ module Cache
5
+
6
+ describe Store do
7
+
8
+ describe '#read' do
9
+ it 'should return the cached vin explosion' do
10
+ Store.new.read('DOESNTMATTER').should == nil
11
+ end
12
+ it 'should return nil if no explosion found' do
13
+ Store.new.read('DOESNTMATTER').should == nil
14
+ end
15
+ end
16
+
17
+ describe '#write' do
18
+ it 'should return the value that was written' do
19
+ Store.new.write('VIN', 'EXPLODED_VIN').should == 'EXPLODED_VIN'
20
+ Store.new.read('VIN').should == nil
21
+ end
22
+ end
23
+
24
+ describe '#fetch' do
25
+ it 'should execute the block and pass through #write' do
26
+ store = Store.new
27
+ store.should_receive(:write).with('VIN', 'EXPLODED_VIN').exactly(1).times { 'EXPLODED_VIN' }
28
+ store.fetch('VIN') do
29
+ 'EXPLODED_VIN'
30
+ end.should == 'EXPLODED_VIN'
31
+ end
32
+
33
+ it 'should return nil with no block' do
34
+ store = Store.new
35
+ store.should_receive(:read).with('VIN').exactly(1).times { 'EXPLODED_VIN' }
36
+ store.fetch('VIN').should == 'EXPLODED_VIN'
37
+ end
38
+ end
39
+
40
+ describe '#delete' do
41
+ it 'should return true if cache item was deleted' do
42
+ Store.new.delete('VIN').should == true
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+ require 'sqlite3'
3
+ require 'sequel'
4
+ require 'vin_exploder/cache'
5
+ require 'vin_exploder/cache/sequel_cache_store'
6
+
7
+ module VinExploder
8
+ module Cache
9
+
10
+ describe SequelCacheStore do
11
+
12
+ before(:all) do
13
+ @db_config = {:adapter => "sqlite"}
14
+ @store = SequelCacheStore.new @db_config
15
+ @store.connection.create_table(:vins) do
16
+ String :key, :unique=>true, :size=>10
17
+ String :data, :null=>false, :text=>true
18
+ end
19
+ end
20
+
21
+ after(:each) do
22
+ @store.connection[:vins].truncate
23
+ end
24
+
25
+ it "should initialize" do
26
+ @store.class.should == SequelCacheStore
27
+ end
28
+
29
+ it "should read and write a hash" do
30
+ hash = @store.read(:fake_vin_number)
31
+ hash.should be_nil
32
+ @store.write(:fake_vin_number, {:vin => 'fake_vin_number', :make => 'Ford'})
33
+ hash = @store.read(:fake_vin_number)
34
+ hash.should_not be_nil
35
+ hash[:make].should == 'Ford'
36
+ end
37
+
38
+ it "should fetch and cache new vins" do
39
+ hash = @store.fetch(:fake_vin_number) do
40
+ {:vin => 'fake_vin_number', :make => 'Ford'}
41
+ end
42
+ hash2 = @store.read(:fake_vin_number)
43
+ hash[:vin].should == hash2[:vin]
44
+ end
45
+
46
+ it "should delete a vin from the cache" do
47
+ hash = @store.read(:fake_vin_number)
48
+ hash.should be_nil
49
+ @store.write(:fake_vin_number, {:vin => 'fake_vin_number', :make => 'Ford'})
50
+ hash = @store.read(:fake_vin_number)
51
+ hash.should_not be_nil
52
+ hash[:make].should == 'Ford'
53
+ deleted = @store.delete(:fake_vin_number)
54
+ deleted.should == true
55
+ hash = @store.read(:fake_vin_number)
56
+ hash.should be_nil
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'vin_exploder/configuration'
3
+
4
+ module VinExploder
5
+
6
+ describe Configuration do
7
+
8
+ describe '#cache_store' do
9
+ it 'should return nil if no cache is set' do
10
+ c = Configuration.new
11
+ c.cache_store.should == nil
12
+ end
13
+
14
+ it 'should convert a symbol to a camel case constant within the VinExploder::Cache scope' do
15
+ class VinExploder::Cache::TestSymbolConst; end
16
+ c = Configuration.new
17
+ c.cache_store :test_symbol_const
18
+ c.cache_store.should == VinExploder::Cache::TestSymbolConst
19
+ end
20
+
21
+ it 'should return the constant previously set' do
22
+ c = Configuration.new
23
+ c.cache_store String
24
+ c.cache_store.should == String
25
+ end
26
+ end
27
+
28
+ describe '#adapter' do
29
+ it 'should return nil where no adapter defined' do
30
+ c = Configuration.new
31
+ c.adapter.should == nil
32
+ end
33
+
34
+ it 'should convert a symbol to a camel case constant within the VinExploder::Decode scope' do
35
+ class VinExploder::Decode::TestSymbolConst; end
36
+ c = Configuration.new
37
+ c.adapter :test_symbol_const
38
+ c.adapter.should == VinExploder::Decode::TestSymbolConst
39
+ end
40
+
41
+ it 'should return the constant previously set' do
42
+ c = Configuration.new
43
+ c.adapter String
44
+ c.adapter.should == String
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ if ENV["COVERAGE"]
3
+ require 'simplecov'
4
+ SimpleCov.start 'rails'
5
+ end
6
+
7
+ require "bundler"
8
+ Bundler.setup
9
+
10
+ require 'rspec'
11
+
12
+ require 'vin_exploder'
13
+
14
+ RSpec.configure do |config|
15
+
16
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'vin_exploder'
3
+
4
+ class VinExploder::Decode::TestAdapter; end
5
+
6
+ module VinExploder
7
+
8
+ describe Exploder do
9
+
10
+ describe '#new' do
11
+ it "should raise a MissingAdapter error if nil is provided to initialize" do
12
+ expect { Exploder.new(nil) }.to raise_error(MissingAdapter)
13
+ end
14
+
15
+ it "should raise a ArgumentError error if no arguments are provided to initialize" do
16
+ expect { Exploder.new }.to raise_error(ArgumentError)
17
+ end
18
+
19
+ it "should initialize with a default cache store when no cache argument is passed" do
20
+ s = VinExploder::Cache::Store.new
21
+ VinExploder::Cache::Store.should_receive(:new).exactly(1).times { s }
22
+ e = Exploder.new(double("Adapter"))
23
+ end
24
+ end
25
+
26
+ describe '#get' do
27
+ it "should get a vin Explosion" do
28
+ a = double("Adapter")
29
+ a.should_receive(:explode) { {} }
30
+ e = Exploder.new(a)
31
+ ex = e.get('VIN')
32
+ ex.class.should == VinExploder::Explosion
33
+ ex.valid?.should == true
34
+ ex.success?.should == true
35
+ end
36
+ end
37
+
38
+ describe "VinExploder#explode" do
39
+ it "should return an Explosion object" do
40
+ ta = VinExploder::Decode::TestAdapter.new
41
+ ta.should_receive(:explode) { {} }
42
+ VinExploder::Decode::TestAdapter.should_receive(:new){ ta }
43
+
44
+ VinExploder.config.adapter :test_adapter
45
+ VinExploder.explode("VIN").class.should == Explosion
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vin_exploder
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Jake Mallory
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-20 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.6.0
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: simplecov
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: sequel
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: sqlite3
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: activerecord
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 3.0.0
68
+ type: :development
69
+ version_requirements: *id005
70
+ description: A caching client for vin decoding web services. The caching allows the consumer to avoid the cost of secondary lookups.
71
+ email: tinomen@gmail.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files:
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - README.textile
80
+ files:
81
+ - lib/vin_exploder/adapter.rb
82
+ - lib/vin_exploder/cache/activerecord_cache_store.rb
83
+ - lib/vin_exploder/cache/sequel_cache_store.rb
84
+ - lib/vin_exploder/cache.rb
85
+ - lib/vin_exploder/configuration.rb
86
+ - lib/vin_exploder/exploder.rb
87
+ - lib/vin_exploder/explosion.rb
88
+ - lib/vin_exploder/version.rb
89
+ - lib/vin_exploder.rb
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - README.textile
93
+ - spec/abstract_adapter_spec.rb
94
+ - spec/cache/activerecord_cache_store_spec.rb
95
+ - spec/cache/cache_store_spec.rb
96
+ - spec/cache/sequel_cache_store_spec.rb
97
+ - spec/configuration_spec.rb
98
+ - spec/spec_helper.rb
99
+ - spec/vin_exploder_spec.rb
100
+ homepage: http://github.com/tinomen/vin_exploder
101
+ licenses: []
102
+
103
+ post_install_message:
104
+ rdoc_options:
105
+ - --title
106
+ - A caching client for vin decoding services
107
+ - --main
108
+ - README.textile
109
+ - --line-numbers
110
+ - --charset=UTF-8
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: "0"
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 1.3.6
125
+ requirements: []
126
+
127
+ rubyforge_project:
128
+ rubygems_version: 1.7.2
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: A caching client for vin decoding services
132
+ test_files:
133
+ - spec/abstract_adapter_spec.rb
134
+ - spec/cache/activerecord_cache_store_spec.rb
135
+ - spec/cache/cache_store_spec.rb
136
+ - spec/cache/sequel_cache_store_spec.rb
137
+ - spec/configuration_spec.rb
138
+ - spec/spec_helper.rb
139
+ - spec/vin_exploder_spec.rb