Skip to content
This repository has been archived by the owner on May 3, 2023. It is now read-only.

Commit

Permalink
release/0.4.0 (#17)
Browse files Browse the repository at this point in the history
* exclude empty header shards
* improve test coverage
  • Loading branch information
littlespex authored Sep 15, 2021
1 parent 80bc761 commit a9f217e
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist
node_modules
docs
coverage
22 changes: 18 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cmcd.js",
"version": "0.3.2",
"version": "0.4.0",
"description": "CMCD (Common Media Client Data) Library with Typescript definitions",
"main": "dist/cmcd.min.js",
"types": "dist/types/index.d.ts",
Expand All @@ -17,7 +17,7 @@
"ts"
],
"scripts": {
"test": "jest",
"test": "jest --coverage",
"build": "tsc",
"bundle": "rollup dist/types/index.js -o dist/cmcd.js -m",
"minify": "terser dist/cmcd.js -c -m --mangle-props regex=/_$/ --source-map url=cmcd.min.js.map -o dist/cmcd.min.js",
Expand All @@ -31,6 +31,7 @@
"license": "ISC",
"devDependencies": {
"@types/jest": "^27.0.1",
"crypto": "^1.0.1",
"jest": "^27.2.0",
"rollup": "^2.56.3",
"terser": "^5.8.0",
Expand All @@ -40,6 +41,7 @@
"typescript": "^4.4.3"
},
"jest": {
"testEnvironment": "jsdom",
"testPathIgnorePatterns": [
"/node_modules/",
".jsx?$"
Expand Down
6 changes: 0 additions & 6 deletions src/CmcdHeader.ts

This file was deleted.

22 changes: 0 additions & 22 deletions src/CmcdHeaderMap.ts

This file was deleted.

18 changes: 12 additions & 6 deletions src/CmcdUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function uuid(): string {
return (`${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`).replace(/[018]/g, (c: any) => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
}

function serialize(obj: any, { format = true, sort = false }: Partial<CmcdEncodeOptions> = {}) {
export function serialize(obj: any, { format = true, sort = false }: Partial<CmcdEncodeOptions> = {}) {
try {
return processData(obj, {
format,
Expand Down Expand Up @@ -51,9 +51,9 @@ function serialize(obj: any, { format = true, sort = false }: Partial<CmcdEncode
}
}

type ProcessOptions = CmcdEncodeOptions & { map?: (value: any, key?: string, obj?: any) => any; };
type ProcessOptions = CmcdEncodeOptions & { map: (value: any, key?: string, obj?: any) => any; };

function processData(obj: any, { format = true, sort = true, map }: Partial<ProcessOptions> = {}): any {
function processData(obj: any, { format = true, sort = true, map }: Partial<ProcessOptions>): any {
const results = [];

Object
Expand Down Expand Up @@ -83,7 +83,7 @@ function processData(obj: any, { format = true, sort = true, map }: Partial<Proc
}
}

const result = (map) ? map(value, key, obj) : [key, value];
const result = map(value, key, obj);

// sort inline
if (sort) {
Expand All @@ -108,7 +108,10 @@ export function toHeaders(cmcd: Partial<Cmcd>, options?: Partial<CmcdEncodeOptio
const entries = Object.entries(cmcd);
Object.entries(CmcdShards).forEach(([shard, props]) => {
const shards = entries.filter(entry => props.includes(entry[0]));
headers[`cmcd-${shard}`] = serialize(Object.fromEntries(shards), options);
const value = serialize(Object.fromEntries(shards), options);
if (value) {
headers[`cmcd-${shard}`] = value;
}
});

return headers;
Expand All @@ -125,6 +128,9 @@ export function toQuery(cmcd: Partial<Cmcd>, options?: Partial<CmcdEncodeOptions
* Convert a CMCD data object to JSON
*/
export function toJson(cmcd: Partial<Cmcd>, options?: Partial<CmcdEncodeOptions>) {
const data = processData(cmcd, options);
const data = processData(cmcd, {
...options,
map: (value, key) => [key, typeof value == 'symbol' ? value.description : value],
});
return JSON.stringify(Object.fromEntries(data));
};
79 changes: 68 additions & 11 deletions tests/CmcdUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import crypto from 'crypto';
import { Cmcd } from '../src/Cmcd';
import { toHeaders, toJson, toQuery } from '../src/CmcdUtils';
import { serialize, toHeaders, toJson, toQuery, uuid } from '../src/CmcdUtils';

// @ts-ignore
global.crypto = crypto.webcrypto;

const data = new Cmcd();
data.sid = 'session-id';
Expand All @@ -11,20 +15,73 @@ data.d = 324.69;
data.mtp = 10049;
data.bs = true;
data.br = 200;
data.v = 1;
data.pr = 1;

// custom data
data['com.example-hello'] = 'world';
data['com.example-testing'] = 1234;
data['com.example-exists'] = true;
data['com.example-notExists'] = false;
data['com.example-token'] = Symbol('s');

describe('UUID generation', () => {
const regex = /^[A-F\d]{8}-[A-F\d]{4}-4[A-F\d]{3}-[89AB][A-F\d]{3}-[A-F\d]{12}$/i;
const id = uuid();

test('format', () => {
expect(regex.test(id)).toBe(true);
});

test('unique', () => {
expect(uuid() == id).toBe(false);
});
});

describe('serialize', () => {
test('empty', () => {
expect(serialize({})).toEqual('');
});
});

test('Query serialization', () => {
expect(toQuery(data)).toBe('CMCD=br%3D200%2Cd%3D325%2Cmtp%3D10000%2Cnor%3D%22..%252Ftesting%252F3.m4v%22%2Cnrr%3D%220-99%22%2Ccid%3D%22content-id%22%2Csid%3D%22session-id%22%2Cbs');
describe('Query serialization', () => {
test('formatted, unsorted', () => {
expect(toQuery(data)).toBe('CMCD=br%3D200%2Cd%3D325%2Cmtp%3D10000%2Cnor%3D%22..%252Ftesting%252F3.m4v%22%2Cnrr%3D%220-99%22%2Ccid%3D%22content-id%22%2Csid%3D%22session-id%22%2Cbs%2Ccom.example-hello%3D%22world%22%2Ccom.example-testing%3D1234%2Ccom.example-exists%2Ccom.example-token%3Ds');
});

test('sorted', () => {
expect(toQuery(data, { sort: true })).toBe('CMCD=br%3D200%2Cbs%2Ccid%3D%22content-id%22%2Ccom.example-exists%2Ccom.example-hello%3D%22world%22%2Ccom.example-testing%3D1234%2Ccom.example-token%3Ds%2Cd%3D325%2Cmtp%3D10000%2Cnor%3D%22..%252Ftesting%252F3.m4v%22%2Cnrr%3D%220-99%22%2Csid%3D%22session-id%22');
});

test('unformatted', () => {
expect(toQuery(data, { format: false })).toBe('CMCD=br%3D200%2Cd%3D324.69%2Cmtp%3D10049%2Cnor%3D%22..%2Ftesting%2F3.m4v%22%2Cnrr%3D%220-99%22%2Ccid%3D%22content-id%22%2Csid%3D%22session-id%22%2Cbs%2Ccom.example-hello%3D%22world%22%2Ccom.example-testing%3D1234%2Ccom.example-exists%2Ccom.example-token%3Ds');
});
});

test('Header serialization', () => {
expect(toHeaders(data)).toEqual({
'cmcd-object': 'br=200,d=325',
'cmcd-request': 'mtp=10000,nor="..%2Ftesting%2F3.m4v",nrr="0-99"',
'cmcd-session': 'cid="content-id",sid="session-id"',
'cmcd-status': 'bs',
describe('Header serialization', () => {
test('all shards', () => {
expect(toHeaders(data)).toEqual({
'cmcd-object': 'br=200,d=325',
'cmcd-request': 'mtp=10000,nor="..%2Ftesting%2F3.m4v",nrr="0-99"',
'cmcd-session': 'cid="content-id",sid="session-id"',
'cmcd-status': 'bs',
});
});

test('ignore empty shards', () => {
expect(toHeaders({ br: 200 })).toEqual({
'cmcd-object': 'br=200',
});
});
});

test('JSON serialization', () => {
expect(toJson(data)).toEqual('{"br":200,"bs":true,"cid":"content-id","d":325,"mtp":10000,"nor":"..%2Ftesting%2F3.m4v","nrr":"0-99","sid":"session-id"}');
describe('JSON serialization', () => {

test('json', () => {
expect(toJson(data)).toEqual('{"br":200,"bs":true,"cid":"content-id","com.example-exists":true,"com.example-hello":"world","com.example-testing":1234,"com.example-token":"s","d":325,"mtp":10000,"nor":"..%2Ftesting%2F3.m4v","nrr":"0-99","sid":"session-id"}');
});

test('empty', () => {
expect(toJson(null)).toEqual('{}');
});
});

0 comments on commit a9f217e

Please sign in to comment.