UNPKG

cake-hash

Version:

CakePHP in Utility.Hash class like a collection manipulation. In JavaScript.

850 lines (768 loc) 23.7 kB
import assert from "power-assert" import Hash from "../src/cake-hash" function getArticleData() { return [ { article: { id: "1", user_id: "1", title: "First Article", body: "First Article Body" }, user: { id: "1", user: "mariano", password: "5f4dcc3b5aa765d61d8327deb882cf99" }, comment: [ { id: "1", article_id: "1", user_id: "2", comment: "First Comment for First Article" }, { id: "2", article_id: "1", user_id: "4", comment: "Second Comment for Second Article" } ], tag: [ { id: "1", tag: "tag1" }, { id: "2", tag: "tag2" } ], deep: { nesting: { test: { 1: "foo", 2: { and: {more: "stuff"} } } } } }, { article: { id: "2", user_id: "1", title: "Second Article", body: "Second Article Body", published: "Y" }, user: { id: "2", user: "mariano", password: "5f4dcc3b5aa765d61d8327deb882cf99" }, comment: [], tag: [] }, { article: { id: "3", user_id: "1", title: "Third Article", body: "Third Article Body" }, user: { id: "3", user: "mariano", password: "5f4dcc3b5aa765d61d8327deb882cf99" }, comment: [], tag: [] }, { article: { id: "4", user_id: "1", title: "Fourth Article", body: "Fourth Article Body" }, user: { id: "4", user: "mariano", password: "5f4dcc3b5aa765d61d8327deb882cf99" }, comment: [], tag: [] }, { article: { id: "5", user_id: "1", title: "Fifth Article", body: "Fifth Article Body" }, user: { id: "5", user: "mariano", password: "5f4dcc3b5aa765d61d8327deb882cf99" }, comment: [], tag: [] } ]; } function getUserData() { return [ { user: { id: 2, group_id: 1, data: { user: "mariano.iglesias", name: "Mariano Iglesias" } } }, { user: { id: 14, group_id: 2, data: { user: "phpnut", name: "Larry E. Masters" } } }, { user: { id: 25, group_id: 1, data: { user: "gwoo", name: "The Gwoo" } } } ]; } describe("cake-hash", () => { it("get()", () => { let data = ["abc", "def"]; assert(Hash.get(data, "0") === "abc"); assert(Hash.get(data, 0) === "abc"); assert(Hash.get(data, "1") === "def"); data = getArticleData(); assert(Hash.get([], "1.article.title") == null); assert(Hash.get([], "") == null); assert(Hash.get([], null, "-") === "-"); assert(Hash.get(data, "0.article.title") === "First Article"); assert(Hash.get(data, "1.article.title") === "Second Article"); assert(Hash.get(data, "5.article.title") == null); let defaultValue = ["empty"]; assert(defaultValue === Hash.get(data, "5.article.title", defaultValue)); assert(defaultValue === Hash.get([], "5.article.title", defaultValue)); assert(Hash.get(data, "1.article.title.not_there") == null); assert.deepEqual(Hash.get(data, "1.article"), data[1]["article"]); assert.deepEqual(Hash.get(data, ["1", "article"]), data[1]["article"]); data = {a: {b: {c: {d: 1}}}}; assert(Hash.get(data, "a.b.c.d") === 1); data = { "example.com": { "path": { "to": { "index.html": "Hello World" } } } }; assert(Hash.get(data, "example\\.com.path.to.index\\.html") === "Hello World"); }); describe("extract()", () => { it("Basic", () => { let data = getArticleData(); assert.deepEqual(Hash.extract(data, ""), data); assert(Hash.extract(data, "0.article.title") === "First Article"); assert(Hash.extract(data, "1.article.title") === "Second Article"); assert.deepEqual(Hash.extract([false], "{n}.something.another_thing"), []); }); it("NumericKey", () => { let data = getArticleData(); assert.deepEqual(Hash.extract(data, "{n}.article.title"), [ "First Article", "Second Article", "Third Article", "Fourth Article", "Fifth Article" ]); assert.deepEqual(Hash.extract(data, "0.comment.{n}.user_id"), ["2", "4"]); }); it("NumericMixedKeys", () => { let data = { user: { 0: { id: 4, name: "Neo" }, 1: { id: 5, name: "Morpheus" }, stringKey: { name: "Fail" } } }; assert.deepEqual(Hash.extract(data, "user.{n}.name"), ["Neo", "Morpheus"]); }); it("NumericNonZero", () => { let data = { 1: { user: { id: 1, name: "John" } }, 2: { user: { id: 2, name: "Bob" } }, 3: { user: { id: 3, name: "Tony" } } }; assert.deepEqual(Hash.extract(data, "{n}.user.name"), ["John", "Bob", "Tony"]); }); it("StringKey", () => { let data = getArticleData(); assert.deepEqual(Hash.extract(data, "{n}.{s}.user"), [ "mariano", "mariano", "mariano", "mariano", "mariano" ]); assert.deepEqual(Hash.extract(data, "{n}.{s}.nesting.test.1"), ["foo"]); }); it("Wildcard", () => { let data = { "02000009C5560001": {name: "Mr. Alphanumeric"}, "2300000918020101": {name: "Mr. Numeric"}, "390000096AB30001": {name: "Mrs. Alphanumeric"}, stuff: {name: "Ms. Word"}, 123: {name: "Mr. Number"} }; let results = Hash.extract(data, "{*}.name"); assert(results.length === 5); assert(results.indexOf("Mr. Alphanumeric") > -1); assert(results.indexOf("Mr. Numeric") > -1); assert(results.indexOf("Mrs. Alphanumeric") > -1); assert(results.indexOf("Ms. Word") > -1); assert(results.indexOf("Mr. Number") > -1); }); it("AttributePresence", () => { let data = getArticleData(); assert.deepEqual(Hash.extract(data, "{n}.article[published]"), [data[1].article]); assert.deepEqual(Hash.extract(data, "{n}.article[id][published]"), [data[1].article]); }); it("AttributeEquality", () => { let data = getArticleData(); assert.deepEqual(Hash.extract(data, "{n}.article[id=3]"), [data[2].article]); assert.deepEqual(Hash.extract(data, "{n}.article[id = 3]"), [data[2].article]); let result = Hash.extract(data, "{n}.article[id!=3]"); assert(result[0]["id"] === "1"); assert(result[1]["id"] === "2"); assert(result[2]["id"] === "4"); assert(result[3]["id"] === "5"); }); it("AttributeBoolean", () => { let users = [ { id: 2, username: "johndoe", active: true }, { id: 5, username: "kevin", active: true }, { id: 9, username: "samantha", active: false } ]; let result; result = Hash.extract(users, "{n}[active=0]"); assert(result.length === 1); assert.deepEqual(result[0], users[2]); result = Hash.extract(users, "{n}[active=false]"); assert(result.length === 1); assert.deepEqual(result[0], users[2]); result = Hash.extract(users, "{n}[active=1]"); assert(result.length === 2); assert.deepEqual(result[0], users[0]); assert.deepEqual(result[1], users[1]); result = Hash.extract(users, "{n}[active=true]"); assert(result.length === 2); assert.deepEqual(result[0], users[0]); assert.deepEqual(result[1], users[1]); }); it("AttributeEqualityOnScalarValue", () => { let data = { entity: { id: 1, data1: "value" } }; assert.deepEqual(Hash.extract(data, "entity[id=1].data1"), ["value"]); data = {entity: false}; assert.deepEqual(Hash.extract(data, "entity[id=1].data1"), []); }); it("AttributeComparison", () => { let data = getArticleData(); let result; result = Hash.extract(data, "{n}.comment.{n}[user_id > 2]"); assert.deepEqual(result, [data[0]["comment"][1]]); assert(result[0]["user_id"] === "4"); result = Hash.extract(data, "{n}.comment.{n}[user_id >= 4]"); assert.deepEqual(result, [data[0]["comment"][1]]); assert(result[0]["user_id"] === "4"); result = Hash.extract(data, "{n}.comment.{n}[user_id < 3]"); assert.deepEqual(result, [data[0]["comment"][0]]); assert(result[0]["user_id"] === "2"); result = Hash.extract(data, "{n}.comment.{n}[user_id <= 2]"); assert.deepEqual(result, [data[0]["comment"][0]]); assert(result[0]["user_id"] === "2"); }); it("AttributeMultiple", () => { let data = getArticleData(); assert(Hash.extract(data, "{n}.comment.{n}[user_id > 2][id=1]").length === 0); assert.deepEqual(Hash.extract(data, "{n}.comment.{n}[user_id > 2][id=2]"), [data[0]["comment"][1]]); }); it("AttributePattern", () => { let data = getArticleData(); assert.deepEqual(Hash.extract(data, "{n}.article[title=/^First/]"), [data[0]["article"]]); assert.deepEqual(Hash.extract(data, "{n}.article[title=/^Fir[a-z]+/]"), [data[0]["article"]]); }); it("AttributeMatchesNull", () => { let data = { country: [ {name: "Canada"}, {name: "Australia"}, {name: null} ] }; assert.deepEqual(Hash.extract(data, "country.{n}[name=/Canada|^$/]"), [ {name: "Canada"}, {name: null} ]); }); it("UnevenKeys", () => { let data = { level1: { level2: ["test1", "test2"], level2bis: ["test3", "test4"] } }; assert.deepEqual(Hash.extract(data, "level1.level2"), ["test1", "test2"]); assert.deepEqual(Hash.extract(data, "level1.level2bis"), ["test3", "test4"]); data = { level1: { level2bis: [ ["test3", "test4"], ["test5", "test6"] ] } }; let expected = [ ["test3", "test4"], ["test5", "test6"] ]; assert.deepEqual(Hash.extract(data, "level1.level2bis"), expected); data["level1"]["level2"] = ["test1", "test2"]; assert.deepEqual(Hash.extract(data, "level1.level2bis"), expected); }); it("FilenameKey", () => { let data = { "cake-hash.min.js": [ {keyword: "array"}, {keyword: "object"}, {keyword: "utility"}, {keyword: "browser"}, {keyword: "client"}, {keyword: "server"}, {keyword: "cakephp"} ] }; assert.deepEqual(Hash.extract(data, "cake-hash\\.min\\.js.{n}[keyword=/^(a|c)/]"), [ {keyword: "array"}, {keyword: "client"}, {keyword: "cakephp"} ]); }); }); describe("insert()", () => { it("Simple", () => { let data = { pages: {name: "page"} }; assert.deepEqual(Hash.insert(data, "files", {name: "file"}), { pages: {name: "page"}, files: {name: "file"} }); data = { pages: {name: "page"} }; assert.deepEqual(Hash.insert(data, "pages.name", []), { pages: {name: []} }); data = { foo: {bar: "baz"} }; let result = Hash.insert(data, "some.0123.path", {foo: {bar: "baz"}}); assert.deepEqual(Hash.get(result, "some.0123.path"), { foo: {bar: "baz"} }); }); it("Multi", () => { let data = getArticleData(); let result = Hash.insert(data, "{n}.article.insert", "value"); assert(result[0]["article"]["insert"] === "value"); assert(result[1]["article"]["insert"] === "value"); result = Hash.insert(data, "{n}.comment.{n}.insert", "value"); assert(result[0]["comment"][0]["insert"] === "value"); assert(result[0]["comment"][1]["insert"] === "value"); data = [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second"}}, {item: {id: 3, title: "third"}}, {item: {id: 4, title: "fourth"}}, {item: {id: 5, title: "fifth"}} ]; result = Hash.insert(data, "{n}.item[id=/\\b2|\\b4/]", {test: 2}); assert.deepEqual(result, [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second", test: 2}}, {item: {id: 3, title: "third"}}, {item: {id: 4, title: "fourth", test: 2}}, {item: {id: 5, title: "fifth"}} ]); data = [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second"}}, {item: {id: 3, title: "third"}}, {item: {id: 4, title: "fourth"}, testable: true}, {item: {id: 5, title: "fifth"}} ]; result = Hash.insert(data, "{n}[testable].item[id=/\\b|\\b4/].test", 2); assert.deepEqual(result, [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second"}}, {item: {id: 3, title: "third"}}, {item: {id: 4, title: "fourth", test: 2}, testable: true}, {item: {id: 5, title: "fifth"}} ]); }); it("OverwriteStringValue", () => { let data = { some: {string: "value"} }; assert.deepEqual(Hash.insert(data, "some.string.value", ["values"]), { some: {string: {value: ["values"]}} }); }); }); describe("remove()", () => { it("Simple", () => { let data = { pages: {name: "page"}, files: {name: "file"} }; assert.deepEqual(Hash.remove(data, "files"), { pages: {name: "page"} }); data = { pages: [ {name: "main"}, {name: "about", vars: {title: "page title"}} ] }; assert.deepEqual(Hash.remove(data, "pages.1.vars"), { pages: [ {name: "main"}, {name: "about"} ] }); assert.deepEqual(Hash.remove(data, "pages.2.vars"), data); data = [ {name: "pages"}, {name: "files"} ]; assert.deepEqual(Hash.remove(data, "{n}[name=files]"), [ {name: "pages"} ]); data = ["foo", ["baz"]]; assert.deepEqual(Hash.remove(data, "{n}.part"), ["foo", ["baz"]]); assert.deepEqual(Hash.remove(data, "{n}.{n}.part"), ["foo", ["baz"]]); }); it("Multi", () => { let data = getArticleData(); let result = Hash.remove(data, "{n}.article.title"); assert(result[0]["article"]["title"] === undefined); assert(result[1]["article"]["title"] === undefined); data = getArticleData(); result = Hash.remove(data, "{n}.article.{s}"); assert(result[0]["article"] === undefined); data = [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second"}}, {item: {id: 3, title: "third"}}, {item: {id: 4, title: "fourth"}}, {item: {id: 5, title: "fifth"}} ]; let expected = []; expected[0] = {item: {id: 1, title: "first"}}; expected[2] = {item: {id: 3, title: "third"}}; expected[4] = {item: {id: 5, title: "fifth"}}; assert.deepEqual(Hash.remove(data, "{n}.item[id=/\\b2|\\b4/]"), expected); data = [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second"}}, {item: {id: 3, title: "third"}}, {item: {id: 4, title: "fourth"}, testable: true}, {item: {id: 5, title: "fifth"}} ]; assert.deepEqual(Hash.remove(data, "{n}[testable].item[id=/\\b2|\\b4/].title"), [ {item: {id: 1, title: "first"}}, {item: {id: 2, title: "second"}}, {item: {id: 3, title: "third"}}, {item: {id: 4}, testable: true}, {item: {id: 5, title: "fifth"}} ]); }); }); describe("combine()", () => { it("Simple", () => { assert(Hash.combine([], "{n}.user.id", "{n}.user.data").length === 0); let data = getUserData(); let expected = []; expected[2] = null; expected[14] = null; expected[25] = null; assert.deepEqual(Hash.combine(data, "{n}.user.id"), expected); assert.deepEqual(Hash.combine(data, "{n}.user.id", "{n}.user.non-existant"), expected); expected[2] = {user: "mariano.iglesias", name: "Mariano Iglesias"}; expected[14] = {user: "phpnut", name: "Larry E. Masters"}; expected[25] = {user: "gwoo", name: "The Gwoo"}; assert.deepEqual(Hash.combine(data, "{n}.user.id", "{n}.user.data"), expected); expected[2] = "Mariano Iglesias"; expected[14] = "Larry E. Masters"; expected[25] = "The Gwoo"; assert.deepEqual(Hash.combine(data, "{n}.user.id", "{n}.user.data.name"), expected); }); it("MissingValue", () => { let data = [ {user: {id: 1, name: "mark"}}, {user: {name: "jose"}} ]; assert(Hash.combine(data, "{n}.user.id", "{n}.user.name").length === 0); }); it("MissingKey", () => { let data = [ {user: {id: 1, name: "mark"}}, {user: {id: 2}} ]; assert(Hash.combine(data, "{n}.user.id", "{n}.user.name").length === 0); }); it("GroupPath", () => { let data = getUserData(); let expected = []; expected[1] = []; expected[1][2] = {user: "mariano.iglesias", name: "Mariano Iglesias"}; expected[1][25] = {user: "gwoo", name: "The Gwoo"}; expected[2] = []; expected[2][14] = {user: "phpnut", name: "Larry E. Masters"}; assert.deepEqual(Hash.combine(data, "{n}.user.id", "{n}.user.data", "{n}.user.group_id"), expected); expected = []; expected[1] = []; expected[1][2] = "Mariano Iglesias"; expected[1][25] = "The Gwoo"; expected[2] = []; expected[2][14] = "Larry E. Masters"; assert.deepEqual(Hash.combine(data, "{n}.user.id", "{n}.user.data.name", "{n}.user.group_id"), expected); expected = []; expected[1] = []; expected[1][2] = {user: "mariano.iglesias", name: "Mariano Iglesias"}; expected[1][25] = {user: "gwoo", name: "The Gwoo"}; expected[2] = []; expected[2][14] = {user: "phpnut", name: "Larry E. Masters"}; assert.deepEqual(Hash.combine(data, "{n}.user.id", "{n}.user.data", "{n}.user.group_id"), expected); }); }); it("check()", () => { let data = { "My Index 1": { first: "The first item" } }; assert(Hash.check(data, "My Index 1.first") === true); assert(Hash.check(data, "My Index 1") === true); data = { "My Index 1": { first: { second: { third: { fourth: "Heavy. Nesting" } } } } }; assert(Hash.check(data, "My Index 1.first.second") === true); assert(Hash.check(data, "My Index 1.first.second.third") === true); assert(Hash.check(data, "My Index 1.first.second.third.fourth") === true); assert(Hash.check(data, "My Index 1.first.seconds.third.fourth") === false); }); it("flatten", () => { let data = ["Larry", "Curly", "Moe"]; assert.deepEqual(Hash.flatten(data), data); data[9] = "Shemp"; assert.deepEqual(Hash.flatten(data), data); data = [ { post: {id: 1, author_id: 1, title: "First Post"}, author: {id: 1, user: "nate", password: "foo"} }, { post: {id: 2, author_id: 3, title: "Second Post", body: "Second Post Body"}, author: {id: 3, user: "larry", password: null} } ]; assert.deepEqual(Hash.flatten(data), { "0.post.id": 1, "0.post.author_id": 1, "0.post.title": "First Post", "0.author.id": 1, "0.author.user": "nate", "0.author.password": "foo", "1.post.id": 2, "1.post.author_id": 3, "1.post.title": "Second Post", "1.post.body": "Second Post Body", "1.author.id": 3, "1.author.user": "larry", "1.author.password": null }); data = [ { post: {id: 1, author_id: null, title: "First Post"}, author: [] } ]; assert.deepEqual(Hash.flatten(data), { "0.post.id": 1, "0.post.author_id": null, "0.post.title": "First Post", "0.author": [] }); data = [ {post: {id: 1}}, {post: {id: 2}} ]; assert.deepEqual(Hash.flatten(data, "/"), { "0/post/id": 1, "1/post/id": 2 }); data = [ {"index.html": {title: "Dashboard", body: "Dashboard Page"}}, {"about.html": {title: "About", body: "About Page"}}, {"./path/to/file.bundle.js": {title: "Bundle File", body: "Hello"}} ]; assert.deepEqual(Hash.flatten(data, "."), { "0.index\\.html.title": "Dashboard", "0.index\\.html.body": "Dashboard Page", "1.about\\.html.title": "About", "1.about\\.html.body": "About Page", "2.\\./path/to/file\\.bundle\\.js.title": "Bundle File", "2.\\./path/to/file\\.bundle\\.js.body": "Hello" }); }); it("expand", () => { let data = ["My", "Array", "To", "Flatten"]; let flat = Hash.flatten(data); assert.deepEqual(Hash.expand(flat), data); data = { "0.post.id": 1, "0.post.author_id": 1, "0.post.title": "First Post", "0.author.id": 1, "0.author.user": "nate", "0.author.password": "foo", "1.post.id": 2, "1.post.author_id": 3, "1.post.title": "Second Post", "1.post.body": "Second Post Body", "1.author.id": 3, "1.author.user": "larry", "1.author.password": null }; assert.deepEqual(Hash.expand(data), [ { post: {id: 1, author_id: 1, title: "First Post"}, author: {id: 1, user: "nate", password: "foo"} }, { post: {id: 2, author_id: 3, title: "Second Post", body: "Second Post Body"}, author: {id: 3, user: "larry", password: null} } ]); data = { "0/post/id": 1, "0/post/name": "test post" }; assert.deepEqual(Hash.expand(data, "/"), [ { post: {id: 1, name: "test post"} } ]); data = { "a.b.100.a": null, "a.b.200.a": null }; assert.deepEqual(Hash.expand(data), { a: { b: { 100: {a: null}, 200: {a: null} } } }); data = { "https://github\\.com/user/.repo.123.body": "CakePHP", "https://github\\.com/user/.repo.124.body": "CakeHash", "https://github\\.com/user/.repo.125.body": "npm" }; assert.deepEqual(Hash.expand(data), { "https://github.com/user/": { repo: { 123: {body: "CakePHP"}, 124: {body: "CakeHash"}, 125: {body: "npm"} } } }); }); it("map", () => { let data = getArticleData(); assert.deepEqual(Hash.map(data, "{n}.article.id", (value) => parseInt(value, 10) * 2), [2, 4, 6, 8, 10]); }); it("reduce", () => { let data = getArticleData(); assert(Hash.reduce(data, "{n}.article.id", (one, two) => parseInt(one, 10) + parseInt(two, 10)) === 15); }); });