github.com/go-maxhub/gremlins@v1.0.1-0.20231227222204-b03a6a1e3e09/core/coverage/profile.go (about) 1 /* 2 * Copyright 2022 The Gremlins Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package coverage 18 19 import ( 20 "go/token" 21 ) 22 23 // Profile is implemented as a map holding a slice of Block per each filename. 24 type Profile map[string][]Block 25 26 // IsCovered checks if the given token.Position is covered by the coverage Profile. 27 func (p Profile) IsCovered(pos token.Position) bool { 28 blocks, ok := p[pos.Filename] 29 if !ok { 30 return false 31 } 32 for _, b := range blocks { 33 if b.isBetweenLines(pos) { 34 return true 35 } 36 if covered := b.isPositionCovered(pos); covered { 37 return true 38 } 39 } 40 41 return false 42 } 43 44 // Block holds the start and end coordinates of a section of a source file 45 // covered by tests. 46 type Block struct { 47 StartLine int 48 StartCol int 49 EndLine int 50 EndCol int 51 } 52 53 func (b Block) isPositionCovered(pos token.Position) bool { 54 if b.isSingleLine() && b.isOnFirstLine(pos) && b.isSingleLineColCovered(pos) { 55 return true 56 } 57 if b.isMultiLine() && b.isOnFirstLine(pos) && b.isCoveredToEndOfLine(pos) { 58 return true 59 } 60 if b.isMultiLine() && b.isOnLastLine(pos) && b.isCoveredFromStartOfLine(pos) { 61 return true 62 } 63 64 return false 65 } 66 67 func (b Block) isSingleLine() bool { 68 return b.StartLine == b.EndLine 69 } 70 71 func (b Block) isMultiLine() bool { 72 return b.StartLine < b.EndLine 73 } 74 75 func (b Block) isOnFirstLine(pos token.Position) bool { 76 return pos.Line == b.StartLine 77 } 78 79 func (b Block) isOnLastLine(pos token.Position) bool { 80 return pos.Line == b.EndLine 81 } 82 83 func (b Block) isBetweenLines(pos token.Position) bool { 84 return pos.Line > b.StartLine && pos.Line < b.EndLine 85 } 86 87 func (b Block) isSingleLineColCovered(pos token.Position) bool { 88 return pos.Column >= b.StartCol && pos.Column <= b.EndCol 89 } 90 91 func (b Block) isCoveredToEndOfLine(pos token.Position) bool { 92 return pos.Column >= b.StartCol 93 } 94 func (b Block) isCoveredFromStartOfLine(pos token.Position) bool { 95 return pos.Column <= b.EndCol 96 }