resident 0.0.9
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/.gemtest +0 -0
 - data/MIT-LICENSE +19 -0
 - data/README.rdoc +57 -0
 - data/lib/national_identification_number/base.rb +31 -0
 - data/lib/national_identification_number/finnish.rb +53 -0
 - data/lib/national_identification_number/swedish.rb +105 -0
 - data/lib/national_identification_number.rb +2 -0
 - data/lib/resident.rb +1 -0
 - data/spec/national_identification_number/base_spec.rb +74 -0
 - data/spec/national_identification_number/finnish_spec.rb +60 -0
 - data/spec/national_identification_number/swedish_spec.rb +147 -0
 - metadata +98 -0
 
    
        data/.gemtest
    ADDED
    
    | 
         
            File without changes
         
     | 
    
        data/MIT-LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2011 Bukowskis.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 4 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 5 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 6 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 7 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 8 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 11 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 14 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 15 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 16 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 17 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 18 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 19 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = Resident
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Validates a National Identification Number (See http://en.wikipedia.org/wiki/National_identification_number).
         
     | 
| 
      
 4 
     | 
    
         
            +
            There are some 62 countries that have this type of number.
         
     | 
| 
      
 5 
     | 
    
         
            +
            This gem currently only supports Swedish (Personnummer) and Finnish (Henkilöasiakkaat) ones.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            There is a special focus on identifying these numbers robustly (i.e. you can safely validate a param[:number] directly, or cleanup your database by running every non-normalized value through this gem).
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            == Installation
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                gem install resident
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            == Usage
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            Really, you can just use <tt>valid?</tt> and <tt>to_s</tt> like so:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                require 'resident'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                number = NationalIdentificationNumber::Swedish.new('0501261853')
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                number.valid?  #=> true
         
     | 
| 
      
 22 
     | 
    
         
            +
                number.to_s    #=> "050126-1853"
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            Please have a look at the specs to see how the national identification numbers of various countries are handled.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            An example of robustness:
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                NationalIdentificationNumber::Swedish.new("19050126-185d3\n").to_s => "050126-1853"
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            == License
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            Some marked parts of the code are inspired or taken from MIT licensed code of
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            * Peter Hellberg https://github.com/c7/personnummer/blob/master/lib/personnummer.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            * Henrik Nyh http://henrik.nyh.se
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            Other than that you got:
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            Copyright (c) 2011 Bukowskis.
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 42 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 43 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 44 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 45 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 46 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 49 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 52 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 53 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 54 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 55 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 56 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 57 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'date'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module NationalIdentificationNumber
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Base
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(number)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @number = number
         
     | 
| 
      
 8 
     | 
    
         
            +
                  repair
         
     | 
| 
      
 9 
     | 
    
         
            +
                  validate
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def valid?
         
     | 
| 
      
 13 
     | 
    
         
            +
                  !!@valid
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @number
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                protected
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def repair
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @number = @number.to_s.upcase.gsub(/\s/, '')
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def validate
         
     | 
| 
      
 27 
     | 
    
         
            +
                  raise 'You need to implement at least this method in subclasses.'
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'national_identification_number/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module NationalIdentificationNumber
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Finnish < Base
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                CHECKSUMS = %w{ 0 1 2 3 4 5 6 7 8 9 A B C D E F H J K L M N P R S T U V W X Y }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                protected
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def repair
         
     | 
| 
      
 11 
     | 
    
         
            +
                  super
         
     | 
| 
      
 12 
     | 
    
         
            +
                  if @number.match(/(\d{6})(\-{0,1})(\d{3})([#{CHECKSUMS}]{1})/)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @number = "#{$1}-#{$3}#{$4}"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  else
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @number.gsub!(/[^#{CHECKSUMS}\-\+]/, '')
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def validate
         
     | 
| 
      
 20 
     | 
    
         
            +
                  if @number.match(/(\d{2})(\d{2})(\d{2})([\-\+A]{0,1})(\d{3})([#{CHECKSUMS}]{1})/)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    checksum = self.class.calculate_checksum("#{$1}#{$2}#{$3}#{$5}")
         
     | 
| 
      
 22 
     | 
    
         
            +
                    if checksum == $6
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      day     = $1.to_i
         
     | 
| 
      
 25 
     | 
    
         
            +
                      month   = $2.to_i
         
     | 
| 
      
 26 
     | 
    
         
            +
                      year    = $3.to_i
         
     | 
| 
      
 27 
     | 
    
         
            +
                      divider ||= $4 ||'-'
         
     | 
| 
      
 28 
     | 
    
         
            +
                      serial  = $5.to_i
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                      century = case divider
         
     | 
| 
      
 31 
     | 
    
         
            +
                      when '+' then 1800
         
     | 
| 
      
 32 
     | 
    
         
            +
                      when 'A' then 2000
         
     | 
| 
      
 33 
     | 
    
         
            +
                      else          1900
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 37 
     | 
    
         
            +
                        Date.parse("#{century+year}-#{month}-#{day}")
         
     | 
| 
      
 38 
     | 
    
         
            +
                        @valid = true
         
     | 
| 
      
 39 
     | 
    
         
            +
                        @number = ("#{$1}#{$2}#{$3}#{divider}#{$5}#{checksum}")
         
     | 
| 
      
 40 
     | 
    
         
            +
                      rescue ArgumentError
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                private
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def self.calculate_checksum(number)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  CHECKSUMS[number.to_i % 31]
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,105 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'national_identification_number/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module NationalIdentificationNumber
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Inspired by https://github.com/c7/personnummer/blob/master/lib/personnummer.rb
         
     | 
| 
      
 5 
     | 
    
         
            +
              # Copyright (c) 2008 Peter Hellberg MIT
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Swedish < Base
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :date # used for testing
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # Generator for valid Swedish personnummer: http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)
         
     | 
| 
      
 11 
     | 
    
         
            +
                # By Henrik Nyh <http://henrik.nyh.se> 2009-01-29 under the MIT license.
         
     | 
| 
      
 12 
     | 
    
         
            +
                def self.generate(date=nil, serial=nil)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  date ||= Date.new(1900+rand(100), 1+rand(12), 1+rand(28))
         
     | 
| 
      
 14 
     | 
    
         
            +
                  serial = serial ? serial.to_s : format("%03d", rand(999)+1)  # 001-999
         
     | 
| 
      
 15 
     | 
    
         
            +
                  date_part = date.strftime('%y%m%d')
         
     | 
| 
      
 16 
     | 
    
         
            +
                  pnr = [date_part, serial].join
         
     | 
| 
      
 17 
     | 
    
         
            +
                  digits = []
         
     | 
| 
      
 18 
     | 
    
         
            +
                  pnr.split('').each_with_index do |n,i|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    digits << n.to_i * (2 - i % 2)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  sum = digits.join.split('').inject(0) {|sum,digit| sum + digit.to_i }
         
     | 
| 
      
 22 
     | 
    
         
            +
                  checksum = 10 - sum % 10
         
     | 
| 
      
 23 
     | 
    
         
            +
                  checksum = 0 if checksum == 10
         
     | 
| 
      
 24 
     | 
    
         
            +
                  "#{date_part}-#{serial}#{checksum}"
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                protected
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def repair
         
     | 
| 
      
 30 
     | 
    
         
            +
                  super
         
     | 
| 
      
 31 
     | 
    
         
            +
                  if @number.match(/\A(\d{0}|\d{2})(\d{6})(\-{0,1})(\d{4})\Z/)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @number = "#{$2}-#{$4}"
         
     | 
| 
      
 33 
     | 
    
         
            +
                  else
         
     | 
| 
      
 34 
     | 
    
         
            +
                    @number.gsub!(/[^\d\-\+]/, '')
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def validate
         
     | 
| 
      
 39 
     | 
    
         
            +
                  if @number.match(/(\d{2})(\d{2})(\d{2})([\-\+]{0,1})(\d{3})(\d{1})/)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    checksum = self.class.luhn_algorithm("#{$1}#{$2}#{$3}#{$5}")
         
     | 
| 
      
 41 
     | 
    
         
            +
                    if checksum == $6.to_i
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                       year    = $1.to_i
         
     | 
| 
      
 44 
     | 
    
         
            +
                       month   = $2.to_i
         
     | 
| 
      
 45 
     | 
    
         
            +
                       day     = $3.to_i
         
     | 
| 
      
 46 
     | 
    
         
            +
                       divider ||= $4 ||'-'
         
     | 
| 
      
 47 
     | 
    
         
            +
                       serial  = $5.to_i
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                       today = Date.today
         
     | 
| 
      
 50 
     | 
    
         
            +
                       if year <= (today.year-2000) && divider == '-'
         
     | 
| 
      
 51 
     | 
    
         
            +
                         century = 2000
         
     | 
| 
      
 52 
     | 
    
         
            +
                       elsif year <= (today.year-2000) && divider == '+'
         
     | 
| 
      
 53 
     | 
    
         
            +
                         century = 1900
         
     | 
| 
      
 54 
     | 
    
         
            +
                       elsif divider == '+'
         
     | 
| 
      
 55 
     | 
    
         
            +
                         century = 1800
         
     | 
| 
      
 56 
     | 
    
         
            +
                       else
         
     | 
| 
      
 57 
     | 
    
         
            +
                         century = 1900
         
     | 
| 
      
 58 
     | 
    
         
            +
                       end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                       begin
         
     | 
| 
      
 61 
     | 
    
         
            +
                         @date = Date.parse("#{century+year}-#{month}-#{day}")
         
     | 
| 
      
 62 
     | 
    
         
            +
                         @valid = true
         
     | 
| 
      
 63 
     | 
    
         
            +
                         @number = ("#{$1}#{$2}#{$3}#{divider}#{$5}#{checksum}")
         
     | 
| 
      
 64 
     | 
    
         
            +
                       rescue ArgumentError
         
     | 
| 
      
 65 
     | 
    
         
            +
                       end
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                private
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def self.luhn_algorithm(number)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  multiplications = []
         
     | 
| 
      
 74 
     | 
    
         
            +
                  number.split(//).each_with_index do |digit, i|
         
     | 
| 
      
 75 
     | 
    
         
            +
                    if i % 2 == 0
         
     | 
| 
      
 76 
     | 
    
         
            +
                      multiplications << digit.to_i*2
         
     | 
| 
      
 77 
     | 
    
         
            +
                    else
         
     | 
| 
      
 78 
     | 
    
         
            +
                      multiplications << digit.to_i
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  sum = 0
         
     | 
| 
      
 82 
     | 
    
         
            +
                  multiplications.each do |number|
         
     | 
| 
      
 83 
     | 
    
         
            +
                    number.to_s.each_byte do |character|
         
     | 
| 
      
 84 
     | 
    
         
            +
                      sum += character.chr.to_i
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                  if sum % 10 == 0
         
     | 
| 
      
 88 
     | 
    
         
            +
                    control_digit = 0
         
     | 
| 
      
 89 
     | 
    
         
            +
                  else
         
     | 
| 
      
 90 
     | 
    
         
            +
                    control_digit = (sum / 10 + 1) * 10 - sum
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                  control_digit
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
            end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            if $0 == __FILE__
         
     | 
| 
      
 99 
     | 
    
         
            +
              # Randomize every part
         
     | 
| 
      
 100 
     | 
    
         
            +
              puts Bukowskis::NationalIdentificationNumber::Swedish.generate
         
     | 
| 
      
 101 
     | 
    
         
            +
              # Use given date, randomize serial
         
     | 
| 
      
 102 
     | 
    
         
            +
              puts Bukowskis::NationalIdentificationNumber::Swedish.generate(Date.new(1975,1,1))
         
     | 
| 
      
 103 
     | 
    
         
            +
              # Use given date and serial, calculate checksum
         
     | 
| 
      
 104 
     | 
    
         
            +
              puts Bukowskis::NationalIdentificationNumber::Swedish.generate(Date.new(1975,1,1), 123)
         
     | 
| 
      
 105 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/resident.rb
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'national_identification_number'
         
     | 
| 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'resident'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            include NationalIdentificationNumber
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class TestBaseChild < NationalIdentificationNumber::Base
         
     | 
| 
      
 7 
     | 
    
         
            +
              def set_valid_to_nil
         
     | 
| 
      
 8 
     | 
    
         
            +
                @valid = nil
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              protected
         
     | 
| 
      
 11 
     | 
    
         
            +
              def validate
         
     | 
| 
      
 12 
     | 
    
         
            +
                @valid = 'validates_to_true'
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            describe Base, 'new' do
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              it "should instantiate correctly" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                TestBaseChild.new('12345').should be_an_instance_of TestBaseChild
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
             it "should repair on initialization" do
         
     | 
| 
      
 23 
     | 
    
         
            +
               TestBaseChild.new(' 12345abc ').to_s.should == '12345ABC'
         
     | 
| 
      
 24 
     | 
    
         
            +
             end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
             it "should validate on initialization" do
         
     | 
| 
      
 27 
     | 
    
         
            +
               lambda {  NationalIdentificationNumber::Base.new('12345') }.should raise_error(RuntimeError, 'You need to implement at least this method in subclasses.')
         
     | 
| 
      
 28 
     | 
    
         
            +
             end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            describe Base, 'valid?' do
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              it "should return true if it is valid" do
         
     | 
| 
      
 35 
     | 
    
         
            +
                TestBaseChild.new('12345abc').should be_valid
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              it "should return true if it is valid" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                base = TestBaseChild.new('12345abc')
         
     | 
| 
      
 40 
     | 
    
         
            +
                base.set_valid_to_nil
         
     | 
| 
      
 41 
     | 
    
         
            +
                base.should_not be_valid
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            describe Base, 'to_s' do
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              it "should return the number" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                TestBaseChild.new('12345ABC').to_s.should == '12345ABC'
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            describe Base, 'repair' do
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              it "should be a protected method" do
         
     | 
| 
      
 57 
     | 
    
         
            +
                lambda { TestBaseChild.new('12345').repair }.should raise_error NoMethodError
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              it "should strip whitespaces and capitalize everything" do
         
     | 
| 
      
 61 
     | 
    
         
            +
                TestBaseChild.new(' 123  45  abc %&/ ').to_s.should == '12345ABC%&/'
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              it "should make it a string" do
         
     | 
| 
      
 65 
     | 
    
         
            +
                TestBaseChild.new(:symbol).to_s.should == 'SYMBOL'
         
     | 
| 
      
 66 
     | 
    
         
            +
                TestBaseChild.new(1234).to_s.should == '1234'
         
     | 
| 
      
 67 
     | 
    
         
            +
                TestBaseChild.new(nil).to_s.should == ''
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              it "should strip newlines and tabs" do
         
     | 
| 
      
 71 
     | 
    
         
            +
                TestBaseChild.new("one\ntwo\tthree\n").to_s.should == 'ONETWOTHREE'
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,60 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'resident'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            include NationalIdentificationNumber
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            describe Finnish, 'valid?' do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              it "should recognize valid numbers" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                Finnish.new('311280-999J').should be_valid
         
     | 
| 
      
 10 
     | 
    
         
            +
                Finnish.new('131052-308T').should be_valid
         
     | 
| 
      
 11 
     | 
    
         
            +
                Finnish.new('290164-862u').should be_valid
         
     | 
| 
      
 12 
     | 
    
         
            +
                Finnish.new('270368A172X').should be_valid
         
     | 
| 
      
 13 
     | 
    
         
            +
                Finnish.new('310145A586a').should be_valid
         
     | 
| 
      
 14 
     | 
    
         
            +
                Finnish.new('080266+183P').should be_valid
         
     | 
| 
      
 15 
     | 
    
         
            +
                Finnish.new('290248+145c').should be_valid
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              it "should recognize invalid numbers" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                Finnish.new('671301A172V').should_not be_valid # valid checksum, invalid month
         
     | 
| 
      
 20 
     | 
    
         
            +
                Finnish.new('830231A172M').should_not be_valid # valid checksum, invalid day
         
     | 
| 
      
 21 
     | 
    
         
            +
                Finnish.new('311180-999J').should_not be_valid
         
     | 
| 
      
 22 
     | 
    
         
            +
                Finnish.new('131052-308S').should_not be_valid
         
     | 
| 
      
 23 
     | 
    
         
            +
                Finnish.new('290164X862U').should_not be_valid
         
     | 
| 
      
 24 
     | 
    
         
            +
                Finnish.new('670368A172X').should_not be_valid
         
     | 
| 
      
 25 
     | 
    
         
            +
                Finnish.new('310145--586A').should_not be_valid
         
     | 
| 
      
 26 
     | 
    
         
            +
                Finnish.new('asdf').should_not be_valid
         
     | 
| 
      
 27 
     | 
    
         
            +
                Finnish.new('1234567890').should_not be_valid
         
     | 
| 
      
 28 
     | 
    
         
            +
                Finnish.new('0000000000000').should_not be_valid
         
     | 
| 
      
 29 
     | 
    
         
            +
                Finnish.new('000000-0000').should_not be_valid
         
     | 
| 
      
 30 
     | 
    
         
            +
                Finnish.new('').should_not be_valid
         
     | 
| 
      
 31 
     | 
    
         
            +
                Finnish.new(1234567890).should_not be_valid
         
     | 
| 
      
 32 
     | 
    
         
            +
                Finnish.new(:really_bad_input_value).should_not be_valid
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            describe Finnish, 'to_s' do
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              it "should repair missing dashes, even if the number is invalid" do
         
     | 
| 
      
 40 
     | 
    
         
            +
                Finnish.new('311280999K').to_s.should == '311280-999K'
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              it "should return the number normalized if the number is valid" do
         
     | 
| 
      
 44 
     | 
    
         
            +
                Finnish.new('311280999J').to_s.should == '311280-999J'
         
     | 
| 
      
 45 
     | 
    
         
            +
                Finnish.new('270368A172X  ').to_s.should == '270368A172X'
         
     | 
| 
      
 46 
     | 
    
         
            +
                Finnish.new('xx270368A172X  ').to_s.should == '270368A172X'
         
     | 
| 
      
 47 
     | 
    
         
            +
                Finnish.new('xxx270368A172Xt  ').to_s.should == '270368A172X'
         
     | 
| 
      
 48 
     | 
    
         
            +
                Finnish.new('\t050126-1853').to_s.should == '050126-1853'
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              it "should always be injection safe, valid or not" do
         
     | 
| 
      
 52 
     | 
    
         
            +
                Finnish.new(%Q{270368"A172   \tX}).to_s.should == '270368A172X'
         
     | 
| 
      
 53 
     | 
    
         
            +
                Finnish.new(%Q{270368"A172\tX\n\n}).to_s.should == '270368A172X'
         
     | 
| 
      
 54 
     | 
    
         
            +
                Finnish.new(%Q{270368"A172X}).to_s.should == '270368A172X'
         
     | 
| 
      
 55 
     | 
    
         
            +
                Finnish.new(%Q{270368A<172X}).to_s.should == '270368A172X'
         
     | 
| 
      
 56 
     | 
    
         
            +
                Finnish.new(%Q{270368A'172X}).to_s.should == '270368A172X'
         
     | 
| 
      
 57 
     | 
    
         
            +
                Finnish.new(%Q{270368A>172X}).to_s.should == '270368A172X'
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,147 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'resident'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            include NationalIdentificationNumber
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            describe Swedish, '.generate' do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              it "should generate valid numbers" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                50.times { Swedish.new(Swedish.generate).should be_valid } # I know, it feels weird :)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            describe Swedish, 'valid?' do
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              it "should recognize valid numbers" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                Swedish.new("19180123-2669").should be_valid
         
     | 
| 
      
 18 
     | 
    
         
            +
                Swedish.new("00180123-2669").should be_valid
         
     | 
| 
      
 19 
     | 
    
         
            +
                Swedish.new("000180123-2669").should be_valid
         
     | 
| 
      
 20 
     | 
    
         
            +
                Swedish.new("050126-1853").should be_valid
         
     | 
| 
      
 21 
     | 
    
         
            +
                Swedish.new("0asdfghj501261853").should be_valid
         
     | 
| 
      
 22 
     | 
    
         
            +
                Swedish.new("050112-2451").should be_valid
         
     | 
| 
      
 23 
     | 
    
         
            +
                Swedish.new("450202-6950").should be_valid
         
     | 
| 
      
 24 
     | 
    
         
            +
                Swedish.new("19450202-6950").should be_valid
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              it "should recognize invalid numbers" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                Swedish.new("991301-1236").should_not be_valid # valid checksum, invalid month
         
     | 
| 
      
 29 
     | 
    
         
            +
                Swedish.new("830231-5554").should_not be_valid # valid checksum, invalid day
         
     | 
| 
      
 30 
     | 
    
         
            +
                Swedish.new("050112--2451").should_not be_valid
         
     | 
| 
      
 31 
     | 
    
         
            +
                Swedish.new("123456-1239").should_not be_valid
         
     | 
| 
      
 32 
     | 
    
         
            +
                Swedish.new("180123-2668").should_not be_valid
         
     | 
| 
      
 33 
     | 
    
         
            +
                Swedish.new("150D1261853").should_not be_valid
         
     | 
| 
      
 34 
     | 
    
         
            +
                Swedish.new("750112-2451").should_not be_valid
         
     | 
| 
      
 35 
     | 
    
         
            +
                Swedish.new("123").should_not be_valid
         
     | 
| 
      
 36 
     | 
    
         
            +
                Swedish.new("000000-0000").should_not be_valid
         
     | 
| 
      
 37 
     | 
    
         
            +
                Swedish.new("0000000000").should_not be_valid
         
     | 
| 
      
 38 
     | 
    
         
            +
                Swedish.new("asdfghj").should_not be_valid
         
     | 
| 
      
 39 
     | 
    
         
            +
                Swedish.new("").should_not be_valid
         
     | 
| 
      
 40 
     | 
    
         
            +
                Swedish.new(12345678).should_not be_valid
         
     | 
| 
      
 41 
     | 
    
         
            +
                Swedish.new(:really_bad_input).should_not be_valid
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            describe Swedish, 'to_s' do
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              it "should repair missing dashes and a superfluous century, even if the number is invalid" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                Swedish.new('1234561239').to_s.should == '123456-1239'
         
     | 
| 
      
 50 
     | 
    
         
            +
                Swedish.new('123456-1239').to_s.should == '123456-1239'
         
     | 
| 
      
 51 
     | 
    
         
            +
                Swedish.new("191234561239").to_s.should == '123456-1239'
         
     | 
| 
      
 52 
     | 
    
         
            +
                Swedish.new("19123456-1239").to_s.should == '123456-1239'
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              it "should return the number normalized if the number is valid" do
         
     | 
| 
      
 56 
     | 
    
         
            +
                Swedish.new('0501261853').to_s.should == '050126-1853'
         
     | 
| 
      
 57 
     | 
    
         
            +
                Swedish.new('050126-1853').to_s.should == '050126-1853'
         
     | 
| 
      
 58 
     | 
    
         
            +
                Swedish.new("190501261853").to_s.should == '050126-1853'
         
     | 
| 
      
 59 
     | 
    
         
            +
                Swedish.new("19050126-1853").to_s.should == '050126-1853'
         
     | 
| 
      
 60 
     | 
    
         
            +
                Swedish.new("19050126-185d3").to_s.should == '050126-1853'
         
     | 
| 
      
 61 
     | 
    
         
            +
                Swedish.new("19050126-185d3\n").to_s.should == '050126-1853'
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              it "should always be injection safe, valid or not" do
         
     | 
| 
      
 65 
     | 
    
         
            +
                Swedish.new("    180 123  -  2669 \n\n\t").to_s.should == '180123-2669'
         
     | 
| 
      
 66 
     | 
    
         
            +
                Swedish.new("    180 123  -  2669 \n").to_s.should == '180123-2669'
         
     | 
| 
      
 67 
     | 
    
         
            +
                Swedish.new(%Q{180123-"2669}).to_s.should == '180123-2669'
         
     | 
| 
      
 68 
     | 
    
         
            +
                Swedish.new(%Q{180123-<2669}).to_s.should == '180123-2669'
         
     | 
| 
      
 69 
     | 
    
         
            +
                Swedish.new(%Q{1801D23-'2669}).to_s.should == '180123-2669'
         
     | 
| 
      
 70 
     | 
    
         
            +
                Swedish.new(%Q{180s123->2669}).to_s.should == '180123-2669'
         
     | 
| 
      
 71 
     | 
    
         
            +
                Swedish.new(%Q{19180s123->2669}).to_s.should == '180123-2669'
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            describe Swedish, 'date' do # For testing only, no public API
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              it "should recognize babies born today" do
         
     | 
| 
      
 79 
     | 
    
         
            +
                today = Date.today.strftime("%y%m%d")
         
     | 
| 
      
 80 
     | 
    
         
            +
                born_today = Swedish.new("#{today}-000#{Swedish.luhn_algorithm("#{today}000")}")
         
     | 
| 
      
 81 
     | 
    
         
            +
                born_today.should be_valid
         
     | 
| 
      
 82 
     | 
    
         
            +
                born_today.date.should == Date.today
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
              it "should recognize babies born yesterday" do
         
     | 
| 
      
 86 
     | 
    
         
            +
                today = (Date.today - 1).strftime("%y%m%d")
         
     | 
| 
      
 87 
     | 
    
         
            +
                born_yesterday = Swedish.new("#{today}-000#{Swedish.luhn_algorithm("#{today}000")}")
         
     | 
| 
      
 88 
     | 
    
         
            +
                born_yesterday.should be_valid
         
     | 
| 
      
 89 
     | 
    
         
            +
                born_yesterday.date.should == (Date.today - 1)
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              it "should recognize people born in the year 2000" do
         
     | 
| 
      
 93 
     | 
    
         
            +
                beginning_of_year = Swedish.new("000101-0008")
         
     | 
| 
      
 94 
     | 
    
         
            +
                beginning_of_year.should be_valid
         
     | 
| 
      
 95 
     | 
    
         
            +
                beginning_of_year.date.should == Date.new(2000, 1, 1)
         
     | 
| 
      
 96 
     | 
    
         
            +
                leap_year = Swedish.new("000229-0005") # 2000 was a leap year, 1900 not
         
     | 
| 
      
 97 
     | 
    
         
            +
                leap_year.should be_valid
         
     | 
| 
      
 98 
     | 
    
         
            +
                leap_year.date.should == Date.new(2000, 2, 29)
         
     | 
| 
      
 99 
     | 
    
         
            +
                end_of_year = Swedish.new("001231-0009")
         
     | 
| 
      
 100 
     | 
    
         
            +
                end_of_year.should be_valid
         
     | 
| 
      
 101 
     | 
    
         
            +
                end_of_year.date.should == Date.new(2000, 12, 31)
         
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              it "should recognize people born in the year 1999" do
         
     | 
| 
      
 105 
     | 
    
         
            +
                beginning_of_year = Swedish.new("990101-0000")
         
     | 
| 
      
 106 
     | 
    
         
            +
                beginning_of_year.should be_valid
         
     | 
| 
      
 107 
     | 
    
         
            +
                beginning_of_year.date.should == Date.new(1999, 1, 1)
         
     | 
| 
      
 108 
     | 
    
         
            +
                end_of_year = Swedish.new("991231-0001")
         
     | 
| 
      
 109 
     | 
    
         
            +
                end_of_year.should be_valid
         
     | 
| 
      
 110 
     | 
    
         
            +
                end_of_year.date.should == Date.new(1999, 12, 31)
         
     | 
| 
      
 111 
     | 
    
         
            +
              end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
              it "should recognize all other people less than 100 years old" do
         
     | 
| 
      
 114 
     | 
    
         
            +
                will_turn_99_this_year = Date.new(Date.today.year - 99, 12, 31).strftime("%y%m%d")
         
     | 
| 
      
 115 
     | 
    
         
            +
                soon_99 = Swedish.new("#{will_turn_99_this_year}-000#{Swedish.luhn_algorithm("#{will_turn_99_this_year}000")}")
         
     | 
| 
      
 116 
     | 
    
         
            +
                soon_99.should be_valid
         
     | 
| 
      
 117 
     | 
    
         
            +
                soon_99.date.should == Date.new(Date.today.year - 99, 12, 31)
         
     | 
| 
      
 118 
     | 
    
         
            +
                turned_99_this_year = Date.new(Date.today.year - 99, 1, 1).strftime("%y%m%d")
         
     | 
| 
      
 119 
     | 
    
         
            +
                already_99 = Swedish.new("#{turned_99_this_year}-000#{Swedish.luhn_algorithm("#{turned_99_this_year}000")}")
         
     | 
| 
      
 120 
     | 
    
         
            +
                already_99.should be_valid
         
     | 
| 
      
 121 
     | 
    
         
            +
                already_99.date.should == Date.new(Date.today.year - 99, 1, 1)
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              it "should recognize people that turn 100 years in this year" do
         
     | 
| 
      
 125 
     | 
    
         
            +
                will_turn_100_this_year = Date.new(Date.today.year - 100, 12, 31).strftime("%y%m%d")
         
     | 
| 
      
 126 
     | 
    
         
            +
                soon_100 = Swedish.new("#{will_turn_100_this_year}+000#{Swedish.luhn_algorithm("#{will_turn_100_this_year}000")}")
         
     | 
| 
      
 127 
     | 
    
         
            +
                soon_100.should be_valid
         
     | 
| 
      
 128 
     | 
    
         
            +
                soon_100.date.should == Date.new(Date.today.year - 100, 12, 31)
         
     | 
| 
      
 129 
     | 
    
         
            +
                turned_100_this_year = Date.new(Date.today.year - 100, 1, 1).strftime("%y%m%d")
         
     | 
| 
      
 130 
     | 
    
         
            +
                already_100 = Swedish.new("#{turned_100_this_year}+000#{Swedish.luhn_algorithm("#{turned_100_this_year}000")}")
         
     | 
| 
      
 131 
     | 
    
         
            +
                already_100.should be_valid
         
     | 
| 
      
 132 
     | 
    
         
            +
                already_100.date.should == Date.new(Date.today.year - 100, 1, 1)
         
     | 
| 
      
 133 
     | 
    
         
            +
              end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
              it "should recognize people older than 100 years born after 1900" do
         
     | 
| 
      
 136 
     | 
    
         
            +
                normal = Swedish.new("010101+0007")
         
     | 
| 
      
 137 
     | 
    
         
            +
                normal.should be_valid
         
     | 
| 
      
 138 
     | 
    
         
            +
                normal.date.should == Date.new(1901, 1, 1)
         
     | 
| 
      
 139 
     | 
    
         
            +
              end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              it "should recognize people older than 100 years born before 1900" do
         
     | 
| 
      
 142 
     | 
    
         
            +
                normal = Swedish.new("991231+0001")
         
     | 
| 
      
 143 
     | 
    
         
            +
                normal.should be_valid
         
     | 
| 
      
 144 
     | 
    
         
            +
                normal.date.should == Date.new(1899, 12, 31)
         
     | 
| 
      
 145 
     | 
    
         
            +
              end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,98 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: resident
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 13
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 9
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.0.9
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Bukowskis
         
     | 
| 
      
 14 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 16 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2011-12-19 00:00:00 +01:00
         
     | 
| 
      
 19 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 21 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 22 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 23 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 24 
     | 
    
         
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 25 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 26 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 27 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 28 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 29 
     | 
    
         
            +
                    hash: 3
         
     | 
| 
      
 30 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 31 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 32 
     | 
    
         
            +
                    version: "0"
         
     | 
| 
      
 33 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 34 
     | 
    
         
            +
              version_requirements: *id001
         
     | 
| 
      
 35 
     | 
    
         
            +
            description: 
         
     | 
| 
      
 36 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 37 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 42 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 43 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 44 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/national_identification_number/base.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/national_identification_number/finnish.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - lib/national_identification_number/swedish.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - lib/national_identification_number.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - lib/resident.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 51 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 52 
     | 
    
         
            +
            - .gemtest
         
     | 
| 
      
 53 
     | 
    
         
            +
            - spec/national_identification_number/base_spec.rb
         
     | 
| 
      
 54 
     | 
    
         
            +
            - spec/national_identification_number/finnish_spec.rb
         
     | 
| 
      
 55 
     | 
    
         
            +
            - spec/national_identification_number/swedish_spec.rb
         
     | 
| 
      
 56 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 57 
     | 
    
         
            +
            homepage: http://github.com/bukowskis/national_identification_number/
         
     | 
| 
      
 58 
     | 
    
         
            +
            licenses: 
         
     | 
| 
      
 59 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 60 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 61 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 62 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 63 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 64 
     | 
    
         
            +
            - --charset=UTF-8
         
     | 
| 
      
 65 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 66 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 67 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 68 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 69 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 70 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 71 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 72 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 73 
     | 
    
         
            +
                  hash: 57
         
     | 
| 
      
 74 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 75 
     | 
    
         
            +
                  - 1
         
     | 
| 
      
 76 
     | 
    
         
            +
                  - 8
         
     | 
| 
      
 77 
     | 
    
         
            +
                  - 7
         
     | 
| 
      
 78 
     | 
    
         
            +
                  version: 1.8.7
         
     | 
| 
      
 79 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 80 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 81 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 82 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 83 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 84 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 85 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 86 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 87 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 88 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 91 
     | 
    
         
            +
            rubygems_version: 1.5.3
         
     | 
| 
      
 92 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 93 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 94 
     | 
    
         
            +
            summary: Validate National Identification Numbers.
         
     | 
| 
      
 95 
     | 
    
         
            +
            test_files: 
         
     | 
| 
      
 96 
     | 
    
         
            +
            - spec/national_identification_number/base_spec.rb
         
     | 
| 
      
 97 
     | 
    
         
            +
            - spec/national_identification_number/finnish_spec.rb
         
     | 
| 
      
 98 
     | 
    
         
            +
            - spec/national_identification_number/swedish_spec.rb
         
     |