Skip to content

Instantly share code, notes, and snippets.

@caioertai
Created January 28, 2019 22:13
Show Gist options
  • Save caioertai/64dde20a45e90082fdaed19e2845d835 to your computer and use it in GitHub Desktop.
Save caioertai/64dde20a45e90082fdaed19e2845d835 to your computer and use it in GitHub Desktop.
'01': Ain
'02': Aisne
'03': Allier
'04': Alpes-de-Haute-Provence
'05': Hautes-Alpes
'06': Alpes-Maritimes
'07': Ardèche
'08': Ardennes
'09': Ariège
'10': Aube
'11': Aude
'12': Aveyron
'13': Bouches-du-Rhône
'14': Calvados
'15': Cantal
'16': Charente
'17': Charente-Maritime
'18': Cher
'19': Corrèze
'2A': Corse-du-Sud
'2B': Haute-Corse
'21': Côte-d'Or
'22': Côtes-d'Armor
'23': Creuse
'24': Dordogne
'25': Doubs
'26': Drôme
'27': Eure
'28': Eure-et-Loir
'29': Finistère
'30': Gard
'31': Haute-Garonne
'32': Gers
'33': Gironde
'34': Hérault
'35': Ille-et-Vilaine
'36': Indre
'37': Indre-et-Loire
'38': Isère
'39': Jura
'40': Landes
'41': Loir-et-Cher
'42': Loire
'43': Haute-Loire
'44': Loire-Atlantique
'45': Loiret
'46': Lot
'47': Lot-et-Garonne
'48': Lozère
'49': Maine-et-Loire
'50': Manche
'51': Marne
'52': Haute-Marne
'53': Mayenne
'54': Meurthe-et-Moselle
'55': Meuse
'56': Morbihan
'57': Moselle
'58': Nièvre
'59': Nord
'60': Oise
'61': Orne
'62': Pas-de-Calais
'63': Puy-de-Dôme
'64': Pyrénées-Atlantiques
'65': Hautes-Pyrénées
'66': Pyrénées-Orientales
'67': Bas-Rhin
'68': Haut-Rhin
'69': Rhône
'70': Haute-Saône
'71': Saône-et-Loire
'72': Sarthe
'73': Savoie
'74': Haute-Savoie
'75': Paris
'76': Seine-Maritime
'77': Seine-et-Marne
'78': Yvelines
'79': Deux-Sèvres
'80': Somme
'81': Tarn
'82': Tarn-et-Garonne
'83': Var
'84': Vaucluse
'85': Vendée
'86': Vienne
'87': Haute-Vienne
'88': Vosges
'89': Yonne
'90': Territoire de Belfort
'91': Essonne
'92': Hauts-de-Seine
'93': Seine-Saint-Denis
'94': Val-de-Marne
'95': Val-d'Oise
# Requires the YAML library in order to read the .yml file
require 'yaml'
def valid_ssn_key?(ssn_number)
no_key_ssn = ssn_number.gsub(/\s/, '')[0..-3].to_i
key = ssn_number[-2..-1].to_i
(97 - no_key_ssn) % 97 != key
end
def french_ssn_info(ssn_number)
# Regex built on Rubular
regex = /^(?<gender>[12])\s?(?<year>\d{2})\s?(?<month>0[1-9]|1[0-2])\s?(?<department>\d{2})\s?\d{3}\s?\d{3}\s?\d{2}/
ssn_data = ssn_number.match(regex)
# Returns invalid if it doesn't match the regex OR (||) the ssn key
# doesn't match the modulo condition
# Abstracted the key validation to method #valid_ssn_key? for clarity
return 'The number is invalid' if ssn_data.nil? || valid_ssn_key?(ssn_number)
# Gets the departments from the *.yml, and checks it against the
# number of the ssn's department
yaml_string = open('french_departments.yml').read
departments = YAML.safe_load(yaml_string)
department = departments[ssn_data[:department]]
# Assigns gender as man for 1 or woman for 2
gender = ssn_data[:gender] == '1' ? 'man' : 'woman'
# Uses the Ruby Date::MONTHNAMES library to assign the
# month name by its index
month = Date::MONTHNAMES[ssn_data[:month].to_i]
# Assigns to year 19 + last 2 digits of the year
year = "19#{ssn_data[:year]}"
# Returns the built info string
"a #{gender}, born in #{month}, #{year} in #{department}."
end
require_relative 'french_ssn_info'
describe '#french_ssn_info' do
it 'returns invalid for an invalid SSN' do
actual = french_ssn_info("123")
expected = "The number is invalid"
expect(actual).to eq(expected)
end
it 'return the correct citizen info if given a valid ssn' do
actual = french_ssn_info("1 84 12 76 451 089 46")
expected = "a man, born in December, 1984 in Seine-Maritime."
expect(actual).to eq(expected)
end
it 'returns invalid for an invalid KEY' do
actual = french_ssn_info("1 84 12 76 451 089 99")
expected = "The number is invalid"
expect(actual).to eq(expected)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment