Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 13 possibility to add more options #16

Closed
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
.vscode
node_modules
node_modules
.DS_Store
80 changes: 19 additions & 61 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"use strict";
var { validateInput } = require("./input-validation");

function toRadians(angleInDegrees) {
return (angleInDegrees * Math.PI) / 180;
}
Expand All @@ -24,69 +26,11 @@ function offset(c1, distance, bearing) {
return [toDegrees(lon), toDegrees(lat)];
}

function validateCenter(center) {
const validCenterLengths = [2, 3]
if (!Array.isArray(center) || !validCenterLengths.includes(center.length)) {
throw new Error("ERROR! Center has to be an array of length two or three");
}
const [lng, lat] = center;
if (typeof lng !== "number" || typeof lat !== "number") {
throw new Error(
`ERROR! Longitude and Latitude has to be numbers but where ${typeof lng} and ${typeof lat}`
);
}
if (lng > 180 || lng < -180) {
throw new Error(
`ERROR! Longitude has to be between -180 and 180 but was ${lng}`
);
}

if (lat > 90 || lat < -90) {
throw new Error(
`ERROR! Latitude has to be between -90 and 90 but was ${lat}`
);
}
}

function validateRadius(radius) {
if (typeof radius !== "number") {
throw new Error(
`ERROR! Radius has to be a positive number but was: ${typeof radius}`
);
}

if (radius <= 0) {
throw new Error(
`ERROR! Radius has to be a positive number but was: ${radius}`
);
}
}

function validateNumberOfSegments(numberOfSegments) {
if (typeof numberOfSegments !== "number" && numberOfSegments !== undefined) {
throw new Error(
`ERROR! Number of segments has to be a number but was: ${typeof numberOfSegments}`
);
}

if (numberOfSegments < 3) {
throw new Error(
`ERROR! Number of segments has to be at least 3 but was: ${numberOfSegments}`
);
}
}

function validateInput({ center, radius, numberOfSegments }) {
validateCenter(center);
validateRadius(radius);
validateNumberOfSegments(numberOfSegments);
}

module.exports = function circleToPolygon(center, radius, numberOfSegments) {
var n = numberOfSegments ? numberOfSegments : 32;
module.exports = function circleToPolygon(center, radius, options) {
var n = getNumberOfSegments(options);

// validateInput() throws error on invalid input and do nothing on valid input
validateInput({ center, radius, numberOfSegments });
validateInput({ center, radius, numberOfSegments: n });

var coordinates = [];
for (var i = 0; i < n; ++i) {
Expand All @@ -99,3 +43,17 @@ module.exports = function circleToPolygon(center, radius, numberOfSegments) {
coordinates: [coordinates]
};
};

function getNumberOfSegments(options) {
if (options === undefined) {
return 32;
} else if (isObjectNotArray(options)) {
var numberOfSegments = options.numberOfSegments;
return numberOfSegments === undefined ? 32 : numberOfSegments;
}
return options;
}

function isObjectNotArray(argument) {
return typeof argument === "object" && !Array.isArray(argument)
}
15 changes: 15 additions & 0 deletions input-validation/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var validateCenter = require("./validateCenter").validateCenter;
var validateRadius = require("./validateRadius").validateRadius;
var validateNumberOfSegments = require("./validateNumberOfSegments")
.validateNumberOfSegments;

function validateInput({ center, radius, numberOfSegments }) {
validateCenter(center);
validateRadius(radius);
validateNumberOfSegments(numberOfSegments);
}

exports.validateCenter = validateCenter;
exports.validateRadius = validateRadius;
exports.validateNumberOfSegments = validateNumberOfSegments;
exports.validateInput = validateInput;
24 changes: 24 additions & 0 deletions input-validation/validateCenter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
exports.validateCenter = function validateCenter(center) {
var validCenterLengths = [2, 3];
if (!Array.isArray(center) || !validCenterLengths.includes(center.length)) {
throw new Error("ERROR! Center has to be an array of length two or three");
}

var [lng, lat] = center;
if (typeof lng !== "number" || typeof lat !== "number") {
throw new Error(
`ERROR! Longitude and Latitude has to be numbers but where ${typeof lng} and ${typeof lat}`
);
}
if (lng > 180 || lng < -180) {
throw new Error(
`ERROR! Longitude has to be between -180 and 180 but was ${lng}`
);
}

if (lat > 90 || lat < -90) {
throw new Error(
`ERROR! Latitude has to be between -90 and 90 but was ${lat}`
);
}
};
18 changes: 18 additions & 0 deletions input-validation/validateNumberOfSegments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
exports.validateNumberOfSegments = function validateNumberOfSegments(
numberOfSegments
) {
if (typeof numberOfSegments !== "number") {
const ARGUMENT_TYPE = Array.isArray(numberOfSegments)
? "array"
: typeof numberOfSegments;
throw new Error(
`ERROR! Number of segments has to be a number but was: ${ARGUMENT_TYPE}`
);
}

if (numberOfSegments < 3) {
throw new Error(
`ERROR! Number of segments has to be at least 3 but was: ${numberOfSegments}`
);
}
};
13 changes: 13 additions & 0 deletions input-validation/validateRadius.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
exports.validateRadius = function validateRadius(radius) {
if (typeof radius !== "number") {
throw new Error(
`ERROR! Radius has to be a positive number but was: ${typeof radius}`
);
}

if (radius <= 0) {
throw new Error(
`ERROR! Radius has to be a positive number but was: ${radius}`
);
}
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { assert } = require("chai");
const circleToPolygon = require(".");
const circleToPolygon = require("..");

describe("Input verification", () => {
describe("Validating center input", () => {
Expand Down Expand Up @@ -119,6 +119,14 @@ describe("Input verification", () => {
);
});

it("should throw error if numberOfSegments values is zero", () => {
assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 0),
Error,
"ERROR! Number of segments has to be at least 3 but was: 0"
);
});

it("should NOT throw error when numberOfSegments is undefined", () => {
assert.doesNotThrow(
() => circleToPolygon([-59.99029, -58.99029], 50),
Expand All @@ -141,24 +149,54 @@ describe("Input verification", () => {
);
});

it("should throw error on too low value of numberOfSegments", () => {
assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 0),
it("should throw error when numberOfSegments is a function", () => {
assert.throw(
() => circleToPolygon([-59.99029, -58.99029], 3, function(){}),
Error,
"ERROR! Number of segments has to be at least 3 but was: 0"
"ERROR! Number of segments has to be a number but was: function"
);
});

assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 1),
it("should throw error when numberOfSegments is an array", () => {
assert.throw(
() => circleToPolygon([-59.99029, -58.99029], 3, [23]),
Error,
"ERROR! Number of segments has to be at least 3 but was: 1"
);

assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 2),
Error,
"ERROR! Number of segments has to be at least 3 but was: 2"
"ERROR! Number of segments has to be a number but was: array"
);
});

describe("On too low numberOfSegments value", () => {
it("numberOfSegments is < 0", () => {
assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, -10),
Error,
"ERROR! Number of segments has to be at least 3 but was: -10"
);
});

it("numberOfSegments is zero (0)", () => {
assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 0),
Error,
"ERROR! Number of segments has to be at least 3 but was: 0"
);
});

it("numberOfSegments is one (1)", () => {
assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 1),
Error,
"ERROR! Number of segments has to be at least 3 but was: 1"
);
});

it("numberOfSegments is 2 (2)", () => {
assert.throws(
() => circleToPolygon([-59.99029, -58.99029], 50, 2),
Error,
"ERROR! Number of segments has to be at least 3 but was: 2"
);
});
})
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { expect } = require("chai");
const circleToPolygon = require("./index.js");
const circleToPolygon = require("../index.js");

describe("Output verification", () => {
describe("Polygon should have correct attributes", () => {
Expand Down Expand Up @@ -142,6 +142,40 @@ describe("Output verification", () => {
});
});

it("should give same value when numberOfSegemnts is undefined or 32", () => {
const expectedCoordinates = circleToPolygon([131.034184, -25.343467], 5000, 32)
.coordinates[0];
const coordinates = circleToPolygon(
[131.034184, -25.343467],
5000,
undefined
).coordinates[0];

coordinates.forEach((cord, cordIndex) => {
cord.forEach((value, valueIndex) => {
const expectedValue = expectedCoordinates[cordIndex][valueIndex];
expect(value).to.be.closeTo(expectedValue, 0.00001);
});
});
});

it("should give same value when numberOfSegemnts is { numberOfSegments: undefined } or 32", () => {
const expectedCoordinates = circleToPolygon([131.034184, -25.343467], 5000, 32)
.coordinates[0];
const coordinates = circleToPolygon(
[131.034184, -25.343467],
5000,
{ numberOfSegments: undefined }
).coordinates[0];

coordinates.forEach((cord, cordIndex) => {
cord.forEach((value, valueIndex) => {
const expectedValue = expectedCoordinates[cordIndex][valueIndex];
expect(value).to.be.closeTo(expectedValue, 0.00001);
});
});
});

it("should give correct coordinates for point west of GMT, north of equator", () => {
const coordinates = circleToPolygon([-121.003331, 66.001764], 50000, 64)
.coordinates[0];
Expand Down Expand Up @@ -329,4 +363,16 @@ describe("Output verification", () => {
xit("test 2", () => {});
});
});

describe("Testing Different Options", () => {
it("should give same result when passing numberOfSegments as number or as object", () => {
const sentAsNumber = circleToPolygon([7.023961, 38.870996], 64, 23)
.coordinates[0];
const sentAsObject = circleToPolygon([7.023961, 38.870996], 64, {
numberOfSegments: 23
}).coordinates[0];

expect(sentAsObject).to.eql(sentAsNumber);
});
});
});