Skip to content

Commit

Permalink
draft inferValue helper
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislav-atr committed Dec 30, 2022
1 parent e45a707 commit bcef888
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 113 deletions.
35 changes: 35 additions & 0 deletions src/helpers/string-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,38 @@ export function generateRandomResponse(customResponseText) {
customResponse = getRandomStrByLength(length);
return customResponse;
}

/**
* Infers value from string argument
* @param {string} value
* @returns {any}
*/
export function inferValue(value) {
// describe waterfall here
if (value === 'undefined') {
return undefined;
} if (value === 'false') {
return false;
} if (value === 'true') {
return true;
} if (value === 'null') {
return null;
} if (value === 'NaN') {
return NaN;
}

const numVal = parseFloat(value, 10)
if (!nativeIsNaN(numVal)) {
return numVal;
}

try {
const parsableVal = JSON.parse(value);
if (parsableVal instanceof Object) {
return parsableVal;
}
} catch { /* no */ }

const errorMessage = `'${value}' argument's value can't be inferred`;
throw new TypeError(errorMessage);
}
83 changes: 3 additions & 80 deletions src/scriptlets/trusted-set-constant.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
hit,
inferValue,
logMessage,
noopArray,
noopObject,
Expand Down Expand Up @@ -98,86 +99,7 @@ export function trustedSetConstant(source, property, value, infer = false, stack
return;
}


const constantValue = infer ? inferValue(value) : value;

/**
* #%#//scriptlet('trusted-set-constant', 'prop', '12.34') => typeof window.prop === 'string'
*
* #%#//scriptlet('trusted-set-constant', 'prop', '12.34', true) => typeof window.prop === 'number'
*
*
*
* #%#//scriptlet('trusted-set-constant', 'prop', '{}') => typeof window.prop === 'string'
*
* #%#//scriptlet('trusted-set-constant', 'prop', '{}', true) => typeof window.prop === 'object'
*/

/**
* Infers value from string argument
* @param {string} value
* @returns {any}
*/
function inferValue(value) {
if (value === 'undefined') {
return undefined;
} else if (value === 'false') {
return false;
} else if (value === 'true') {
return true;
} else if (value === 'null') {
return null;
} else if (value === 'NaN') {
return NaN;
}

const numVal = value.indexOf('.') === -1
? parseInt(value, 10) : parseFloat(value, 10);
if (!isNaN(numVal)) {
return numVal;
}

try {
let parsableVal = JSON.parse(value);
if (typeof parsableVal === 'object') {
return parsableVal;
}
} catch { /* no */ }

throw new Error('wtf');
}

const constantValue2 = convertValue(value, type)
/**
* Converts value to a specified type
* @param {string} value
* @param {string} type
* @returns
*/
function convertValue(value, type) {
switch (type) {
case 'number':
return parseInt(value, 10);
case 'decimal':
return parseFloat(value, 10);
case 'object':
return JSON.parse(value);
case 'NaN':
return NaN;
case 'undefined':
return undefined;
case 'null':
return null;
case 'true':
return true;
case 'false':
return false;

default: {
throw new Error('wtf');
}
}
}
const constantValue = infer ? inferValue(value, type) : value;

let canceled = false;
const mustCancel = (value) => {
Expand Down Expand Up @@ -311,6 +233,7 @@ trustedSetConstant.names = [
];
trustedSetConstant.injections = [
hit,
inferValue,
logMessage,
noopArray,
noopObject,
Expand Down
125 changes: 92 additions & 33 deletions tests/helpers/string-utils.test.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,107 @@
import { toRegExp } from '../../src/helpers';
import { toRegExp, inferValue } from '../../src/helpers';

const { test, module } = QUnit;
const name = 'scriptlets-redirects helpers';

module(name);

test('Test toRegExp for valid inputs', (assert) => {
const DEFAULT_VALUE = '.?';
const defaultRegexp = new RegExp(DEFAULT_VALUE);
let inputStr;
let expRegex;
// test('Test toRegExp for valid inputs', (assert) => {
// const DEFAULT_VALUE = '.?';
// const defaultRegexp = new RegExp(DEFAULT_VALUE);
// let inputStr;
// let expRegex;

inputStr = '/abc/';
expRegex = /abc/;
assert.deepEqual(toRegExp(inputStr), expRegex);
// inputStr = '/abc/';
// expRegex = /abc/;
// assert.deepEqual(toRegExp(inputStr), expRegex);

inputStr = '/[a-z]{1,9}/';
expRegex = /[a-z]{1,9}/;
assert.deepEqual(toRegExp(inputStr), expRegex);
// inputStr = '/[a-z]{1,9}/';
// expRegex = /[a-z]{1,9}/;
// assert.deepEqual(toRegExp(inputStr), expRegex);

inputStr = '';
assert.deepEqual(toRegExp(inputStr), defaultRegexp);
});
// inputStr = '';
// assert.deepEqual(toRegExp(inputStr), defaultRegexp);
// });

// test('Test toRegExp for invalid inputs', (assert) => {
// let inputStr;

// assert.throws(() => {
// inputStr = '/\\/';
// toRegExp(inputStr);
// });

// assert.throws(() => {
// inputStr = '/[/';
// toRegExp(inputStr);
// });

// assert.throws(() => {
// inputStr = '/*/';
// toRegExp(inputStr);
// });

// assert.throws(() => {
// inputStr = '/[0-9]++/';
// toRegExp(inputStr);
// });
// });

test('inferValue works as expected with valid args', (assert) => {
// convert to number
let rawString = '1234';
let expected = 1234;
let result = inferValue(rawString);
assert.strictEqual(result, expected, 'value to number ok');

// convert to float
rawString = '-12.34';
expected = -12.34;
result = inferValue(rawString);
assert.strictEqual(result, expected, 'value to float ok');

// convert to boolean
rawString = 'false';
expected = false;
result = inferValue(rawString);
assert.strictEqual(result, expected, 'value to false ok');

rawString = 'true';
expected = true;
result = inferValue(rawString);
assert.strictEqual(result, expected, 'value to true ok');

test('Test toRegExp for invalid inputs', (assert) => {
let inputStr;
// convert to undefined
rawString = 'undefined';
expected = undefined;
result = inferValue(rawString);
assert.strictEqual(result, expected, 'value to undefined ok');

assert.throws(() => {
inputStr = '/\\/';
toRegExp(inputStr);
});
// convert to null
rawString = 'null';
expected = null;
result = inferValue(rawString);
assert.strictEqual(result, expected, 'value to null ok');

assert.throws(() => {
inputStr = '/[/';
toRegExp(inputStr);
});
// convert to NaN
rawString = 'NaN';
result = inferValue(rawString);
assert.ok(Number.isNaN(result), 'value to NaN ok');

assert.throws(() => {
inputStr = '/*/';
toRegExp(inputStr);
});
// convert to object
rawString = '{"aaa":123,"bbb":{"ccc":"string"}}';
expected = {
aaa: 123,
bbb: {
ccc: 'string',
},
};
result = inferValue(rawString);
assert.deepEqual(result, expected, 'value to object ok');

assert.throws(() => {
inputStr = '/[0-9]++/';
toRegExp(inputStr);
});
// convert to array
rawString = '[1,2,"string"]';
expected = [1, 2, 'string'];
result = inferValue(rawString);
assert.deepEqual(result, expected, 'value to array ok');
});

0 comments on commit bcef888

Please sign in to comment.