Skip to content

Commit 73728b8

Browse files
committed
Initial commit
0 parents  commit 73728b8

6 files changed

Lines changed: 232 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Postcodes
2+
3+
Utility methods for UK Postcodes
4+
5+
## Getting Started
6+
7+
Install with `npm install postcode`
8+
9+
Create an instance of Postcode to perform utility methods, like so
10+
11+
```
12+
var Postcode = require("postcode");
13+
14+
var postcode = new Postcode("id11qd");
15+
```
16+
17+
Perform simple validations, parsing and normalisation
18+
19+
```
20+
postcode.valid() // => True
21+
postcode.outcode() // => "ID1"
22+
postcode.incode() // => "1QD"
23+
postcode.normalise() // => "ID1 1QD"
24+
```
25+
26+
## Testing
27+
28+
```npm test```
29+
30+
## Note on Postcode Validation
31+
32+
Postcodes cannot be validated just using just a regular expression. Proper postcode validation requires having a full list of postcodes to check against.
33+
34+
Please do not solely rely on a regex to check postcodes or you're bound to get false postives/negatives.
35+
36+
## License
37+
38+
MIT

index.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"use strict";
2+
3+
var validationRegex = /^[a-z0-9]{1,4}\s?\d[a-z]{2}$/i,
4+
incodeRegex = /^[a-z0-9]{1,4}/i,
5+
outcodeRegex = /\d[a-z]{2}$/i;
6+
7+
function isValidPostcode (postcode) {
8+
return !!postcode.match(validationRegex);
9+
}
10+
11+
function parseIncode (postcode) {
12+
return postcode.match(incodeRegex)[0];
13+
}
14+
15+
function parseOutcode (postcode) {
16+
return postcode.match(outcodeRegex)[0];
17+
}
18+
19+
function Postcode (rawPostcode) {
20+
this._raw = rawPostcode;
21+
this._valid = isValidPostcode(rawPostcode);
22+
23+
if (!this._valid) {
24+
return null;
25+
}
26+
}
27+
28+
Postcode.prototype.valid = function () {
29+
return this._valid;
30+
}
31+
32+
Postcode.prototype.incode = function () {
33+
if (!this._valid) return null;
34+
if (this._incode) return this._incode;
35+
this._incode = parseIncode(this._raw);
36+
return this._incode;
37+
}
38+
39+
Postcode.prototype.outcode = function () {
40+
if (!this._valid) return null;
41+
if (this._outcode) return this._outcode;
42+
this._outcode = parseOutcode(this._raw);
43+
return this._outcode;
44+
}
45+
46+
Postcode.prototype.normalise = function () {
47+
if (!this._valid) return null;
48+
if (this.postcode) return this.postcode;
49+
return [this.incode().toUpperCase()," ", this.outcode().toUpperCase()].join("");
50+
}
51+
52+
module.exports = Postcode;

tests/data/normalisation.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"tests" : [
3+
{
4+
"base" : "L27 8XY",
5+
"expected" : "L27 8XY"
6+
},
7+
{
8+
"base" : "NR10 3EZ",
9+
"expected" : "NR10 3EZ"
10+
},
11+
{
12+
"base" : "NE69 7AW",
13+
"expected" : "NE69 7AW"
14+
},
15+
{
16+
"base" : "SE23 2NF",
17+
"expected" : "SE23 2NF"
18+
},
19+
{
20+
"base" : "Definitely wrong",
21+
"expected" : null
22+
}
23+
]
24+
}

tests/data/validation.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"tests" : [
3+
{
4+
"base" : "L27 8XY",
5+
"expected" : true
6+
},
7+
{
8+
"base" : "NR103EZ",
9+
"expected" : true
10+
},
11+
{
12+
"base" : "RG45AY",
13+
"expected" : true
14+
},
15+
{
16+
"base" : "NE69 7AW",
17+
"expected" : true
18+
},
19+
{
20+
"base" : "SE23 2NF",
21+
"expected" : true
22+
},
23+
{
24+
"base" : "Definitely wrong",
25+
"expected" : false
26+
},
27+
{
28+
"base" : "12FSSD",
29+
"expected" : false
30+
},
31+
{
32+
"base" : "BT35 8GE",
33+
"expected" : true
34+
}
35+
]
36+
}

tests/unit.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
var assert = require("chai").assert,
2+
fs = require("fs"),
3+
path = require("path"),
4+
dataDir = path.join(__dirname, "/data"),
5+
Postcode = require(path.join(__dirname, "../index")),
6+
testData, testResult;
7+
8+
describe("Postcode#Valid", function () {
9+
before(function (done) {
10+
testData = fs.readFile(path.join(dataDir, "validation.json"), function (error, data) {
11+
if (error) throw error;
12+
testData = JSON.parse(data);
13+
done();
14+
});
15+
});
16+
17+
it ("should return true for postcodes that look correct", function () {
18+
testData.tests.forEach(function (elem) {
19+
assert.equal(new Postcode(elem.base).valid(), elem.expected);
20+
});
21+
});
22+
});
23+
24+
describe("Postcode normalisation", function () {
25+
before(function (done) {
26+
testData = fs.readFile(path.join(dataDir, "normalisation.json"), function (error, data) {
27+
if (error) throw error;
28+
testData = JSON.parse(data);
29+
done();
30+
});
31+
});
32+
33+
it ("should correctly normalise postcodes", function () {
34+
testData.tests.forEach(function (elem) {
35+
assert.equal(new Postcode(elem.base).normalise(), elem.expected);
36+
})
37+
});
38+
39+
it ("should return null if invalid postcode", function () {
40+
assert.isNull(new Postcode("Definitly bogus").normalise());
41+
});
42+
});
43+
44+
describe("Incode parsing", function () {
45+
before(function (done) {
46+
testData = fs.readFile(path.join(dataDir, "incode.json"), function (error, data) {
47+
if (error) throw error;
48+
testData = JSON.parse(data);
49+
done();
50+
});
51+
});
52+
53+
it ("should correctly parse incodes", function () {
54+
testData.tests.forEach(function (elem) {
55+
assert.equal(new Postcode(elem.base).incode(), elem.expected);
56+
});
57+
});
58+
59+
it ("should return null if invalid postcode", function () {
60+
assert.isNull(new Postcode("Definitly bogus").incode());
61+
});
62+
});
63+
64+
describe("Outcode parsing", function () {
65+
before(function (done) {
66+
testData = fs.readFile(path.join(dataDir, "outcode.json"), function (error, data) {
67+
if (error) throw error;
68+
testData = JSON.parse(data);
69+
done();
70+
});
71+
});
72+
73+
it ("should correctly parse outcodes", function () {
74+
testData.tests.forEach(function (elem) {
75+
assert.equal(new Postcode(elem.base).outcode(), elem.expected);
76+
});
77+
});
78+
it ("should return null if invalid postcode", function () {
79+
assert.isNull(new Postcode("Definitly bogus").outcode());
80+
});
81+
});

0 commit comments

Comments
 (0)