class Identity
Represents a unique identity for a test or context, used for identification and location tracking.
Definitions
def self.file(parent, path, name = path, **options)
Create an identity for a file.
Signature
-
parameter
parentIdentity, nil The parent identity.
-
parameter
pathString The file path.
-
parameter
nameString The name (defaults to path).
-
parameter
optionsHash Additional options.
-
returns
Identity A new Identity instance.
Implementation
def self.file(parent, path, name = path, **options)
self.new(path, name, nil, nil, **options)
end
def self.nested(parent, name, location = nil, **options)
Create a nested identity.
Signature
-
parameter
parentIdentity, nil The parent identity.
-
parameter
nameString The name of this identity.
-
parameter
locationThread::Backtrace::Location, nil Optional location (defaults to caller location).
-
parameter
optionsHash Additional options.
-
returns
Identity A new Identity instance.
Implementation
def self.nested(parent, name, location = nil, **options)
location ||= caller_locations(3...4).first
self.new(location.path, name, location.lineno, parent, **options)
end
def self.current
Create an identity for the current location.
Signature
-
returns
Identity A new Identity instance for the current caller location.
Implementation
def self.current
self.nested(nil, nil, caller_locations(1...2).first)
end
def initialize(path, name = nil, line = nil, parent = nil, unique: true)
Initialize a new Identity.
Signature
-
parameter
pathString The file path.
-
parameter
nameString, nil Optional name.
-
parameter
lineInteger, nil Optional line number.
-
parameter
parentIdentity, nil Optional parent identity.
-
parameter
uniqueBoolean, Symbol Whether this identity is unique or needs a unique key/line number suffix.
Implementation
def initialize(path, name = nil, line = nil, parent = nil, unique: true)
@path = path
@name = name
@line = line
@parent = parent
@unique = unique
@key = nil
end
def with_line(line)
Create a new identity with a different line number.
Signature
-
parameter
lineInteger The line number.
-
returns
Identity A new Identity instance.
Implementation
def with_line(line)
self.class.new(@path, @name, line, @parent, unique: @unique)
end
attr :path
Signature
-
attribute
String The file path.
attr :name
Signature
-
attribute
String, nil The name.
attr :line
Signature
-
attribute
Integer, nil The line number.
attr :parent
Signature
-
attribute
Identity, nil The parent identity.
attr :unique
Signature
-
attribute
Boolean, Symbol Whether this identity is unique.
def to_s
Signature
-
returns
String A string representation of this identity (the key).
Implementation
def to_s
self.key
end
def to_location
Signature
-
returns
Hash A hash containing the path and line number.
Implementation
def to_location
{
path: ::File.expand_path(@path),
line: @line,
}
end
def inspect
Signature
-
returns
String An inspect representation of this identity.
Implementation
def inspect
"\#<#{self.class} #{self.to_s}>"
end
def match?(other)
Check if this identity matches another.
Signature
-
parameter
otherIdentity The identity to match against.
-
returns
Boolean Whether the identities match.
Implementation
def match?(other)
if path = other.path
return false unless path === @path
end
if name = other.name
return false unless name === @name
end
if line = other.line
return false unless line === @line
end
end
def each(&block)
Iterate over this identity and all its parents.
Signature
-
yields
{|identity| ...} Each identity in the chain.
Implementation
def each(&block)
@parent&.each(&block)
yield self
end
def key
Signature
-
returns
String A unique key for this identity.
Implementation
def key
unless @key
key = Array.new
# For a specific leaf node, the last part is not unique, i.e. it must be identified explicitly.
append_unique_key(key, @unique == true ? false : @unique)
@key = key.join(":")
end
return @key
end
def scoped(locations = nil)
Given a set of locations, find the first one which matches this identity and return a new identity with the updated line number. This can be used to extract a location from a backtrace.
Signature
-
parameter
locationsArray(Thread::Backtrace::Location), nil Optional locations to search (defaults to caller locations).
-
returns
Identity A new identity with updated line number if a match is found, otherwise returns self.
Implementation
def scoped(locations = nil)
if locations
# This code path is normally taken if we've got an exception with a backtrace:
locations.each do |location|
if location.path == @path
return self.with_line(location.lineno)
end
end
else
# In theory this should be a bit faster:
Thread.each_caller_location do |location|
if location.path == @path
return self.with_line(location.lineno)
end
end
end
return self
end