Skip to content

Commit

Permalink
feat: add es-set-tostringtag
Browse files Browse the repository at this point in the history
feat: add `es-set-tostringtag`
  • Loading branch information
merodiro committed Jul 21, 2024
1 parent 5a6d86e commit e4ba031
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
61 changes: 61 additions & 0 deletions codemods/es-set-tostringtag/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import jscodeshift from 'jscodeshift';
import { removeImport } from '../shared.js';

/**
* @typedef {import('../../types.js').Codemod} Codemod
* @typedef {import('../../types.js').CodemodOptions} CodemodOptions
*/

/**
* @param {CodemodOptions} [options]
* @returns {Codemod}
*/
export default function (options) {
return {
name: 'es-set-tostringtag',
transform: ({ file }) => {
const j = jscodeshift;
const root = j(file.source);
let dirtyFlag = false;

const { identifier } = removeImport('es-set-tostringtag', root, j);

root
.find(j.CallExpression, {
callee: {
type: 'Identifier',
name: identifier,
},
})
.forEach((path) => {
const args = path.value.arguments;
const newExpression = j.callExpression(
j.memberExpression(
j.identifier('Object'),
j.identifier('defineProperty'),
),
[
args[0],
j.memberExpression(
j.identifier('Symbol'),
j.identifier('toStringTag'),
),
j.objectExpression([
j.property(
'init',
j.identifier('configurable'),
j.booleanLiteral(true),
),
// @ts-expect-error
j.property('init', j.identifier('value'), args[1]),
]),
],
);
j(path).replaceWith(newExpression);
dirtyFlag = true;
});

return dirtyFlag ? root.toSource(options) : file.source;
},
};
}
31 changes: 31 additions & 0 deletions test/fixtures/es-set-tostringtag/case-1/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const assert = require("assert");

const obj = {};
const sentinel = {};

Object.defineProperty(obj, Symbol.toStringTag, {
configurable: true,
value: sentinel,
});

assert.equal(
obj[Symbol.toStringTag],
sentinel,
"toStringTag property is as expected"
);

assert.equal(String(obj), "[object Object]", "toStringTag works");

var tagged = {};
tagged[Symbol.toStringTag] = "already tagged";
assert.equal(String(tagged), "[object already tagged]", "toStringTag works");

Object.defineProperty(tagged, Symbol.toStringTag, {
configurable: true,
value: "new tag",
});
assert.equal(
String(tagged),
"[object already tagged]",
"toStringTag is unchanged"
);
26 changes: 26 additions & 0 deletions test/fixtures/es-set-tostringtag/case-1/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const assert = require("assert");
const setToStringTag = require("es-set-tostringtag");

const obj = {};
const sentinel = {};

setToStringTag(obj, sentinel);

assert.equal(
obj[Symbol.toStringTag],
sentinel,
"toStringTag property is as expected"
);

assert.equal(String(obj), "[object Object]", "toStringTag works");

var tagged = {};
tagged[Symbol.toStringTag] = "already tagged";
assert.equal(String(tagged), "[object already tagged]", "toStringTag works");

setToStringTag(tagged, "new tag");
assert.equal(
String(tagged),
"[object already tagged]",
"toStringTag is unchanged"
);
31 changes: 31 additions & 0 deletions test/fixtures/es-set-tostringtag/case-1/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const assert = require("assert");

const obj = {};
const sentinel = {};

Object.defineProperty(obj, Symbol.toStringTag, {
configurable: true,
value: sentinel
});

assert.equal(
obj[Symbol.toStringTag],
sentinel,
"toStringTag property is as expected"
);

assert.equal(String(obj), "[object Object]", "toStringTag works");

var tagged = {};
tagged[Symbol.toStringTag] = "already tagged";
assert.equal(String(tagged), "[object already tagged]", "toStringTag works");

Object.defineProperty(tagged, Symbol.toStringTag, {
configurable: true,
value: "new tag"
});
assert.equal(
String(tagged),
"[object already tagged]",
"toStringTag is unchanged"
);

0 comments on commit e4ba031

Please sign in to comment.