1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview Regression tests. 7 */ 8 9'use strict'; 10 11const assert = require('assert'); 12const { execSync } = require("child_process"); 13const fs = require('fs'); 14const sinon = require('sinon'); 15const tempfile = require('tempfile'); 16const tempy = require('tempy'); 17 18const exceptions = require('../exceptions.js'); 19const helpers = require('./helpers.js'); 20const scriptMutator = require('../script_mutator.js'); 21 22const sandbox = sinon.createSandbox(); 23 24const SYNTAX_ERROR_RE = /.*SyntaxError.*/ 25 26function createFuzzTest(fake_db, settings, inputFiles) { 27 const sources = inputFiles.map(input => helpers.loadTestData(input)); 28 29 const mutator = new scriptMutator.ScriptMutator(settings, fake_db); 30 const result = mutator.mutateMultiple(sources); 31 32 const output_file = tempfile('.js'); 33 fs.writeFileSync(output_file, result.code); 34 return output_file; 35} 36 37function execFile(jsFile) { 38 execSync("node " + jsFile, {stdio: ['pipe']}); 39} 40 41describe('Regression tests', () => { 42 beforeEach(() => { 43 helpers.deterministicRandom(sandbox); 44 45 this.settings = { 46 ADD_VAR_OR_OBJ_MUTATIONS: 0.0, 47 MUTATE_CROSSOVER_INSERT: 0.0, 48 MUTATE_EXPRESSIONS: 0.0, 49 MUTATE_FUNCTION_CALLS: 0.0, 50 MUTATE_NUMBERS: 0.0, 51 MUTATE_VARIABLES: 0.0, 52 engine: 'V8', 53 testing: true, 54 } 55 }); 56 57 afterEach(() => { 58 sandbox.restore(); 59 }); 60 61 it('combine strict and with', () => { 62 // Test that when a file with "use strict" is used in the inputs, 63 // the result is only strict if no other file contains anything 64 // prohibited in strict mode (here a with statement). 65 // It is assumed that such input files are marked as sloppy in the 66 // auto generated exceptions. 67 sandbox.stub(exceptions, 'getGeneratedSloppy').callsFake( 68 () => { return new Set(['regress/strict/input_with.js']); }); 69 const file = createFuzzTest( 70 'test_data/regress/strict/db', 71 this.settings, 72 ['regress/strict/input_strict.js', 'regress/strict/input_with.js']); 73 execFile(file); 74 }); 75 76 it('combine strict and delete', () => { 77 // As above with unqualified delete. 78 sandbox.stub(exceptions, 'getGeneratedSloppy').callsFake( 79 () => { return new Set(['regress/strict/input_delete.js']); }); 80 const file = createFuzzTest( 81 'test_data/regress/strict/db', 82 this.settings, 83 ['regress/strict/input_strict.js', 'regress/strict/input_delete.js']); 84 execFile(file); 85 }); 86 87 it('mutates negative value', () => { 88 // This tests that the combination of number, function call and expression 89 // mutator does't produce an update expression. 90 // Previously the 1 in -1 was replaced with another negative number leading 91 // to e.g. -/*comment/*-2. Then cloning the expression removed the 92 // comment and produced --2 in the end. 93 this.settings['MUTATE_NUMBERS'] = 1.0; 94 this.settings['MUTATE_FUNCTION_CALLS'] = 1.0; 95 this.settings['MUTATE_EXPRESSIONS'] = 1.0; 96 const file = createFuzzTest( 97 'test_data/regress/numbers/db', 98 this.settings, 99 ['regress/numbers/input_negative.js']); 100 execFile(file); 101 }); 102 103 it('mutates indices', () => { 104 // Test that indices are not replaced with a negative number causing a 105 // syntax error (e.g. {-1: ""}). 106 this.settings['MUTATE_NUMBERS'] = 1.0; 107 const file = createFuzzTest( 108 'test_data/regress/numbers/db', 109 this.settings, 110 ['regress/numbers/input_indices.js']); 111 execFile(file); 112 }); 113}); 114