vin_exploder 0.1.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.
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