Skip to content

Commit

Permalink
Object function properties should call next()
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed Nov 5, 2019
1 parent ac439a6 commit 6ce8383
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 16 deletions.
20 changes: 15 additions & 5 deletions src/function.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Next } from "./types";
import { Next, ToString } from "./types";
import { quoteKey, isValidVariableName } from "./quote";

/**
Expand Down Expand Up @@ -35,12 +35,22 @@ const TOKENS_PRECEDING_REGEXPS = new Set(
).split(" ")
);

/**
* Track function parser usage.
*/
export const USED_METHOD_KEY = new WeakSet<Function>();

/**
* Stringify a function.
*/
export function functionToString(fn: Function, space: string, next: Next) {
return new FunctionParser(fn, space, next).stringify();
}
export const functionToString: ToString = (fn, space, next, key) => {
const name = typeof key === "string" ? key : undefined;

// Track in function parser for object stringify to avoid duplicate output.
if (name !== undefined) USED_METHOD_KEY.add(fn);

return new FunctionParser(fn, space, next, name).stringify();
};

/**
* Rewrite a stringified function to remove initial indentation.
Expand Down Expand Up @@ -78,7 +88,7 @@ export class FunctionParser {
public fn: Function,
public indent: string,
public next: Next,
public key?: PropertyKey
public key?: string
) {
this.fnString = Function.prototype.toString.call(fn);
this.fnType = fn.constructor.name as keyof typeof FUNCTION_PREFIXES;
Expand Down
33 changes: 33 additions & 0 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,39 @@ describe("javascript-stringify", () => {

expect(result).toEqual("[object Object]");
});

it("should support object functions", () => {
function makeRaw(str: string) {
const fn = () => {
/* Noop. */
};
fn.__expression = str;
return fn;
}

const result = stringify(
{
"no-console": makeRaw(
`process.env.NODE_ENV === 'production' ? 'error' : 'off'`
),
"no-debugger": makeRaw(
`process.env.NODE_ENV === 'production' ? 'error' : 'off'`
)
},
(val, indent, stringify) => {
if (val && val.__expression) {
return val.__expression;
}
return stringify(val);
},
2
);

expect(result).toEqual(`{
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}`);
});
});

describe("max depth", () => {
Expand Down
19 changes: 8 additions & 11 deletions src/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,22 @@ const rawObjectToString: ToString = (obj, indent, next) => {
const values = Object.keys(obj)
.reduce(
function(values, key) {
if (typeof obj[key] === "function") {
const parser = new FunctionParser(obj[key], indent, next, key);
const result = parser.stringify();
values.push(indent + result.split("\n").join(`\n${indent}`));
return values;
}

const result = next(obj[key], key);
const fn = obj[key];
const result = next(fn, key);

// Omit `undefined` object entries.
if (result === undefined) return values;

// String format the value data.
const value = result.split("\n").join(`\n${indent}`);

values.push(
`${indent}${quoteKey(key, next)}:${indent ? " " : ""}${value}`
);
// Skip `key` prefix for function parser.
if (USED_METHOD_KEY.has(fn)) {
values.push(`${indent}${value}`);
return values;
}

values.push(`${indent}${quoteKey(key, next)}:${space}${value}`);
return values;
},
[] as string[]
Expand Down

0 comments on commit 6ce8383

Please sign in to comment.