New functions for fun

Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
Fabio José 2019-07-29 09:33:37 -03:00
parent 22a03405df
commit 374c0a233c
4 changed files with 127 additions and 14 deletions

View File

@ -2,8 +2,11 @@ const uuid = require("uuid/v4");
const empty = require("is-empty");
const Ajv = require("ajv");
// Reserved attributes names
const reserved = {
const {
equalsOrThrow
} = require("../utils/fun.js");
const RESERVED_ATTRIBUTES = {
type: "type",
specversion: "specversion",
source: "source",
@ -16,13 +19,16 @@ const reserved = {
data: "data"
};
const SUPPORTED_CONTENT_ENCODING = [];
SUPPORTED_CONTENT_ENCODING.push("base64");
const schema = require("../../ext/spec_0_3.json");
const ajv = new Ajv({
extendRefs: true
});
const validate = ajv.compile(schema);
const isValidAgainstSchema = ajv.compile(schema);
function Spec03(_caller){
this.payload = {
@ -67,14 +73,31 @@ function Spec03(_caller){
* Check the spec constraints
*/
Spec03.prototype.check = function(ce){
var toCheck = ce;
if(!toCheck) {
toCheck = this.payload;
}
var valid = validate(toCheck);
var toCheck = (!ce ? this.payload : ce);
var valid = isValidAgainstSchema(toCheck);
Array.of(toCheck)
.filter((tc) => (typeof tc.data) !== 'string')
.filter((tc) => tc["datacontentencoding"])
.forEach((tc) => {
throw {message: "invalid payload", errors: [
"Use 'datacontentencoding' when 'data' is a string"
]};
});
Array.of(toCheck)
.filter((tc) => tc["datacontentencoding"])
.map((tc) => tc["datacontentencoding"].toLocaleLowerCase("en-US"))
.filter((dce) => !SUPPORTED_CONTENT_ENCODING.includes(dce))
.forEach((dce) => {
throw {message: "invalid payload", errors: [
"Unsupported content encoding: " + dce
]};
})
if(!valid) {
throw {message: "invalid payload", errors: validate.errors};
throw {message: "invalid payload", errors: isValidAgainstSchema.errors};
}
};
@ -173,7 +196,7 @@ Spec03.prototype.getData = function() {
};
Spec03.prototype.addExtension = function(key, value){
if(!reserved.hasOwnProperty(key)){
if(!RESERVED_ATTRIBUTES.hasOwnProperty(key)){
this.payload[key] = value;
} else {
throw {message: "Reserved attribute name: '" + key + "'"};

View File

@ -3,6 +3,11 @@ const isString = (v) => (typeof v) === "string";
const isObject = (v) => (typeof v) === "object";
const isDefined = (v) => v && (typeof v) != "undefined";
const isStringOrThrow = (v, t) =>
(isString(v)
? true
: (() => {throw t;})());
const isDefinedOrThrow = (v, t) =>
(isDefined(v)
? () => true
@ -15,11 +20,19 @@ const isStringOrObjectOrThrow = (v, t) =>
? true
: (() => {throw t;})());
const equalsOrThrow = (v1, v2, t) =>
(v1 === v2
? true
: (() => {throw t;})());
module.exports = {
isString,
isStringOrThrow,
isObject,
isDefined,
isDefinedOrThrow,
isStringOrObjectOrThrow
isStringOrObjectOrThrow,
equalsOrThrow
};

32
test/fun_tests.js Normal file
View File

@ -0,0 +1,32 @@
const expect = require("chai").expect;
const fun = require("../lib/utils/fun.js");
describe("Functional approach", () => {
describe("isStringOrThrow", () => {
it("should throw when is not a string", () => {
expect(fun.isStringOrThrow.bind(fun, 3.6, {message: "works!"}))
.to
.throw("works!");
});
it("should return true when is a string", () => {
expect(fun.isStringOrThrow("cool", {message: "not throws!"}))
.to
.equals(true);
});
});
describe("equalsOrThrow", () => {
it("should throw when they are not equals", () => {
expect(fun.equalsOrThrow.bind(fun, "z", "a", {message: "works!"}))
.to
.throw("works!");
});
it("should return true when they are equals", () => {
expect(fun.equalsOrThrow("z", "z", {message: "not throws!"}))
.to
.equals(true);
});
});
});

View File

@ -21,7 +21,6 @@ var cloudevent =
.id(id)
.source(source)
.type(type)
.dataContentEncoding(dataContentEncoding)
.dataContentType(dataContentType)
.schemaurl(schemaurl)
.subject(subject)
@ -50,7 +49,10 @@ describe("CloudEvents Spec v0.3", () => {
describe("OPTIONAL Attributes", () => {
it("Should have 'datacontentencoding'", () => {
expect(cloudevent.getDataContentEncoding()).to.equal(dataContentEncoding);
cloudevent.dataContentEncoding(dataContentEncoding);
expect(cloudevent.spec.payload.datacontentencoding)
.to.equal(dataContentEncoding);
delete cloudevent.spec.payload.datacontentencoding;
});
it("Should have 'datacontenttype'", () => {
@ -162,8 +164,51 @@ describe("CloudEvents Spec v0.3", () => {
});
describe("'datacontentencoding'", () => {
it("should throw an erro when 'data' is not a string", () => {
it("should throw an error when 'data' is not a string", () => {
cloudevent
.dataContentEncoding(dataContentEncoding);
expect(cloudevent.format.bind(cloudevent))
.to
.throw("invalid payload");
cloudevent.data(data);
delete cloudevent.spec.payload.datacontentencoding;
});
it("should throw an error when is a unsupported encoding" , () => {
cloudevent
.data("Y2xvdWRldmVudHMK")
.dataContentEncoding("binary");
expect(cloudevent.format.bind(cloudevent))
.to
.throw("invalid payload");
delete cloudevent.spec.payload.datacontentencoding;
cloudevent.data(data);
});
it("should accept when 'data' is a string", () => {
cloudevent
.data("Y2xvdWRldmVudHMK")
.dataContentEncoding("base64");
expect(cloudevent.format()).to.have.property("datacontentencoding");
delete cloudevent.spec.payload.datacontentencoding;
cloudevent.data(data);
});
});
describe("'subject'", () => {
it("should throw an error when is an empty string", () => {
cloudevent.subject("");
expect(cloudevent.format.bind(cloudevent))
.to
.throw("invalid payload");
cloudevent.subject(type);
});
});
describe("'time'", () => {
it("must adhere to the format specified in RFC 3339", () => {
cloudevent.time(time);
expect(cloudevent.format()["time"]).to.equal(time.toISOString());
});
});
});