Files
javascript-obfuscator-javas…/test/unit-tests/node/node-guards/NodeGuards.spec.ts
T

438 lines
16 KiB
TypeScript

import * as ESTree from 'estree';
import { assert } from 'chai';
import { Nodes } from '../../../../src/node/Nodes';
import { NodeGuards } from '../../../../src/node/NodeGuards';
import { NodeUtils } from '../../../../src/node/NodeUtils';
describe('NodeGuards', () => {
describe('isNodeHasBlockScope (node: ESTree.Node): node is TNodeWithBlockScope', () => {
describe('truthful checks', () => {
describe('variant #1: block statement of function declaration', () => {
const expectedResult: boolean = true;
const node: ESTree.Node = Nodes.getBlockStatementNode();
const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
'foo',
[],
node
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isNodeHasBlockScope(node, parentNode);
});
it('should check if node has block scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #2: block statement of function expression', () => {
const expectedResult: boolean = true;
const node: ESTree.Node = Nodes.getBlockStatementNode();
const parentNode: ESTree.FunctionExpression = Nodes.getFunctionExpressionNode(
[],
node
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isNodeHasBlockScope(node, parentNode);
});
it('should check if node has block scope', () => {
assert.equal(result, expectedResult);
});
});
});
describe('false checks', () => {
describe('variant #1: switch-case node', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getSwitchCaseNode(
Nodes.getLiteralNode(1),
[]
);
const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
'foo',
[],
Nodes.getBlockStatementNode([
Nodes.getSwitchStatementNode(
Nodes.getMemberExpressionNode(
Nodes.getIdentifierNode('bar'),
Nodes.getUpdateExpressionNode(
'++',
Nodes.getIdentifierNode('baz')
),
true
),
[node]
)
])
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isNodeHasBlockScope(node, parentNode);
});
it('should check if node has block scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #2: literal node', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getLiteralNode(1);
const parentNode: ESTree.FunctionDeclaration = Nodes.getFunctionDeclarationNode(
'foo',
[],
Nodes.getBlockStatementNode([
Nodes.getExpressionStatementNode(
Nodes.getCallExpressionNode(
Nodes.getIdentifierNode('bar'),
[node]
)
)
])
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isNodeHasBlockScope(node, parentNode);
});
it('should check if node has block scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #3: block statement of if statement', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getBlockStatementNode();
const parentNode: ESTree.IfStatement = Nodes.getIfStatementNode(
Nodes.getIdentifierNode('foo'),
node
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isNodeHasBlockScope(node, parentNode);
});
it('should check if node has block scope', () => {
assert.equal(result, expectedResult);
});
});
});
});
describe('isNodeHasScope (node: ESTree.Node): node is TNodeWithScope', () => {
describe('truthful checks', () => {
describe('variant #1: program node', () => {
const expectedResult: boolean = true;
const node: ESTree.Node = Nodes.getProgramNode();
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #2: block statement node', () => {
const expectedResult: boolean = true;
const node: ESTree.Node = Nodes.getBlockStatementNode();
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #3: switch case node', () => {
const expectedResult: boolean = true;
const node: ESTree.Node = Nodes.getSwitchCaseNode(
Nodes.getLiteralNode(1),
[]
);
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
});
describe('false checks', () => {
describe('variant #1: literal node', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getLiteralNode(1);
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #2: identifier node', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getIdentifierNode('foo');
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #3: if-statement node', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getIfStatementNode(
Nodes.getIdentifierNode('foo'),
Nodes.getBlockStatementNode()
);
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #4: switch-statement node', () => {
const expectedResult: boolean = false;
const node: ESTree.Node = Nodes.getSwitchStatementNode(
Nodes.getIdentifierNode('foo'),
[]
);
let result: boolean;
before(() => {
result = NodeGuards.isNodeHasScope(node);
});
it('should check if node has scope', () => {
assert.equal(result, expectedResult);
});
});
});
});
describe('isReplaceableIdentifierNode (node: ESTree.Node, parentNode: ESTree.Node): node is ESTree.Identifier', () => {
describe('truthful checks', () => {
describe('variant #1: parent node is function declaration node', () => {
const expectedResult: boolean = true;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getFunctionDeclarationNode(
'bar',
[identifier],
Nodes.getBlockStatementNode()
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #2: parent node is computed property node', () => {
const expectedResult: boolean = true;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getPropertyNode(
identifier,
Nodes.getLiteralNode('bar'),
true
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #4: parent node is computed member expression node', () => {
const expectedResult: boolean = true;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getMemberExpressionNode(
Nodes.getIdentifierNode('bar'),
identifier,
true
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #4: parent node is computed method definition node', () => {
const expectedResult: boolean = true;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(
identifier,
Nodes.getFunctionExpressionNode([], Nodes.getBlockStatementNode()),
'method',
true
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
});
describe('false checks', () => {
describe('variant #1: node isn\'t an identifier', () => {
const expectedResult: boolean = false;
const literal: ESTree.Literal = Nodes.getLiteralNode(1);
const parentNode: ESTree.Node = Nodes.getExpressionStatementNode(
Nodes.getCallExpressionNode(
Nodes.getIdentifierNode('foo'),
[literal]
)
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(literal, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #2: parent node isn\'t computed property node', () => {
const expectedResult: boolean = false;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getPropertyNode(
identifier,
Nodes.getLiteralNode('bar'),
false
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #3: parent node isn\'t computed member expression node', () => {
const expectedResult: boolean = false;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getMemberExpressionNode(
Nodes.getIdentifierNode('bar'),
identifier,
false
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
describe('variant #4: parent node isn\'t computed method definition node', () => {
const expectedResult: boolean = false;
const identifier: ESTree.Identifier = Nodes.getIdentifierNode('foo');
const parentNode: ESTree.Node = Nodes.getMethodDefinitionNode(
identifier,
Nodes.getFunctionExpressionNode([], Nodes.getBlockStatementNode()),
'method',
false
);
let result: boolean;
before(() => {
NodeUtils.parentize(parentNode);
result = NodeGuards.isReplaceableIdentifierNode(identifier, parentNode);
});
it('should check if input identifier can be replaced by obfuscated one', () => {
assert.equal(result, expectedResult);
});
});
});
});
});