tracking_number 1.0.3 → 1.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7f7fa343ef418dd7cd2ace8046a191aaf354798c49afab48f74dc2d086efcb7
4
- data.tar.gz: f39e99015f0ad90fc5bc4e25387ab45f5ecd28a0002a666b60c41e2984855fa8
3
+ metadata.gz: 4f3a1ee8c8aa65591877507ca7c24ee28fc958309b2788ffb794aac3051aeb33
4
+ data.tar.gz: 354a02937aaad7e4bfad81ecb34f4fcf3879cf045a58995ab161410e034892cc
5
5
  SHA512:
6
- metadata.gz: 37351ce16a47c35af8f4cd516931251e9c0b8e30ca216857298d09f29988df0944c68081e773c9f0afe806f51fa98169055b924f1dda9d58e633a7abab1d826b
7
- data.tar.gz: 9ada728daa08df0c616db4cf053fe812e0afa346ccd17ad8fe592838658c88fd6e82bbd1c9070e1916bdbac931071d371d4da927f3224adbfe14d02b62735b39
6
+ metadata.gz: c372d83366a97478d4e7e5ebc8b591d9e1271236b97d6a93dcb3f2e603241e8d2f270ff5bfae9c4b59b3898b665c711fa5c2661ae5df954a9cca3d9e23523519
7
+ data.tar.gz: f92fb5029565b16f24315769bd1dabef1987c16312ab8d6942df085cdebe635a320b8f4dbbe043dd6bfd52404b49c7c1b77b78dceec65924fe6253381951b93c
@@ -0,0 +1,20 @@
1
+ name: Ruby
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v1
12
+ - name: Set up Ruby 2.6
13
+ uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6.x
16
+ - name: Build and test with Rake
17
+ run: |
18
+ gem install bundler
19
+ bundle install --jobs 4 --retry 3
20
+ bundle exec rake
data/.travis.yml CHANGED
@@ -4,9 +4,9 @@ cache: bundler
4
4
  rvm:
5
5
  - 2.0.0
6
6
  - 2.1.10
7
- - 2.2.7
8
- - 2.3.4
9
- - 2.4.1
7
+ - 2.2.9
8
+ - 2.3.6
9
+ - 2.4.3
10
10
  - 2.5.0
11
11
  before_install:
12
12
  - travis_retry gem update --system
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source "http://rubygems.org"
2
2
  # Specify your gem's dependencies in tracking_number.gemspec
3
- gemspec
3
+ gemspec
data/README.md CHANGED
@@ -9,6 +9,10 @@ It detects tracking numbers from UPS, FedEx, DHL, USPS, OnTrac, Amazon Logistics
9
9
 
10
10
  This gem does not do tracking. That is left up to you.
11
11
 
12
+ #### New in 1.0
13
+
14
+ Starting with the 1.0 release the specifications for detecting tracking numbers have been moved into a separate repository ([tracking_number_data](http://github.com/jkeen/tracking_number_data)) that this gem relies on. I did this so a) we can have a single place to document all tracking number types and it can be more of a crowdsourced effort, and b) so clients can be written in other languages easier.
15
+
12
16
  ## Usage
13
17
 
14
18
  #### Checking an individual tracking number
@@ -119,9 +123,6 @@ class Shipment < ActiveRecord::Base
119
123
  end
120
124
  ```
121
125
 
122
- ## Where the data comes from
123
- Starting with the 1.0 release of this gem the data for tracking numbers has been extracted into a separate repository ([tracking_number_data](http://github.com/jkeen/tracking_number_data)) so non-ruby clients can benefit from the detection/documentation that used to be contained deep in the code of this gem. If you want to write a client in some other language, that's the stuff you want.
124
-
125
126
  ## Contributing to tracking_number
126
127
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
127
128
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
@@ -133,5 +134,5 @@ Starting with the 1.0 release of this gem the data for tracking numbers has been
133
134
 
134
135
  ## Copyright
135
136
 
136
- Copyright (c) 2010-2018 Jeff Keen. See LICENSE.txt for
137
+ Copyright (c) 2010-2021 Jeff Keen. See LICENSE.txt for
137
138
  further details.
@@ -3,7 +3,7 @@
3
3
  "courier_code": "usps",
4
4
  "tracking_numbers": [
5
5
  {
6
- "tracking_url": "https://m.usps.com/m/TrackConfirmAction_detail?tLabels=%s",
6
+ "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=%s",
7
7
  "name": "USPS 20",
8
8
  "description": "20 digit USPS numbers",
9
9
  "regex": [
@@ -76,7 +76,7 @@
76
76
  "odds_multiplier": 1
77
77
  }
78
78
  },
79
- "tracking_url": "https://m.usps.com/m/TrackConfirmAction_detail?tLabels=%s",
79
+ "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=%s",
80
80
  "test_numbers": {
81
81
  "valid": [
82
82
  "4201002334249200190132607600833457",
@@ -115,7 +115,7 @@
115
115
  }
116
116
  }
117
117
  },
118
- "tracking_url": "https://m.usps.com/m/TrackConfirmAction_detail?tLabels=%s",
118
+ "tracking_url": "https://tools.usps.com/go/TrackConfirmAction?tLabels=%s",
119
119
  "test_numbers": {
120
120
  "valid": [
121
121
  "420 22153 9101026837331000039521",
@@ -6,7 +6,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
6
6
  elsif TrackingNumber.new(value).valid?
7
7
  # looks good to me
8
8
  else
9
- record.errors[attribute] << (options[:message] || 'is not a valid tracking number')
9
+ record.errors.add(attribute, options[:message] || 'is not a valid tracking number')
10
10
  end
11
11
  end
12
12
  end
@@ -1,5 +1,3 @@
1
- require 'checksum_validations'
2
-
3
1
  module TrackingNumber
4
2
  class Base
5
3
  attr_accessor :tracking_number
@@ -95,7 +93,7 @@ module TrackingNumber
95
93
  name = checksum_info[:name]
96
94
  method_name = "validates_#{name}?"
97
95
 
98
- ChecksumValidations.send(method_name, serial_number, check_digit, checksum_info)
96
+ TrackingNumber::ChecksumValidations.send(method_name, serial_number, check_digit, checksum_info)
99
97
  end
100
98
 
101
99
  def to_s
@@ -113,8 +111,7 @@ module TrackingNumber
113
111
  :service_description => service_description,
114
112
  :destination_zip => destination_zip,
115
113
  :shipper_id => shipper_id,
116
- :package_type => package_type,
117
- :package_description => package_description
114
+ :package_type => package_type
118
115
  })
119
116
  end
120
117
 
@@ -159,7 +156,7 @@ module TrackingNumber
159
156
  end
160
157
 
161
158
  def package_type
162
- if matching_additional["ContainerType"]
159
+ if matching_additional["Container Type"]
163
160
  @package_type ||= Info.new(matching_additional["Container Type"]).name
164
161
  end
165
162
  end
@@ -172,6 +169,21 @@ module TrackingNumber
172
169
  match_group("ShipperId")
173
170
  end
174
171
 
172
+ def tracking_url
173
+ url = nil
174
+ if matching_additional["Courier"]
175
+ url = matching_additional["Courier"][:tracking_url]
176
+ else
177
+ if self.class.const_defined?(:TRACKING_URL)
178
+ url = self.class.const_get(:TRACKING_URL)
179
+ end
180
+ end
181
+
182
+ if url
183
+ url.sub('%s', self.tracking_number)
184
+ end
185
+ end
186
+
175
187
  def matching_additional
176
188
  additional = self.class.const_get(:ADDITIONAL) || []
177
189
 
@@ -0,0 +1,65 @@
1
+ module TrackingNumber
2
+ module ChecksumValidations
3
+ class << self
4
+ def validates_s10?(sequence, check_digit, extras = {})
5
+ weighting = [8,6,4,2,3,5,9,7]
6
+
7
+ total = 0
8
+ sequence.chars.to_a.zip(weighting).each do |(a,b)|
9
+ total += a.to_i * b.to_i
10
+ end
11
+
12
+ remainder = total % 11
13
+ check = case remainder
14
+ when 1
15
+ 0
16
+ when 0
17
+ 5
18
+ else
19
+ 11 - remainder
20
+ end
21
+
22
+ return check.to_i == check_digit.to_i
23
+ end
24
+
25
+ def validates_sum_product_with_weightings_and_modulo?(sequence, check_digit, extras = {})
26
+ weighting = extras[:weightings] || []
27
+
28
+ total = 0
29
+ sequence.chars.to_a.zip(weighting).each do |(a,b)|
30
+ total += a.to_i * b
31
+ end
32
+ return (total % extras[:modulo1] % extras[:modulo2]) == check_digit.to_i
33
+ end
34
+
35
+ def validates_mod10?(sequence, check_digit, extras = {})
36
+ total = 0
37
+ sequence.chars.each_with_index do |c, i|
38
+ x = if c[/[0-9]/] # numeric
39
+ c.to_i
40
+ else
41
+ (c[0].ord - 3) % 10
42
+ end
43
+
44
+ if extras[:odds_multiplier] && i.odd?
45
+ x *= extras[:odds_multiplier].to_i
46
+ elsif extras[:evens_multiplier] && i.even?
47
+ x *= extras[:evens_multiplier].to_i
48
+ end
49
+
50
+ total += x
51
+ end
52
+
53
+ check = (total % 10)
54
+ check = (10 - check) unless (check.zero?)
55
+
56
+ return (check.to_i == check_digit.to_i)
57
+ end
58
+
59
+ def validates_mod7?(sequence, check_digit, extras = {})
60
+ # standard mod 7 check
61
+ return true if sequence.to_i % 7 == check_digit.to_i
62
+ end
63
+ end
64
+ end
65
+ end
@@ -11,8 +11,16 @@ module TrackingNumber
11
11
  end
12
12
  end
13
13
 
14
+ def method_missing(*args)
15
+ nil
16
+ end
17
+
14
18
  def to_s
15
19
  @default || @name
16
20
  end
21
+
22
+ def to_json
23
+
24
+ end
17
25
  end
18
26
  end
@@ -0,0 +1,73 @@
1
+
2
+ module TrackingNumber
3
+ module Loader
4
+ class << self
5
+ def load_tracking_number_data
6
+ tracking_number_types = []
7
+
8
+ Dir.glob(File.join(File.dirname(__FILE__), "../data/couriers/*.json")).each do |file|
9
+ courier_info = read_courier_info(file)
10
+
11
+ courier_info[:tracking_numbers].each do |tracking_info|
12
+ tracking_name = tracking_info[:name]
13
+ klass = create_class(klass, courier_info, tracking_info)
14
+
15
+ # Do some basic checks on the data file
16
+ throw 'missing test numbers' unless has_test_numbers?(tracking_info)
17
+ throw 'missing regex match groups' unless test_numbers_return_required_groups?(tracking_info, Regexp.new(klass::VERIFY_PATTERN))
18
+
19
+ const = register_class(klass, tracking_name)
20
+ tracking_number_types.push(const)
21
+ end
22
+ end
23
+
24
+ TrackingNumber.const_set("TYPES", tracking_number_types)
25
+ end
26
+
27
+ private
28
+
29
+ def has_test_numbers?(tracking)
30
+ return tracking[:test_numbers] && tracking[:test_numbers][:valid]
31
+ end
32
+
33
+ def test_numbers_return_required_groups?(tracking, regex)
34
+ test_number = tracking[:test_numbers][:valid][0]
35
+ matches = test_number.match(regex)
36
+
37
+ return matches["SerialNumber"]
38
+ end
39
+
40
+ def read_courier_info(file)
41
+ return JSON.parse(File.read(file)).deep_symbolize_keys!
42
+ end
43
+
44
+ def create_class(klass, courier_info, tracking_info)
45
+ klass = Class.new(TrackingNumber::Base)
46
+ klass.const_set("COURIER_CODE", courier_info[:courier_code])
47
+ info = courier_info.dup
48
+ info.delete(:tracking_numbers)
49
+ klass.const_set("COURIER_INFO", info)
50
+
51
+ pattern = tracking_info[:regex]
52
+ pattern = tracking_info[:regex].join if tracking_info[:regex].is_a?(Array)
53
+
54
+ verify_pattern = "^#{pattern}$"
55
+ search_pattern = "\\b#{pattern}\\b"
56
+
57
+ klass.const_set("SEARCH_PATTERN", Regexp.new(search_pattern))
58
+ klass.const_set("VERIFY_PATTERN", Regexp.new(verify_pattern))
59
+
60
+ klass.const_set("VALIDATION", tracking_info[:validation])
61
+ klass.const_set("ADDITIONAL", tracking_info[:additional])
62
+ klass.const_set("TRACKING_URL", tracking_info[:tracking_url])
63
+
64
+ return klass
65
+ end
66
+
67
+ def register_class(klass, tracking_name)
68
+ klass_name = tracking_name.gsub(/[^0-9A-Za-z]/, '')
69
+ return TrackingNumber.const_set(klass_name, klass)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module TrackingNumber
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.7"
3
3
  end
@@ -1,10 +1,11 @@
1
1
  # Identify if tracking numbers are valid, and which service they belong to
2
2
 
3
3
  require 'json'
4
+ require 'tracking_number/checksum_validations'
5
+ require 'tracking_number/loader'
4
6
  require 'tracking_number/base'
5
7
  require 'tracking_number/info'
6
8
  require 'tracking_number/unknown'
7
- require 'checksum_validations'
8
9
  require 'active_support/core_ext/string'
9
10
  require 'active_support/core_ext/hash'
10
11
 
@@ -12,67 +13,7 @@ if defined?(ActiveModel::EachValidator)
12
13
  require 'tracking_number/active_model_validator'
13
14
  end
14
15
 
15
- def has_test_numbers?(tracking)
16
- return tracking[:test_numbers] && tracking[:test_numbers][:valid]
17
- end
18
-
19
- def test_numbers_return_required_groups?(tracking, regex)
20
- test_number = tracking[:test_numbers][:valid][0]
21
- matches = test_number.match(regex)
22
-
23
- return matches["SerialNumber"]
24
- end
25
-
26
- def read_courier_info(file)
27
- return JSON.parse(File.read(file)).deep_symbolize_keys!
28
- end
29
-
30
- def create_class(klass, courier_info, tracking_info)
31
- klass = Class.new(TrackingNumber::Base)
32
- klass.const_set("COURIER_CODE", courier_info[:courier_code])
33
- info = courier_info.dup
34
- info.delete(:tracking_numbers)
35
- klass.const_set("COURIER_INFO", info)
36
-
37
- pattern = tracking_info[:regex]
38
- pattern = tracking_info[:regex].join if tracking_info[:regex].is_a?(Array)
39
-
40
- verify_pattern = "^#{pattern}$"
41
- search_pattern = "\\b#{pattern}\\b"
42
-
43
- klass.const_set("SEARCH_PATTERN", Regexp.new(search_pattern))
44
- klass.const_set("VERIFY_PATTERN", Regexp.new(verify_pattern))
45
-
46
- klass.const_set("VALIDATION", tracking_info[:validation])
47
- klass.const_set("ADDITIONAL", tracking_info[:additional])
48
-
49
- return klass
50
- end
51
-
52
- def register_class(klass, tracking_name)
53
- klass_name = tracking_name.gsub(/[^0-9A-Za-z]/, '')
54
- return TrackingNumber.const_set(klass_name, klass)
55
- end
56
-
57
- tracking_number_types = []
58
-
59
- Dir.glob(File.join(File.dirname(__FILE__), "data/couriers/*.json")).each do |file|
60
- courier_info = read_courier_info(file)
61
-
62
- courier_info[:tracking_numbers].each do |tracking_info|
63
- tracking_name = tracking_info[:name]
64
- klass = create_class(klass, courier_info, tracking_info)
65
-
66
- # Do some basic checks on the data file
67
- throw 'missing test numbers' unless has_test_numbers?(tracking_info)
68
- throw 'missing regex match groups' unless test_numbers_return_required_groups?(tracking_info, Regexp.new(klass::VERIFY_PATTERN))
69
-
70
- const = register_class(klass, tracking_name)
71
- tracking_number_types.push(const)
72
- end
73
- end
74
-
75
- TrackingNumber.const_set("TYPES", tracking_number_types)
16
+ TrackingNumber::Loader.load_tracking_number_data
76
17
 
77
18
  module TrackingNumber
78
19
  def self.search(body)
@@ -21,13 +21,6 @@ class TrackingNumberMetaTest < Minitest::Test
21
21
 
22
22
  describe "[#{tracking_info[:name]}]" do
23
23
  tracking_info[:test_numbers][:valid].each do |valid_number|
24
-
25
- should "validate #{valid_number} with #{klass_name}" do
26
- t = klass.new(valid_number)
27
- assert_equal courier_code, t.carrier
28
- assert t.valid?, "should be valid"
29
- end
30
-
31
24
  should "detect #{valid_number} as #{klass_name}" do
32
25
  #TODO fix this multiple matching thing
33
26
  matches = TrackingNumber.search(valid_number)
@@ -45,47 +38,53 @@ class TrackingNumberMetaTest < Minitest::Test
45
38
  should_detect_number_variants(valid_number, "TrackingNumber::#{klass_name}".constantize)
46
39
  end
47
40
 
48
- should "return correct courier code on #{valid_number} when calling #courier_code" do
49
- t = klass.new(valid_number)
50
- assert_equal courier_info[:courier_code].to_sym, t.courier_code
51
- assert_equal courier_info[:courier_code].to_sym, t.courier_code
52
- end
41
+ context "number test" do
42
+ tracking_number = klass.new(valid_number)
53
43
 
54
- should "return correct courier name on #{valid_number} when calling #courier_name" do
55
- t = klass.new(valid_number)
44
+ should "validate #{valid_number} with #{klass_name}" do
45
+ assert_equal courier_code, tracking_number.carrier
46
+ assert tracking_number.valid?, "should be valid"
47
+ end
56
48
 
57
- if (t.matching_additional["Courier"])
58
- assert_equal t.matching_additional["Courier"][:courier], t.courier_name
59
- else
60
- assert_equal courier_name, t.courier_name
49
+ should "return correct courier code on #{valid_number} when calling #courier_code" do
50
+ tracking_number = klass.new(valid_number)
51
+ assert_equal courier_info[:courier_code].to_sym, tracking_number.courier_code
52
+ assert_equal courier_info[:courier_code].to_sym,tracking_number.courier_code
61
53
  end
62
- end
63
54
 
64
- should "not throw an error when calling #service_type on #{valid_number}" do
65
- t = klass.new(valid_number)
66
- service_type = t.service_type
67
- assert service_type.is_a?(String) || service_type.nil?
68
- end
55
+ should "return correct courier name on #{valid_number} when calling #courier_name" do
56
+ if (tracking_number.matching_additional["Courier"])
57
+ assert_equal tracking_number.matching_additional["Courier"][:courier], tracking_number.courier_name
58
+ else
59
+ assert_equal courier_name, tracking_number.courier_name
60
+ end
61
+ end
69
62
 
70
- should "not throw an error when calling #destination on #{valid_number}" do
71
- t = klass.new(valid_number)
72
- assert t.destination_zip.is_a?(String) || t.destination_zip.nil?
73
- end
63
+ should "not throw an error when calling #service_type on #{valid_number}" do
64
+ service_type = tracking_number.service_type
65
+ assert service_type.is_a?(String) || service_type.nil?
66
+ end
74
67
 
75
- should "not throw an error when calling #shipper on #{valid_number}" do
76
- t = klass.new(valid_number)
77
- assert t.shipper_id.is_a?(String) || t.shipper_id.nil?
78
- end
68
+ should "not throw an error when calling #destination on #{valid_number}" do
69
+ assert tracking_number.destination_zip.is_a?(String) || tracking_number.destination_zip.nil?
70
+ end
79
71
 
80
- should "not throw an error when calling #package_type on #{valid_number}" do
81
- t = klass.new(valid_number)
82
- assert t.package_type.is_a?(String) || t.package_type.nil?
83
- end
72
+ should "not throw an error when calling #shipper on #{valid_number}" do
73
+ t = klass.new(valid_number)
74
+ assert tracking_number.shipper_id.is_a?(String) || tracking_number.shipper_id.nil?
75
+ end
76
+
77
+ should "not throw an error when calling #package_type on #{valid_number}" do
78
+ t = klass.new(valid_number)
79
+ assert tracking_number.package_type.is_a?(String) || tracking_number.package_type.nil?
80
+ end
81
+
82
+ should "not throw an error when calling #decode on #{valid_number}" do
83
+ t = klass.new(valid_number)
84
+ decode = tracking_number.decode
85
+ assert decode.is_a?(Hash)
86
+ end
84
87
 
85
- should "not throw an error when calling #decode on #{valid_number}" do
86
- t = klass.new(valid_number)
87
- decode = t.decode
88
- assert decode.is_a?(Hash)
89
88
  end
90
89
  end
91
90
 
@@ -64,6 +64,11 @@ class TrackingNumberTest < Minitest::Test
64
64
  should "report correct no package info" do
65
65
  assert_nil tracking_number.package_type
66
66
  end
67
+
68
+ should "have valid tracking url" do
69
+ assert tracking_number.tracking_url, "Tracking url should not be blank"
70
+ assert tracking_number.tracking_url.include?(tracking_number.tracking_number), "Should include tracking number in the url"
71
+ end
67
72
  end
68
73
 
69
74
  context "tracking number additional data for s10" do
@@ -112,6 +117,11 @@ class TrackingNumberTest < Minitest::Test
112
117
  should "report correct no package info" do
113
118
  assert_nil tracking_number.package_type
114
119
  end
120
+
121
+ should "have valid tracking url" do
122
+ assert tracking_number.tracking_url, "Tracking url should not be blank"
123
+ assert tracking_number.tracking_url.include?(tracking_number.tracking_number), "Should include tracking number in the url"
124
+ end
115
125
  end
116
126
 
117
127
  context "tracking number additional data for USPS 34v2" do
@@ -136,5 +146,10 @@ class TrackingNumberTest < Minitest::Test
136
146
  should "report correct no package info" do
137
147
  assert_nil tracking_number.package_type
138
148
  end
149
+
150
+ should "have valid tracking url" do
151
+ assert tracking_number.tracking_url, "Tracking url should not be blank"
152
+ assert tracking_number.tracking_url.include?(tracking_number.tracking_number), "Should include tracking number in the url"
153
+ end
139
154
  end
140
155
  end
@@ -1,5 +1,6 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ # encoding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
4
  require "tracking_number/version"
4
5
 
5
6
  Gem::Specification.new do |s|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracking_number
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Keen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-06 00:00:00.000000000 Z
11
+ date: 2022-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -132,6 +132,7 @@ extra_rdoc_files:
132
132
  - LICENSE.txt
133
133
  files:
134
134
  - ".document"
135
+ - ".github/workflows/ruby.yml"
135
136
  - ".gitignore"
136
137
  - ".gitmodules"
137
138
  - ".travis.yml"
@@ -139,7 +140,6 @@ files:
139
140
  - LICENSE.txt
140
141
  - README.md
141
142
  - Rakefile
142
- - lib/checksum_validations.rb
143
143
  - lib/data/couriers/amazon.json
144
144
  - lib/data/couriers/dhl.json
145
145
  - lib/data/couriers/fedex.json
@@ -150,7 +150,9 @@ files:
150
150
  - lib/tracking_number.rb
151
151
  - lib/tracking_number/active_model_validator.rb
152
152
  - lib/tracking_number/base.rb
153
+ - lib/tracking_number/checksum_validations.rb
153
154
  - lib/tracking_number/info.rb
155
+ - lib/tracking_number/loader.rb
154
156
  - lib/tracking_number/unknown.rb
155
157
  - lib/tracking_number/version.rb
156
158
  - test/active_model_validator_test.rb
@@ -162,7 +164,7 @@ homepage: http://github.com/jkeen/tracking_number
162
164
  licenses:
163
165
  - MIT
164
166
  metadata: {}
165
- post_install_message:
167
+ post_install_message:
166
168
  rdoc_options: []
167
169
  require_paths:
168
170
  - lib
@@ -177,9 +179,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
179
  - !ruby/object:Gem::Version
178
180
  version: '0'
179
181
  requirements: []
180
- rubyforge_project:
181
- rubygems_version: 2.7.4
182
- signing_key:
182
+ rubygems_version: 3.1.4
183
+ signing_key:
183
184
  specification_version: 4
184
185
  summary: Identifies valid tracking numbers
185
- test_files: []
186
+ test_files:
187
+ - test/active_model_validator_test.rb
188
+ - test/test_helper.rb
189
+ - test/tracking_number_meta_test.rb
190
+ - test/tracking_number_test.rb
@@ -1,63 +0,0 @@
1
- module ChecksumValidations
2
- class << self
3
- def validates_s10?(sequence, check_digit, extras = {})
4
- weighting = [8,6,4,2,3,5,9,7]
5
-
6
- total = 0
7
- sequence.chars.to_a.zip(weighting).each do |(a,b)|
8
- total += a.to_i * b.to_i
9
- end
10
-
11
- remainder = total % 11
12
- check = case remainder
13
- when 1
14
- 0
15
- when 0
16
- 5
17
- else
18
- 11 - remainder
19
- end
20
-
21
- return check.to_i == check_digit.to_i
22
- end
23
-
24
- def validates_sum_product_with_weightings_and_modulo?(sequence, check_digit, extras = {})
25
- weighting = extras[:weightings] || []
26
-
27
- total = 0
28
- sequence.chars.to_a.zip(weighting).each do |(a,b)|
29
- total += a.to_i * b
30
- end
31
- return (total % extras[:modulo1] % extras[:modulo2]) == check_digit.to_i
32
- end
33
-
34
- def validates_mod10?(sequence, check_digit, extras = {})
35
- total = 0
36
- sequence.chars.each_with_index do |c, i|
37
- x = if c[/[0-9]/] # numeric
38
- c.to_i
39
- else
40
- (c[0].ord - 3) % 10
41
- end
42
-
43
- if extras[:odds_multiplier] && i.odd?
44
- x *= extras[:odds_multiplier].to_i
45
- elsif extras[:evens_multiplier] && i.even?
46
- x *= extras[:evens_multiplier].to_i
47
- end
48
-
49
- total += x
50
- end
51
-
52
- check = (total % 10)
53
- check = (10 - check) unless (check.zero?)
54
-
55
- return (check.to_i == check_digit.to_i)
56
- end
57
-
58
- def validates_mod7?(sequence, check_digit, extras = {})
59
- # standard mod 7 check
60
- return true if sequence.to_i % 7 == check_digit.to_i
61
- end
62
- end
63
- end