New functions for fun
Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
parent
22a03405df
commit
374c0a233c
|
@ -2,8 +2,11 @@ const uuid = require("uuid/v4");
|
||||||
const empty = require("is-empty");
|
const empty = require("is-empty");
|
||||||
const Ajv = require("ajv");
|
const Ajv = require("ajv");
|
||||||
|
|
||||||
// Reserved attributes names
|
const {
|
||||||
const reserved = {
|
equalsOrThrow
|
||||||
|
} = require("../utils/fun.js");
|
||||||
|
|
||||||
|
const RESERVED_ATTRIBUTES = {
|
||||||
type: "type",
|
type: "type",
|
||||||
specversion: "specversion",
|
specversion: "specversion",
|
||||||
source: "source",
|
source: "source",
|
||||||
|
@ -16,13 +19,16 @@ const reserved = {
|
||||||
data: "data"
|
data: "data"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SUPPORTED_CONTENT_ENCODING = [];
|
||||||
|
SUPPORTED_CONTENT_ENCODING.push("base64");
|
||||||
|
|
||||||
const schema = require("../../ext/spec_0_3.json");
|
const schema = require("../../ext/spec_0_3.json");
|
||||||
|
|
||||||
const ajv = new Ajv({
|
const ajv = new Ajv({
|
||||||
extendRefs: true
|
extendRefs: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const validate = ajv.compile(schema);
|
const isValidAgainstSchema = ajv.compile(schema);
|
||||||
|
|
||||||
function Spec03(_caller){
|
function Spec03(_caller){
|
||||||
this.payload = {
|
this.payload = {
|
||||||
|
@ -67,14 +73,31 @@ function Spec03(_caller){
|
||||||
* Check the spec constraints
|
* Check the spec constraints
|
||||||
*/
|
*/
|
||||||
Spec03.prototype.check = function(ce){
|
Spec03.prototype.check = function(ce){
|
||||||
var toCheck = ce;
|
var toCheck = (!ce ? this.payload : ce);
|
||||||
if(!toCheck) {
|
|
||||||
toCheck = this.payload;
|
var valid = isValidAgainstSchema(toCheck);
|
||||||
}
|
|
||||||
var valid = validate(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) {
|
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){
|
Spec03.prototype.addExtension = function(key, value){
|
||||||
if(!reserved.hasOwnProperty(key)){
|
if(!RESERVED_ATTRIBUTES.hasOwnProperty(key)){
|
||||||
this.payload[key] = value;
|
this.payload[key] = value;
|
||||||
} else {
|
} else {
|
||||||
throw {message: "Reserved attribute name: '" + key + "'"};
|
throw {message: "Reserved attribute name: '" + key + "'"};
|
||||||
|
|
|
@ -3,6 +3,11 @@ const isString = (v) => (typeof v) === "string";
|
||||||
const isObject = (v) => (typeof v) === "object";
|
const isObject = (v) => (typeof v) === "object";
|
||||||
const isDefined = (v) => v && (typeof v) != "undefined";
|
const isDefined = (v) => v && (typeof v) != "undefined";
|
||||||
|
|
||||||
|
const isStringOrThrow = (v, t) =>
|
||||||
|
(isString(v)
|
||||||
|
? true
|
||||||
|
: (() => {throw t;})());
|
||||||
|
|
||||||
const isDefinedOrThrow = (v, t) =>
|
const isDefinedOrThrow = (v, t) =>
|
||||||
(isDefined(v)
|
(isDefined(v)
|
||||||
? () => true
|
? () => true
|
||||||
|
@ -15,11 +20,19 @@ const isStringOrObjectOrThrow = (v, t) =>
|
||||||
? true
|
? true
|
||||||
: (() => {throw t;})());
|
: (() => {throw t;})());
|
||||||
|
|
||||||
|
const equalsOrThrow = (v1, v2, t) =>
|
||||||
|
(v1 === v2
|
||||||
|
? true
|
||||||
|
: (() => {throw t;})());
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isString,
|
isString,
|
||||||
|
isStringOrThrow,
|
||||||
isObject,
|
isObject,
|
||||||
isDefined,
|
isDefined,
|
||||||
|
|
||||||
isDefinedOrThrow,
|
isDefinedOrThrow,
|
||||||
isStringOrObjectOrThrow
|
isStringOrObjectOrThrow,
|
||||||
|
|
||||||
|
equalsOrThrow
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -21,7 +21,6 @@ var cloudevent =
|
||||||
.id(id)
|
.id(id)
|
||||||
.source(source)
|
.source(source)
|
||||||
.type(type)
|
.type(type)
|
||||||
.dataContentEncoding(dataContentEncoding)
|
|
||||||
.dataContentType(dataContentType)
|
.dataContentType(dataContentType)
|
||||||
.schemaurl(schemaurl)
|
.schemaurl(schemaurl)
|
||||||
.subject(subject)
|
.subject(subject)
|
||||||
|
@ -50,7 +49,10 @@ describe("CloudEvents Spec v0.3", () => {
|
||||||
|
|
||||||
describe("OPTIONAL Attributes", () => {
|
describe("OPTIONAL Attributes", () => {
|
||||||
it("Should have 'datacontentencoding'", () => {
|
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'", () => {
|
it("Should have 'datacontenttype'", () => {
|
||||||
|
@ -162,8 +164,51 @@ describe("CloudEvents Spec v0.3", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("'datacontentencoding'", () => {
|
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());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue