1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
# frozen_string_literal: true
require 'forwardable'
require 'cucumber/core/platform'
require 'set'
module Cucumber
module Core
module Test
IncompatibleLocations = Class.new(StandardError)
module Location
def self.of_caller(additional_depth = 0)
from_file_colon_line(*caller[1 + additional_depth])
end
def self.from_file_colon_line(file_colon_line)
file, raw_line = file_colon_line.match(/(.*):(\d+)/)[1..2]
from_source_location(file, raw_line.to_i)
end
def self.from_source_location(file, line, *_args)
file = File.expand_path(file)
pwd = File.expand_path(Dir.pwd)
pwd.force_encoding(file.encoding)
if file.index(pwd)
file = file[(pwd.length + 1)..]
elsif file.match?(/gems\/(.+\.rb)$/)
file = file.split('gems/').last
end
new(file, line)
end
def self.new(file, raw_lines = nil)
if raw_lines
Precise.new(file, Lines.new(raw_lines))
else
Wildcard.new(file)
end
end
Wildcard = Struct.new(:file) do
def to_s
file
end
def match?(other)
other.file == file
end
def include?(_lines)
true
end
end
Precise = Struct.new(:file, :lines) do
def include?(other_lines)
lines.include?(other_lines)
end
def line
lines.first
end
def match?(other)
return false unless other.file == file
other.include?(lines)
end
def to_s
[file, lines.to_s].join(':')
end
def hash
[self.class, to_s].hash
end
def to_str
to_s
end
def merge(multiline_arg)
new_lines = (0..multiline_arg.lines_count).map do |offset|
lines.min + offset
end
Location.new(file, new_lines)
end
def on_line(new_line)
Location.new(file, new_line)
end
def inspect
"<#{self.class}: #{self}>"
end
end
Lines = Struct.new(:data) do
protected :data
def initialize(raw_data)
super(Array(raw_data).to_set)
end
def first
data.first
end
def min
data.min
end
def max
data.max
end
def include?(other)
other.data.subset?(data) || data.subset?(other.data)
end
def +(other)
new_data = data + other.data
self.class.new(new_data)
end
def to_s
return first.to_s if data.length == 1
return "#{data.min}..#{data.max}" if range?
data.to_a.join(':')
end
def inspect
"<#{self.class}: #{self}>"
end
protected
def range?
data.size == (data.max - data.min + 1)
end
end
end
module HasLocation
def file_colon_line
location.to_s
end
def file
location.file
end
def line
location.line
end
def location
raise('Please set @location in the constructor') unless defined?(@location)
@location
end
def attributes
[tags, comments, multiline_arg].flatten
end
def tags
# will be overridden by nodes that actually have tags
[]
end
def comments
# will be overridden by nodes that actually have comments
[]
end
def multiline_arg
# will be overridden by nodes that actually have a multiline_argument
Test::EmptyMultilineArgument.new
end
end
end
end
end
|