From 783795ceeedb8f6212e1d5d5df8dc1eb82c0b7a3 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 7 Jun 2015 11:34:48 -0400 Subject: [PATCH 1/3] Wrapped in StringFilr module as exports --- Source/StringFilr.ts | 366 ++++++++++++++++++++++--------------------- Tests/tests.js | 8 +- 2 files changed, 191 insertions(+), 183 deletions(-) diff --git a/Source/StringFilr.ts b/Source/StringFilr.ts index 296623e..073b79c 100644 --- a/Source/StringFilr.ts +++ b/Source/StringFilr.ts @@ -1,219 +1,227 @@ -interface IStringFilrSettings { - // An Object containing data stored as children of sub-Objects. - library: any; +module StringFilr { + "use strict"; - // A String to use as a default key to rescue on, if provided. - normal?: string; + export interface IStringFilrSettings { + // An Object containing data stored as children of sub-Objects. + library: any; - // Whether it's ok for the library to have Objects that don't contain the - // normal key (by default, false). - requireNormalKey?: boolean; -} + // A String to use as a default key to rescue on, if provided. + normal?: string; -/** - * A general utility for retrieving data from an Object based on nested class - * names. You can think of the internal "library" Object as a tree structure, - * such that you can pass in a listing (in any order) of the path to data for - * retrieval. - * - * @author "Josh Goldberg" - */ -class StringFilr { - // The library of data. - private library: any; - - // Listing of previously found lookups, for speed's sake. - private cache: any; - - // Optional default class to use when no suitable option is found. - private normal: string; - - // Whether to crash when a sub-object in reset has no normal child. - private requireNormalKey: boolean; + // Whether it's ok for the library to have Objects that don't contain the + // normal key (by default, false). + requireNormalKey?: boolean; + } /** - * Resets the StringFilr. + * A general utility for retrieving data from an Object based on nested class + * names. You can think of the internal "library" Object as a tree structure, + * such that you can pass in a listing (in any order) of the path to data for + * retrieval. * - * @constructor - * @param {IStringFilrSettings} settings + * @author "Josh Goldberg" */ - constructor(settings: IStringFilrSettings) { - if (!settings) { - throw new Error("No settings given to StringFilr."); - } + export class StringFilr { + // The library of data. + private library: any; - if (!settings.library) { - throw new Error("No library given to StringFilr."); - } - this.library = settings.library; + // Listing of previously found lookups, for speed's sake. + private cache: any; - this.normal = settings.normal; - this.requireNormalKey = settings.requireNormalKey; + // Optional default class to use when no suitable option is found. + private normal: string; - this.cache = {}; + // Whether to crash when a sub-object in reset has no normal child. + private requireNormalKey: boolean; - if (this.requireNormalKey) { - if (typeof this.normal === "undefined") { - throw new Error("StringFilr is given requireNormalKey, but no normal class."); + /** + * Resets the StringFilr. + * + * @constructor + * @param {IStringFilrSettings} settings + */ + constructor(settings: IStringFilrSettings) { + if (!settings) { + throw new Error("No settings given to StringFilr."); } - this.ensureLibraryNormal(); - } - } + if (!settings.library) { + throw new Error("No library given to StringFilr."); + } + this.library = settings.library; - /** - * @return {Object} The base library of stored information. - */ - getLibrary(): any { - return this.library; - } + this.normal = settings.normal; + this.requireNormalKey = settings.requireNormalKey; - /** - * @return {String} The optional normal class String. - */ - getNormal(): string { - return this.normal; - } + this.cache = {}; - /** - * @return {Object} The complete cache of cached output. - */ - getCache(): any { - return this.cache; - } + if (this.requireNormalKey) { + if (typeof this.normal === "undefined") { + throw new Error("StringFilr is given requireNormalKey, but no normal class."); + } - /** - * @return {Mixed} A cached value, if it exists/ - */ - getCached(key: string): any { - return this.cache[key]; - } - - /** - * Completely clears the cache Object. - */ - clearCache(): void { - this.cache = {}; - } - - /** - * Clears the cached entry for a key. - * - * @param {String} key - */ - clearCached(key: string): void { - if (this.normal) { - key = key.replace(this.normal, ""); + this.ensureLibraryNormal(); + } } - delete this.cache[key]; - } - - /** - * Retrieves the deepest matching data in the library for a key. - * - * @param {String} keyRaw - * @return {Mixed} - */ - get(keyRaw: string): any { - var key: string, - result: any; - - if (this.normal) { - key = keyRaw.replace(this.normal, ""); - } else { - key = keyRaw; + /** + * @return {Object} The base library of stored information. + */ + getLibrary(): any { + return this.library; } - // Quickly return a cached result if it exists - if (this.cache.hasOwnProperty(key)) { + /** + * @return {String} The optional normal class String. + */ + getNormal(): string { + return this.normal; + } + + /** + * @return {Object} The complete cache of cached output. + */ + getCache(): any { + return this.cache; + } + + /** + * @return {Mixed} A cached value, if it exists/ + */ + getCached(key: string): any { return this.cache[key]; } - // Since no existed, it must be found deep within the library - result = this.followClass(key.split(/\s+/g), this.library); - - this.cache[key] = this.cache[keyRaw] = result; - return result; - } - - /** - * Utility helper to recursively check for tree branches in the library - * that don't have a key equal to the normal. For each sub-directory that - * is caught, the path to it is added to output. - * - * @param {Object} current The current location being searched within - * the library. - * @param {String} path The current path within the library. - * @param {String[]} output An Array of the String paths to parts that - * don't have a matching key. - * @return {String[]} output - */ - findLackingNormal(current: any, path: string, output: string[]): string[] { - var i: string; - - if (!current.hasOwnProperty(this.normal)) { - output.push(path); + /** + * Completely clears the cache Object. + */ + clearCache(): void { + this.cache = {}; } - if (typeof current[i] === "object") { - for (i in current) { - if (current.hasOwnProperty(i)) { - this.findLackingNormal(current[i], path + " " + i, output); + /** + * Clears the cached entry for a key. + * + * @param {String} key + */ + clearCached(key: string): void { + if (this.normal) { + key = key.replace(this.normal, ""); + } + + delete this.cache[key]; + } + + /** + * Retrieves the deepest matching data in the library for a key. + * + * @param {String} keyRaw + * @return {Mixed} + */ + get(keyRaw: string): any { + var key: string, + result: any; + + if (this.normal) { + key = keyRaw.replace(this.normal, ""); + } else { + key = keyRaw; + } + + // Quickly return a cached result if it exists + if (this.cache.hasOwnProperty(key)) { + return this.cache[key]; + } + + // Since no existed, it must be found deep within the library + result = this.followClass(key.split(/\s+/g), this.library); + + this.cache[key] = this.cache[keyRaw] = result; + return result; + } + + /** + * Utility helper to recursively check for tree branches in the library + * that don't have a key equal to the normal. For each sub-directory that + * is caught, the path to it is added to output. + * + * @param {Object} current The current location being searched within + * the library. + * @param {String} path The current path within the library. + * @param {String[]} output An Array of the String paths to parts that + * don't have a matching key. + * @return {String[]} output + */ + findLackingNormal(current: any, path: string, output: string[]): string[] { + var i: string; + + if (!current.hasOwnProperty(this.normal)) { + output.push(path); + } + + if (typeof current[i] === "object") { + for (i in current) { + if (current.hasOwnProperty(i)) { + this.findLackingNormal(current[i], path + " " + i, output); + } } } + + return output; } - return output; - } + /** + * Utility function to follow a path into the library (this is the driver + * for searching into the library). For each available key, if it matches + * a key in current, it is removed from keys and recursion happens on the + * sub-directory in current. + * + * @param {String[]} keys The currently available keys to search within. + * @param {Object} current The current location being searched within + * the library. + * @return {Mixed} The most deeply matched part of the library. + */ + private followClass(keys: string[], current: any): any { + var key: string, + i: number; - /** - * Utility function to follow a path into the library (this is the driver - * for searching into the library). For each available key, if it matches - * a key in current, it is removed from keys and recursion happens on the - * sub-directory in current. - * - * @param {String[]} keys The currently available keys to search within. - * @param {Object} current The current location being searched within - * the library. - * @return {Mixed} The most deeply matched part of the library. - */ - private followClass(keys: string[], current: any): any { - var key: string, - i: number; + // If keys runs out, we're done + if (!keys || !keys.length) { + return current; + } - // If keys runs out, we're done - if (!keys || !keys.length) { + // For each key in the current array... + for (i = 0; i < keys.length; i += 1) { + key = keys[i]; + + // ...if it matches, recurse on the other keys + if (current.hasOwnProperty(key)) { + keys.splice(i, 1); + return this.followClass(keys, current[key]); + } + } + + // If no key matched, try the normal (default) + if (this.normal && current.hasOwnProperty(this.normal)) { + return this.followClass(keys, current[this.normal]); + } + + // Nothing matches anything; we're done. return current; } - // For each key in the current array... - for (i = 0; i < keys.length; i += 1) { - key = keys[i]; + /** + * Driver for this.findLackingNormal. If library directories are found to + * not have a normal, it throws an error. + */ + private ensureLibraryNormal(): void { + var caught: string[] = this.findLackingNormal(this.library, "base", []); - // ...if it matches, recurse on the other keys - if (current.hasOwnProperty(key)) { - keys.splice(i, 1); - return this.followClass(keys, current[key]); + if (caught.length) { + throw new Error("Found " + caught.length + " library " + + "sub-directories missing the normal: " + + "\r\n " + caught.join("\r\n ")); } } - - // If no key matched, try the normal (default) - if (this.normal && current.hasOwnProperty(this.normal)) { - return this.followClass(keys, current[this.normal]); - } - - // Nothing matches anything; we're done. - return current; - } - - private ensureLibraryNormal(): void { - var caught: string[] = this.findLackingNormal(this.library, "base", []); - - if (caught.length) { - throw new Error("Found " + caught.length + " library " - + "sub-directories missing the normal: " - + "\r\n " + caught.join("\r\n ")); - } } } diff --git a/Tests/tests.js b/Tests/tests.js index ae6917a..8986632 100644 --- a/Tests/tests.js +++ b/Tests/tests.js @@ -27,18 +27,18 @@ var normal = "color", describe("constructor", function () { it("throws an error if not given settings", function () { chai.expect(function () { - new StringFilr(); + new StringFilr.StringFilr(); }).to.throw("No settings given to StringFilr."); }); it("throws an error if not given library", function () { chai.expect(function () { - new StringFilr({}); + new StringFilr.StringFilr({}); }).to.throw("No library given to StringFilr."); }); it("runs", function () { - StringFiler = new StringFilr({ + StringFiler = new StringFilr.StringFilr({ "normal": normal, "library": library }); @@ -90,4 +90,4 @@ describe("cache", function () { StringFiler.clearCached("my major"); chai.expect(StringFiler.getCached("my major")).to.be.undefined; }); -}); \ No newline at end of file +}); From d01bc17da6739b7b013275fabc97057363a6c609 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 8 Jun 2015 16:00:24 -0400 Subject: [PATCH 2/3] Separated into StringFilr.d.ts with IStringFilr --- Source/StringFilr.d.ts | 23 +++++++++++++++++++++++ Source/StringFilr.ts | 18 ++++-------------- 2 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 Source/StringFilr.d.ts diff --git a/Source/StringFilr.d.ts b/Source/StringFilr.d.ts new file mode 100644 index 0000000..d6fe0f3 --- /dev/null +++ b/Source/StringFilr.d.ts @@ -0,0 +1,23 @@ +declare module StringFilr { + export interface IStringFilrSettings { + // An Object containing data stored as children of sub-Objects. + library: any; + + // A String to use as a default key to rescue on, if provided. + normal?: string; + + // Whether it's ok for the library to have Objects that don't contain the + // normal key (by default, false). + requireNormalKey?: boolean; + } + + export interface IStringFilr { + getLibrary(): any; + getNormal(): string; + getCache(): any; + getCached(key: string): any; + clearCache(): void; + clearCached(key: string): void; + get(keyRaw: string): any; + } +} \ No newline at end of file diff --git a/Source/StringFilr.ts b/Source/StringFilr.ts index 073b79c..086a5ab 100644 --- a/Source/StringFilr.ts +++ b/Source/StringFilr.ts @@ -1,18 +1,8 @@ +/// + module StringFilr { "use strict"; - export interface IStringFilrSettings { - // An Object containing data stored as children of sub-Objects. - library: any; - - // A String to use as a default key to rescue on, if provided. - normal?: string; - - // Whether it's ok for the library to have Objects that don't contain the - // normal key (by default, false). - requireNormalKey?: boolean; - } - /** * A general utility for retrieving data from an Object based on nested class * names. You can think of the internal "library" Object as a tree structure, @@ -21,7 +11,7 @@ module StringFilr { * * @author "Josh Goldberg" */ - export class StringFilr { + export class StringFilr implements IStringFilr { // The library of data. private library: any; @@ -152,7 +142,7 @@ module StringFilr { * don't have a matching key. * @return {String[]} output */ - findLackingNormal(current: any, path: string, output: string[]): string[] { + private findLackingNormal(current: any, path: string, output: string[]): string[] { var i: string; if (!current.hasOwnProperty(this.normal)) { From 45ab3339586b41a5e0cabc9829cc7c8fae52c65a Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 12 Jun 2015 21:43:18 -0400 Subject: [PATCH 3/3] Cleaned up builds with preprocess: one output file --- Gruntfile.js | 16 +++++++++++++++- Source/StringFilr.d.ts | 14 ++++++++++---- Source/StringFilr.ts | 9 ++++----- package.json | 25 ++++++++++++------------- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index b2d8643..09663ff 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -21,11 +21,17 @@ module.exports = function (grunt) { "dest": "<%= meta.paths.source %>/<%= pkg.name %>.js" } }, + "clean": ["<%= meta.paths.dist %>"], "copy": { "default": { "files": [{ "src": "<%= meta.paths.source %>/<%= pkg.name %>.ts", "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts" + }, { + "src": "<%= meta.paths.source %>/References/*.ts", + "dest": "<%= meta.paths.dist %>/", + "expand": true, + "flatten": true }, { "src": "README.md", "dest": "<%= meta.paths.dist %>/" @@ -51,17 +57,25 @@ module.exports = function (grunt) { } } }, + "preprocess": { + "dist": { + "src": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts", + "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts" + } + }, "mocha_phantomjs": { "all": ["Tests/*.html"] } }); + grunt.loadNpmTasks("grunt-contrib-clean"); grunt.loadNpmTasks("grunt-contrib-copy"); grunt.loadNpmTasks("grunt-contrib-uglify"); grunt.loadNpmTasks("grunt-mocha-phantomjs"); + grunt.loadNpmTasks("grunt-preprocess"); grunt.loadNpmTasks("grunt-tslint"); grunt.loadNpmTasks("grunt-typescript"); grunt.registerTask("default", [ - "tslint", "typescript", "copy", "uglify", "mocha_phantomjs" + "tslint", "typescript", "clean", "copy", "uglify", "preprocess", "mocha_phantomjs" ]); }; \ No newline at end of file diff --git a/Source/StringFilr.d.ts b/Source/StringFilr.d.ts index d6fe0f3..e6be8ff 100644 --- a/Source/StringFilr.d.ts +++ b/Source/StringFilr.d.ts @@ -1,13 +1,19 @@ declare module StringFilr { export interface IStringFilrSettings { - // An Object containing data stored as children of sub-Objects. + /** + * An Object containing data stored as children of sub-Objects. + */ library: any; - // A String to use as a default key to rescue on, if provided. + /** + * A String to use as a default key to rescue on, if provided. + */ normal?: string; - // Whether it's ok for the library to have Objects that don't contain the - // normal key (by default, false). + /** + * Whether it's ok for the library to have Objects that don't contain the + * normal key (by default, false). + */ requireNormalKey?: boolean; } diff --git a/Source/StringFilr.ts b/Source/StringFilr.ts index 086a5ab..9a5a17d 100644 --- a/Source/StringFilr.ts +++ b/Source/StringFilr.ts @@ -1,4 +1,8 @@ +// @ifdef INCLUDE_DEFINITIONS /// +// @endif + +// @include ../Source/StringFilr.d.ts module StringFilr { "use strict"; @@ -8,8 +12,6 @@ module StringFilr { * names. You can think of the internal "library" Object as a tree structure, * such that you can pass in a listing (in any order) of the path to data for * retrieval. - * - * @author "Josh Goldberg" */ export class StringFilr implements IStringFilr { // The library of data. @@ -25,9 +27,6 @@ module StringFilr { private requireNormalKey: boolean; /** - * Resets the StringFilr. - * - * @constructor * @param {IStringFilrSettings} settings */ constructor(settings: IStringFilrSettings) { diff --git a/package.json b/package.json index 0fc56f8..e86a39f 100644 --- a/package.json +++ b/package.json @@ -13,21 +13,20 @@ "bugs": { "url": "https://github.com/FullScreenShenanigans/StringFilr/issues" }, - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/FullScreenShenanigans/StringFilr/blob/master/LICENSE.txt" - } - ], + "license": "MIT", "dependencies": { - "chai": "2.2.X", - "grunt": "0.4.X", - "grunt-cli": "0.1.X", - "grunt-contrib-copy": "0.8.X", - "grunt-contrib-uglify": "0.8.X", - "grunt-mocha-phantomjs": "0.6.X", + "chai": "~2.2.X", + "grunt-contrib-clean": "~0.6.0", + "grunt": "~0.4.X", + "grunt-cli": "~0.1.X", + "grunt-contrib-copy": "~0.8.X", + "grunt-contrib-uglify": "~0.8.X", + "grunt-mocha-phantomjs": "~0.6.X", "grunt-tslint": "2.0.X", "grunt-typescript": "0.6.X", - "mocha": "~2.2.X" + "mocha": "~2.2.X", + "grunt-preprocess": "~4.1.X", + "tslint": "~2.0.X", + "typescript": "~1.4.X" } } \ No newline at end of file