| OLD | NEW |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Flags: --allow-natives-syntax --no-always-opt | 5 // Flags: --allow-natives-syntax --no-always-opt |
| 6 | 6 |
| 7 // Test precise code coverage. | 7 // Test precise code coverage. |
| 8 | 8 |
| 9 function GetCoverage(source) { | 9 function GetCoverage(source) { |
| 10 for (var script of %DebugCollectCoverage()) { | 10 for (var script of %DebugCollectCoverage()) { |
| 11 if (script.script.source == source) return script.toplevel; | 11 if (script.script.source == source) return script; |
| 12 } | 12 } |
| 13 return undefined; | 13 return undefined; |
| 14 } | 14 } |
| 15 | 15 |
| 16 function ApplyCoverageToSource(source, range) { | |
| 17 var content = ""; | |
| 18 var cursor = range.start; | |
| 19 if (range.inner) for (var inner of range.inner) { | |
| 20 content += source.substring(cursor, inner.start); | |
| 21 content += ApplyCoverageToSource(source, inner); | |
| 22 cursor = inner.end; | |
| 23 } | |
| 24 content += source.substring(cursor, range.end); | |
| 25 return `[${content}](${range.name}:${range.count})`; | |
| 26 } | |
| 27 | |
| 28 function TestCoverage(name, source, expectation) { | 16 function TestCoverage(name, source, expectation) { |
| 29 source = source.trim(); | 17 source = source.trim(); |
| 30 eval(source); | 18 eval(source); |
| 31 %CollectGarbage("remove dead objects"); | 19 %CollectGarbage("collect dead objects"); |
| 32 var coverage = GetCoverage(source); | 20 var coverage = GetCoverage(source); |
| 33 if (expectation === undefined) { | 21 var result = JSON.stringify(coverage); |
| 34 assertEquals(undefined, coverage); | 22 print(result); |
| 35 } else { | 23 assertEquals(JSON.stringify(expectation), result, name + " failed"); |
| 36 expectation = expectation.trim(); | |
| 37 var result = ApplyCoverageToSource(source, coverage); | |
| 38 print(result); | |
| 39 assertEquals(expectation, result, name + " failed"); | |
| 40 } | |
| 41 } | 24 } |
| 42 | 25 |
| 43 | |
| 44 // Without precise coverage enabled, we lose coverage data to the GC. | 26 // Without precise coverage enabled, we lose coverage data to the GC. |
| 45 TestCoverage( | 27 TestCoverage( |
| 46 "call an IIFE", | 28 "call an IIFE", |
| 47 ` | 29 ` |
| 48 (function f() {})(); | 30 (function f() {})(); |
| 49 `, | 31 `, |
| 50 undefined // The IIFE has been garbage-collected. | 32 undefined // The IIFE has been garbage-collected. |
| 51 ); | 33 ); |
| 52 | 34 |
| 53 TestCoverage( | 35 TestCoverage( |
| 54 "call locally allocated function", | 36 "call locally allocated function", |
| 55 ` | 37 ` |
| 56 for (var i = 0; i < 10; i++) { | 38 for (var i = 0; i < 10; i++) { |
| 57 let f = () => 1; | 39 let f = () => 1; |
| 58 i += f(); | 40 i += f(); |
| 59 } | 41 } |
| 60 `, | 42 `, |
| 61 undefined | 43 undefined |
| 62 ); | 44 ); |
| 63 | 45 |
| 64 // This does not happen with precise coverage enabled. | 46 // This does not happen with precise coverage enabled. |
| 65 %DebugTogglePreciseCoverage(true); | 47 %DebugTogglePreciseCoverage(true); |
| 66 | 48 |
| 67 TestCoverage( | 49 TestCoverage( |
| 68 "call an IIFE", | 50 "call an IIFE", |
| 69 ` | 51 ` |
| 70 (function f() {})(); | 52 (function f() {})(); |
| 71 `, | 53 `, |
| 72 ` | 54 [{"start":0,"end":20,"count":1},{"start":1,"end":16,"count":1}] |
| 73 [([function f() {}](f:1))();](:1) | |
| 74 ` | |
| 75 ); | 55 ); |
| 76 | 56 |
| 77 TestCoverage( | 57 TestCoverage( |
| 78 "call locally allocated function", | 58 "call locally allocated function", |
| 79 ` | 59 ` |
| 80 for (var i = 0; i < 10; i++) { | 60 for (var i = 0; i < 10; i++) { |
| 81 let f = () => 1; | 61 let f = () => 1; |
| 82 i += f(); | 62 i += f(); |
| 83 } | 63 } |
| 84 `, | 64 `, |
| 85 ` | 65 [{"start":0,"end":63,"count":1},{"start":41,"end":48,"count":5}] |
| 86 [for (var i = 0; i < 10; i++) { | |
| 87 let f = [() => 1](f:5); | |
| 88 i += f(); | |
| 89 }](:1) | |
| 90 ` | |
| 91 ); | 66 ); |
| 92 | 67 |
| 93 %DebugTogglePreciseCoverage(false); | 68 %DebugTogglePreciseCoverage(false); |
| OLD | NEW |