OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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 var debug = false; |
| 6 |
| 7 function CheckValid(type) { |
| 8 if (debug) { print("V:", type); } |
| 9 assertDoesNotThrow("'use types'; var x: " + type + ";"); |
| 10 } |
| 11 |
| 12 function CheckInvalid(type) { |
| 13 if (debug) { print("I:", type); } |
| 14 assertThrows("'use types'; var x: " + type + ";", SyntaxError); |
| 15 } |
| 16 |
| 17 // Parameters: |
| 18 // multiplicity: positive integer |
| 19 // generator: (size: positive integer, ...params: any[]) => Iterator<SomeType> |
| 20 // transformations: [false | ((t: SomeType) => OtherType)] |
| 21 // params: any[] |
| 22 // |
| 23 // A "test generator" object will have its "generator" generate tests, |
| 24 // will transform each generated test with all of its "transformations" |
| 25 // and will yield the results. false transformations will be ignored. |
| 26 class TestGen { |
| 27 constructor(multiplicity, generator, transformations, ...params) { |
| 28 // Determines how often this generator will run, compared to other ones. |
| 29 this.multiplicity = multiplicity; |
| 30 // The generator function. It will be called with (size, ...params), |
| 31 // for an appropriate size provided externally to method initialize. |
| 32 this.generator = generator; |
| 33 // The list of transformation functions, excluding false ones. |
| 34 this.transformations = transformations.filter(f => f !== false); |
| 35 // The optional parameters to be passed to the generator function. |
| 36 this.params = params; |
| 37 } |
| 38 // Returns how many tests this test generator is expected to yield |
| 39 // in a row. |
| 40 weight() { |
| 41 return this.multiplicity * this.transformations.length; |
| 42 } |
| 43 // Initialize the generator function. |
| 44 initialize(size) { |
| 45 this.factory = this.generator(size, ...this.params); |
| 46 } |
| 47 // Is the test generator exhausted? |
| 48 exhausted() { |
| 49 return this.factory === null; |
| 50 } |
| 51 // Return a generator that will yield up to weight tests. |
| 52 // It returns an Iterator<OtherType>. |
| 53 * [Symbol.iterator]() { |
| 54 for (let i = 0; i < this.multiplicity; i++) { |
| 55 let element = this.factory.next(); |
| 56 if (element.done) { |
| 57 this.factory = null; |
| 58 return; |
| 59 } |
| 60 for (let f of this.transformations) yield f(element.value); |
| 61 } |
| 62 } |
| 63 } |
| 64 |
| 65 // Parameters: |
| 66 // size: positive integer |
| 67 // generators: [false | string | TestGen] |
| 68 // |
| 69 // This generator function will yield up to size tests. It will iterate |
| 70 // cyclically through the list of test generators. A string in this list |
| 71 // behaves as a simple generator yielding just one test; a false value |
| 72 // behaves as a generator yielding nothing. For every test generator in |
| 73 // the list, this function will generate as many tests as its weight |
| 74 // before proceeding to the next test generator. Once a generator is |
| 75 // exhausted, it is ignored in subsequent iterations. |
| 76 function* Generate(size, generators) { |
| 77 let fixed = 0, flexible = 0; |
| 78 for (let gen of generators) { |
| 79 if (gen === false) continue; |
| 80 if (typeof gen === "string") fixed++; |
| 81 else flexible += gen.weight(); |
| 82 } |
| 83 if (fixed + flexible == 0) throw "Empty list of test generators"; |
| 84 let remaining = 0; |
| 85 for (let gen of generators) { |
| 86 if (gen === false) continue; |
| 87 if (typeof gen !== "string") { |
| 88 let weight = 1 + gen.weight(); |
| 89 gen.initialize(Math.ceil(size * weight / flexible)); |
| 90 remaining++; |
| 91 } |
| 92 } |
| 93 for (let once = true; true; once = false) { |
| 94 if (remaining == 0) return; |
| 95 for (let gen of generators) { |
| 96 if (gen === false) continue; |
| 97 if (typeof gen === "string") { |
| 98 if (once) { |
| 99 if (size-- <= 0) return; else yield gen; |
| 100 } |
| 101 continue; |
| 102 } |
| 103 if (gen.exhausted()) continue; |
| 104 for (let test of gen) { |
| 105 if (size-- <= 0) return; else yield test; |
| 106 } |
| 107 if (gen.exhausted()) remaining--; |
| 108 } |
| 109 } |
| 110 } |
| 111 |
| 112 // Parameters: |
| 113 // size: positive integer |
| 114 // generators: [string | TestGen] |
| 115 // |
| 116 // This function will generate all tests yielded by Generate and will |
| 117 // discard the results. It will normally be called with test generators |
| 118 // whose transformation functions test for validity (e.g. CheckValid or |
| 119 // CheckInvalid) and do not return anything interesting. |
| 120 function Test(size, generators) { |
| 121 for (let attempt of Generate(size, generators)) continue; |
| 122 } |
OLD | NEW |