Chromium Code Reviews| Index: test/mjsunit/harmony/typesystem/testgen.js |
| diff --git a/test/mjsunit/harmony/typesystem/testgen.js b/test/mjsunit/harmony/typesystem/testgen.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..740530d545b9baed76a42e11d51cb311ecb0da7b |
| --- /dev/null |
| +++ b/test/mjsunit/harmony/typesystem/testgen.js |
| @@ -0,0 +1,122 @@ |
| +// Copyright 2016 the V8 project authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +var debug = false; |
| + |
| +function CheckValid(type) { |
| + if (debug) { print("V:", type); } |
| + assertDoesNotThrow("'use types'; var x: " + type + ";"); |
| +} |
| + |
| +function CheckInvalid(type) { |
| + if (debug) { print("I:", type); } |
| + assertThrows("'use types'; var x: " + type + ";", SyntaxError); |
| +} |
| + |
| +// Parameters: |
| +// multiplicity: positive integer |
| +// generator: (size: positive integer, ...params: any[]) => Iterator<SomeType> |
| +// transformations: [false | ((t: SomeType) => OtherType)] |
| +// params: any[] |
| +// |
| +// A "test generator" object will have its "generator" generate tests, |
| +// will transform each generated test with all of its "transformations" |
| +// and will yield the results. false transformations will be ignored. |
| +class TestGen { |
|
rossberg
2016/03/17 16:51:37
I assume this is unchanged?
nickie
2016/03/18 11:12:01
Yes, just deleted from simple-types.js and brought
|
| + constructor(multiplicity, generator, transformations, ...params) { |
| + // Determines how often this generator will run, compared to other ones. |
| + this.multiplicity = multiplicity; |
| + // The generator function. It will be called with (size, ...params), |
| + // for an appropriate size provided externally to method initialize. |
| + this.generator = generator; |
| + // The list of transformation functions, excluding false ones. |
| + this.transformations = transformations.filter(f => f !== false); |
| + // The optional parameters to be passed to the generator function. |
| + this.params = params; |
| + } |
| + // Returns how many tests this test generator is expected to yield |
| + // in a row. |
| + weight() { |
| + return this.multiplicity * this.transformations.length; |
| + } |
| + // Initialize the generator function. |
| + initialize(size) { |
| + this.factory = this.generator(size, ...this.params); |
| + } |
| + // Is the test generator exhausted? |
| + exhausted() { |
| + return this.factory === null; |
| + } |
| + // Return a generator that will yield up to weight tests. |
| + // It returns an Iterator<OtherType>. |
| + * [Symbol.iterator]() { |
| + for (let i = 0; i < this.multiplicity; i++) { |
| + let element = this.factory.next(); |
| + if (element.done) { |
| + this.factory = null; |
| + return; |
| + } |
| + for (let f of this.transformations) yield f(element.value); |
| + } |
| + } |
| +} |
| + |
| +// Parameters: |
| +// size: positive integer |
| +// generators: [false | string | TestGen] |
| +// |
| +// This generator function will yield up to size tests. It will iterate |
| +// cyclically through the list of test generators. A string in this list |
| +// behaves as a simple generator yielding just one test; a false value |
| +// behaves as a generator yielding nothing. For every test generator in |
| +// the list, this function will generate as many tests as its weight |
| +// before proceeding to the next test generator. Once a generator is |
| +// exhausted, it is ignored in subsequent iterations. |
| +function* Generate(size, generators) { |
| + let fixed = 0, flexible = 0; |
| + for (let gen of generators) { |
| + if (gen === false) continue; |
| + if (typeof gen === "string") fixed++; |
| + else flexible += gen.weight(); |
| + } |
| + if (fixed + flexible == 0) throw "Empty list of test generators"; |
| + let remaining = 0; |
| + for (let gen of generators) { |
| + if (gen === false) continue; |
| + if (typeof gen !== "string") { |
| + let weight = 1 + gen.weight(); |
| + gen.initialize(Math.ceil(size * weight / flexible)); |
| + remaining++; |
| + } |
| + } |
| + for (let once = true; true; once = false) { |
| + if (remaining == 0) return; |
| + for (let gen of generators) { |
| + if (gen === false) continue; |
| + if (typeof gen === "string") { |
| + if (once) { |
| + if (size-- <= 0) return; else yield gen; |
| + } |
| + continue; |
| + } |
| + if (gen.exhausted()) continue; |
| + for (let test of gen) { |
| + if (size-- <= 0) return; else yield test; |
| + } |
| + if (gen.exhausted()) remaining--; |
| + } |
| + } |
| +} |
| + |
| +// Parameters: |
| +// size: positive integer |
| +// generators: [string | TestGen] |
| +// |
| +// This function will generate all tests yielded by Generate and will |
| +// discard the results. It will normally be called with test generators |
| +// whose transformation functions test for validity (e.g. CheckValid or |
| +// CheckInvalid) and do not return anything interesting. |
| +function Test(size, generators) { |
| + for (let attempt of Generate(size, generators)) continue; |
| +} |