mirror of
https://github.com/fzaninotto/Faker.git
synced 2025-03-24 01:09:50 +01:00
Company Provider for french locale now returns valid SIREN/SIRET codes which verify the Luhn algorithm.
Added PHPUnit constraint to assert that a string is a valid code.
This commit is contained in:
parent
46a5171fe2
commit
91e87aa0e0
@ -51,11 +51,6 @@ class Company extends \Faker\Provider\Company
|
||||
*/
|
||||
protected static $companySuffix = array('SA', 'S.A.', 'SARL', 'S.A.R.L.', 'S.A.S.', 'et Fils');
|
||||
|
||||
/**
|
||||
* @var string Siren format.
|
||||
*/
|
||||
protected static $sirenFormat = "### ### ###";
|
||||
|
||||
/**
|
||||
* Returns a random catch phrase noun.
|
||||
*
|
||||
@ -106,34 +101,95 @@ class Company extends \Faker\Provider\Company
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a siret number (14 digits).
|
||||
* It is in fact the result of the concatenation of a siren number (9 digits),
|
||||
* a sequential number (4 digits) and a control number (1 digit) concatenation.
|
||||
* If $maxSequentialDigits is invalid, it is set to 2.
|
||||
*
|
||||
* Generates a siret number (14 digits) that passes the Luhn check.
|
||||
* Use $maxSequentialDigits to make sure the digits at position 2 to 5 are not zeros.
|
||||
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
|
||||
* @param int $maxSequentialDigits The maximum number of digits for the sequential number (> 0 && <= 4).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function siret($maxSequentialDigits = 2)
|
||||
{
|
||||
|
||||
if ($maxSequentialDigits > 4 || $maxSequentialDigits <= 0) {
|
||||
$maxSequentialDigits = 2;
|
||||
}
|
||||
|
||||
$sequentialNumber = str_pad(static::randomNumber($maxSequentialDigits), 4, '0', STR_PAD_LEFT);
|
||||
|
||||
return static::numerify(static::siren() . ' ' . $sequentialNumber . '#');
|
||||
|
||||
$controlDigit = mt_rand(0, 9);
|
||||
$siret = $sum = $controlDigit;
|
||||
|
||||
$position = 2;
|
||||
for ($i = 0; $i < $maxSequentialDigits; $i++) {
|
||||
|
||||
$sequentialDigit = mt_rand(0, 9);
|
||||
$isEven = $position++ % 2 === 0;
|
||||
|
||||
$tmp = $isEven ? $sequentialDigit * 2 : $sequentialDigit;
|
||||
if ($tmp >= 10) $tmp -= 9;
|
||||
$sum += $tmp;
|
||||
|
||||
$siret = $sequentialDigit . $siret;
|
||||
|
||||
}
|
||||
|
||||
$siret = str_pad($siret, 5, '0', STR_PAD_LEFT);
|
||||
|
||||
$position = 6;
|
||||
for ($i = 0; $i < 7; $i++) {
|
||||
|
||||
$digit = mt_rand(0, 9);
|
||||
$isEven = $position++ % 2 === 0;
|
||||
|
||||
$tmp = $isEven ? $digit * 2 : $digit;
|
||||
if ($tmp >= 10) $tmp -= 9;
|
||||
$sum += $tmp;
|
||||
|
||||
$siret = $digit . $siret;
|
||||
|
||||
}
|
||||
|
||||
$mod = $sum % 10;
|
||||
if ($mod === 0) {
|
||||
$siret = '00' . $siret;
|
||||
} else {
|
||||
// Use the odd position to avoid multiplying by two
|
||||
$siret = '0' . (10 - $mod) . $siret;
|
||||
}
|
||||
|
||||
return preg_replace("/([0-9]{3})([0-9]{3})([0-9]{3})([0-9]{5})/", "$1 $2 $3 $4", $siret);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a siren number (9 digits).
|
||||
*
|
||||
* Generates a siren number (9 digits) that passes the Luhn check.
|
||||
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
|
||||
* @return string
|
||||
*/
|
||||
public static function siren()
|
||||
{
|
||||
return static::numerify(static::$sirenFormat);
|
||||
$siren = '';
|
||||
$sum = 0;
|
||||
for ($i = 9; $i > 1; $i--) {
|
||||
|
||||
$digit = mt_rand(0, 9);
|
||||
$isEven = $i % 2 === 0;
|
||||
|
||||
$tmp = $isEven ? $digit * 2 : $digit;
|
||||
if ($tmp >= 10) $tmp -= 9;
|
||||
$sum += $tmp;
|
||||
|
||||
$siren = $digit . $siren;
|
||||
|
||||
}
|
||||
|
||||
$mod = $sum % 10;
|
||||
if ($mod === 0) {
|
||||
$siren = '0' . $siren;
|
||||
} else {
|
||||
$siren = (10 - $mod) . $siren;
|
||||
}
|
||||
|
||||
return preg_replace("/([0-9]{3})([0-9]{3})([0-9]{3})/", "$1 $2 $3", $siren);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
16
test/Faker/PHPUnit/Framework/Constraint/IsValidSiren.php
Normal file
16
test/Faker/PHPUnit/Framework/Constraint/IsValidSiren.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Faker\PHPUnit\Framework\Constraint;
|
||||
|
||||
class IsValidSiren extends IsValidSirenSiret
|
||||
{
|
||||
|
||||
protected function getLength() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
protected function getName() {
|
||||
return 'SIREN';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Faker\PHPUnit\Framework\Constraint;
|
||||
|
||||
abstract class IsValidSirenSiret extends \PHPUnit_Framework_Constraint {
|
||||
|
||||
protected function matches($other)
|
||||
{
|
||||
|
||||
$code = str_replace(' ', '', $other);
|
||||
|
||||
if (strlen($code) != $this->getLength())
|
||||
return false;
|
||||
|
||||
$sum = 0;
|
||||
// IMPORTANT : from right to left
|
||||
$position = 1;
|
||||
for ($i = strlen($code) - 1; $i >= 0; $i--) {
|
||||
$isEven = (($position++ % 2) === 0);
|
||||
$tmp = $isEven ? $code[$i] * 2 : $code[$i];
|
||||
if ($tmp >= 10) $tmp -= 9;
|
||||
$sum += $tmp;
|
||||
}
|
||||
return ($sum % 10 === 0);
|
||||
|
||||
}
|
||||
|
||||
public function toString() {
|
||||
return sprintf('is a valid %s number', $this->getName());
|
||||
}
|
||||
|
||||
abstract protected function getLength();
|
||||
|
||||
abstract protected function getName();
|
||||
|
||||
}
|
16
test/Faker/PHPUnit/Framework/Constraint/IsValidSiret.php
Normal file
16
test/Faker/PHPUnit/Framework/Constraint/IsValidSiret.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Faker\PHPUnit\Framework\Constraint;
|
||||
|
||||
class IsValidSiret extends IsValidSirenSiret
|
||||
{
|
||||
|
||||
protected function getLength() {
|
||||
return 14;
|
||||
}
|
||||
|
||||
protected function getName() {
|
||||
return 'SIRET';
|
||||
}
|
||||
|
||||
}
|
@ -3,20 +3,37 @@
|
||||
namespace Faker\Test\Provider\fr_FR;
|
||||
|
||||
use Faker\Provider\fr_FR\Company;
|
||||
use Faker\PHPUnit\Framework\Constraint as Constraint;
|
||||
|
||||
require_once __DIR__ . '/../../PHPUnit/Framework/Constraint/IsValidSirenSiret.php';
|
||||
require_once __DIR__ . '/../../PHPUnit/Framework/Constraint/IsValidSiret.php';
|
||||
require_once __DIR__ . '/../../PHPUnit/Framework/Constraint/IsValidSiren.php';
|
||||
|
||||
class CompanyTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private static function isValidSiret()
|
||||
{
|
||||
return new Constraint\IsValidSiret();
|
||||
}
|
||||
|
||||
private static function isValidSiren()
|
||||
{
|
||||
return new Constraint\IsValidSiren();
|
||||
}
|
||||
|
||||
public function testParagraphWithNegativeNbDigitsReturnsAWellFormattedSiret()
|
||||
{
|
||||
$siret = Company::siret(-1);
|
||||
|
||||
|
||||
$this->assertThat($siret, self :: isValidSiret());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3} 00[\d]{3}/", $siret);
|
||||
}
|
||||
|
||||
public function testParagraphWithInvalidNbDigitsReturnsAWellFormattedSiret()
|
||||
{
|
||||
$siret = Company::siret(6);
|
||||
|
||||
|
||||
$this->assertThat($siret, self :: isValidSiret());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3} 00[\d]{3}/", $siret);
|
||||
}
|
||||
|
||||
@ -26,12 +43,24 @@ class CompanyTest extends \PHPUnit_Framework_TestCase
|
||||
$siret2 = Company::siret(2);
|
||||
$siret3 = Company::siret(3);
|
||||
$siret4 = Company::siret(4);
|
||||
|
||||
|
||||
$this->assertThat($siret1, self :: isValidSiret());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3} 000[\d]{2}/", $siret1);
|
||||
$this->assertThat($siret2, self :: isValidSiret());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3} 00[\d]{3}/", $siret2);
|
||||
$this->assertThat($siret3, self :: isValidSiret());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3} 0[\d]{4}/", $siret3);
|
||||
$this->assertThat($siret4, self :: isValidSiret());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3} [\d]{5}/", $siret4);
|
||||
}
|
||||
|
||||
public function testSirenReturnsAValidAndWellFormattedSiren()
|
||||
{
|
||||
$siret = Company::siren();
|
||||
|
||||
$this->assertThat($siret, self :: isValidSiren());
|
||||
$this->assertRegExp("/[\d]{3} [\d]{3} [\d]{3}/", $siret);
|
||||
}
|
||||
|
||||
public function testCatchPhraseValidationReturnsFalse()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user