Skip to content

Commit 6360a11

Browse files
committed
Merge pull request #13 from seegno/support/replace-iso-3166-1-data-set
Replace ISO 3166-1 country assert source
2 parents 03a6c8e + 405f54b commit 6360a11

File tree

9 files changed

+205
-27
lines changed

9 files changed

+205
-27
lines changed

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ A set of extra asserts for [validator.js](https://github.com/guillaumepotier/val
1111

1212
Install the package via `npm`:
1313

14-
```
14+
```sh
1515
$ npm install --save validator.js-asserts
1616
```
1717

@@ -25,6 +25,7 @@ The following set of extra asserts are provided by this package:
2525
* BigNumberLessThan
2626
* BigNumberLessThanOrEqualTo
2727
* Boolean
28+
* Country
2829
* Date
2930
* DateDiffGreaterThan
3031
* DateDiffLessThan
@@ -99,6 +100,11 @@ Tests if the difference between two dates is less than a given threshold.
99100
* `fromDate` - the date where the diff is measured with. If omitted, defaults to `now`.
100101
* `unit` - the unit of the difference measurement (`years`, `months`, `weeks`, `days`, `hours`, `minutes` and `seconds`).
101102

103+
### Country
104+
105+
Tests if the value is a valid country by alpha-3 code, alpha-2 code, common name, official name or alternative spelling names.
106+
The difference from the `Iso3166Country` assert is that it is less rigid in its definitions since it is based on a community-effort rather than a standards body where rules are very strict.
107+
102108
### Email
103109

104110
Tests if the value is a valid email.
@@ -125,7 +131,8 @@ Tests if the value is a valid ip (v4 or v6).
125131

126132
### Iso3166Country
127133

128-
Tests if the value is a valid ISO-3166 country by alpha-3 code, alpha-2 code or name.
134+
Tests if the value is a valid ISO-3166 country by alpha-3 code, alpha-2 code, short name or uppercase name.
135+
All officially-assigned, transitionally-assigned and user-assigned codes are considered valid.
129136

130137
### Json
131138

@@ -184,7 +191,7 @@ if (true !== violation) {
184191

185192
## Tests
186193

187-
```
194+
```sh
188195
$ npm test
189196
```
190197

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
* Module dependencies.
44
*/
55

6+
var _ = require('lodash');
67
var Assert = require('validator.js').Assert;
78
var asserts = require('require-dir')('./lib/asserts');
8-
var pascal = require('to-pascal-case');
99

1010
/**
1111
* Register asserts.
@@ -14,7 +14,7 @@ var pascal = require('to-pascal-case');
1414
for (var assert in asserts) {
1515
var func = asserts[assert];
1616

17-
assert = pascal(assert).replace('Assert', '');
17+
assert = _.flowRight(_.capitalize, _.camelCase)(assert).replace('Assert', '');
1818

1919
Assert.prototype[assert] = func;
2020
}

lib/asserts/country-assert.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
/**
3+
* Module dependencies.
4+
*/
5+
6+
var _ = require('lodash');
7+
var Validator = require('validator.js').Validator;
8+
var Violation = require('validator.js').Violation;
9+
var countries = require('world-countries').concat(
10+
require('world-countries/data/bes.divisions'),
11+
require('world-countries/data/shn.divisions')
12+
);
13+
14+
/**
15+
* Export `CountryAssert`.
16+
*/
17+
18+
module.exports = function() {
19+
20+
/**
21+
* Class name.
22+
*/
23+
24+
this.__class__ = 'Country';
25+
26+
/**
27+
* Validation algorithm.
28+
*/
29+
30+
this.validate = function(value) {
31+
if ('string' !== typeof value) {
32+
/* jshint camelcase: false */
33+
throw new Violation(this, value, { value: Validator.errorCode.must_be_a_string });
34+
/* jshint camelcase: true */
35+
}
36+
37+
// Test by `alpha-3` code.
38+
var country = _.find(countries, { cca3: value });
39+
40+
// Test by `alpha-2` code.
41+
if (!country) {
42+
country = _.find(countries, { cca2: value });
43+
}
44+
45+
var name = value.toLocaleUpperCase();
46+
47+
// Test by `name`.
48+
if (!country) {
49+
country = _.find(countries, function(country) {
50+
return country.name.common.toLocaleUpperCase() === name
51+
|| country.name.official.toLocaleUpperCase() === name
52+
|| _.find(country.altSpellings, function(altSpelling) {
53+
return altSpelling.toLocaleUpperCase() === name;
54+
});
55+
});
56+
}
57+
58+
if (!country) {
59+
throw new Violation(this, value);
60+
}
61+
62+
return true;
63+
};
64+
65+
return this;
66+
};

lib/asserts/iso-3166-country-assert.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
var _ = require('lodash');
77
var Validator = require('validator.js').Validator;
88
var Violation = require('validator.js').Violation;
9-
var countries = require('iso-3166-1-data');
9+
var countries = require('isoc');
1010

1111
/**
1212
* Export `Iso3166CountryAssert`.
@@ -20,6 +20,12 @@ module.exports = function() {
2020

2121
this.__class__ = 'Iso3166Country';
2222

23+
/**
24+
* Data source.
25+
*/
26+
27+
this.countries = countries;
28+
2329
/**
2430
* Validation algorithm.
2531
*/
@@ -31,22 +37,25 @@ module.exports = function() {
3137
/* jshint camelcase: true */
3238
}
3339

34-
// Test by alpha-3 code.
35-
var country = _.find(countries, { alpha3: value });
40+
// Test by `alpha-3` code.
41+
var country = _.find(this.countries, { alpha3: value });
3642

37-
// Test by alpha-2 code if a country was not found.
43+
// Test by `alpha-2` code.
3844
if (!country) {
39-
country = _.find(countries, { alpha2: value });
45+
country = _.find(this.countries, { alpha2: value });
4046
}
4147

42-
// Test by full country name if a country was not found.
48+
// Test by `name`.
49+
var name = value.toLocaleUpperCase();
50+
4351
if (!country) {
4452
country = _.find(countries, function(country) {
45-
return country.name.toLowerCase() === value.toLowerCase();
53+
return country.name.short.toLocaleUpperCase() === name
54+
|| country.name.uppercase.toLocaleUpperCase() === name
4655
});
4756
}
4857

49-
// Country is invalid or not in a ISO 3166-1 compatible format.
58+
// Country is invalid or not in a `ISO 3166-1` compatible format.
5059
if (!country) {
5160
throw new Violation(this, value);
5261
}

package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,20 @@
4444
"node": ">= 0.10"
4545
},
4646
"dependencies": {
47-
"bignumber.js": "^2.0.0",
48-
"iso-3166-1-data": "0.0.2",
49-
"lodash": "^2.4.1",
50-
"moment": "^2.8.4",
51-
"provinces": "^0.2.0",
52-
"require-dir": "^0.1.0",
53-
"to-pascal-case": "0.0.2",
54-
"validator": "^3.22.1",
55-
"validator.js": "^1.0.1"
47+
"bignumber.js": "^2.0.7",
48+
"isoc": "0.0.1",
49+
"lodash": "^3.9.1",
50+
"moment": "^2.10.3",
51+
"provinces": "^1.7.1",
52+
"require-dir": "^0.3.0",
53+
"validator": "^3.40.0",
54+
"validator.js": "^1.1.1",
55+
"world-countries": "^1.7.3"
5656
},
5757
"devDependencies": {
58-
"github-changes": "0.0.16",
59-
"mocha": "^2.0.1",
60-
"should": "^4.2.1",
61-
"sinon": "^1.12.1"
58+
"github-changes": "^1.0.0",
59+
"mocha": "^2.2.5",
60+
"should": "^6.0.3",
61+
"sinon": "^1.14.1"
6262
}
6363
}

test/asserts/boolean-assert_test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ describe('BooleanAssert', function() {
2626
choices.forEach(function(choice) {
2727
try {
2828
new Assert().Boolean().validate(choice);
29+
30+
should.fail();
2931
} catch (e) {
3032
e.should.be.instanceOf(Violation);
3133
/* jshint camelcase: false */
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
/**
3+
* Module dependencies.
4+
*/
5+
6+
var Assert = require('validator.js').Assert;
7+
var Validator = require('validator.js').Validator;
8+
var Violation = require('validator.js').Violation;
9+
var assert = require('../../lib/asserts/country-assert');
10+
var should = require('should');
11+
12+
/**
13+
* Test `CountryAssert`.
14+
*/
15+
16+
describe('CountryAssert', function() {
17+
before(function() {
18+
Assert.prototype.Country = assert;
19+
});
20+
21+
it('should throw an error if the input value is not a string', function() {
22+
var choices = [[], {}, 123];
23+
24+
choices.forEach(function(choice) {
25+
try {
26+
new Assert().Country().validate(choice);
27+
28+
should.fail();
29+
} catch (e) {
30+
e.should.be.instanceOf(Violation);
31+
/* jshint camelcase: false */
32+
e.violation.value.should.equal(Validator.errorCode.must_be_a_string);
33+
/* jshint camelcase: true */
34+
}
35+
});
36+
});
37+
38+
it('should throw an error if country is invalid', function() {
39+
try {
40+
new Assert().Country().validate('FOO');
41+
42+
should.fail();
43+
} catch (e) {
44+
e.should.be.instanceOf(Violation);
45+
e.value.should.equal('FOO');
46+
}
47+
});
48+
49+
it('should expose `assert` equal to `Country`', function() {
50+
try {
51+
new Assert().Country().validate([]);
52+
53+
should.fail();
54+
} catch(e) {
55+
e.show().assert.should.equal('Country');
56+
}
57+
});
58+
59+
it('should accept an `alpha-3` code', function() {
60+
new Assert().Country().validate('PRT');
61+
});
62+
63+
it('should accept an `alpha-3` code belonging to a division', function() {
64+
new Assert().Country().validate('SHN');
65+
});
66+
67+
it('should accept an `alpha-2` code', function() {
68+
new Assert().Country().validate('PT');
69+
});
70+
71+
it('should accept an `alpha-2` code belonging to a division', function() {
72+
new Assert().Country().validate('BQ');
73+
});
74+
75+
it('should accept a country `official` name', function() {
76+
new Assert().Country().validate('Portuguese Republic');
77+
});
78+
79+
it('should accept a country `common` name', function() {
80+
new Assert().Country().validate('Portugal');
81+
});
82+
83+
it('should accept a country `altSpelling` name', function() {
84+
new Assert().Country().validate('República Portuguesa');
85+
});
86+
});

test/asserts/ip-assert_test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ describe('IpAssert', function() {
2424
choices.forEach(function(choice) {
2525
try {
2626
new Assert().Ip().validate(choice);
27+
28+
should.fail();
2729
} catch (e) {
2830
e.should.be.instanceOf(Violation);
2931
/* jshint camelcase: false */

test/asserts/iso-3166-country-assert_test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ describe('Iso3166CountryAssert', function() {
2424
choices.forEach(function(choice) {
2525
try {
2626
new Assert().Iso3166Country().validate(choice);
27+
28+
should.fail();
2729
} catch (e) {
2830
e.should.be.instanceOf(Violation);
2931
/* jshint camelcase: false */
@@ -62,7 +64,11 @@ describe('Iso3166CountryAssert', function() {
6264
new Assert().Iso3166Country().validate('PT');
6365
});
6466

65-
it('should accept an ISO 3166-1 country name', function() {
67+
it('should accept an ISO 3166-1 country name in short format', function() {
6668
new Assert().Iso3166Country().validate('Portugal');
6769
});
70+
71+
it('should accept an ISO 3166-1 country name in uppercase format', function() {
72+
new Assert().Iso3166Country().validate('PORTUGAL');
73+
});
6874
});

0 commit comments

Comments
 (0)