lib/asciidoctor/doctest/example.rb
# frozen_string_literal: false
require 'corefines'
using Corefines::Object[:blank?, :deep_dup, :instance_values]
module Asciidoctor
module DocTest
##
# This class represents a single test example.
class Example
NAME_SEPARATOR = ':'
# @return [String] the first part of the name.
attr_accessor :group_name
# @return [String] the second part of the name.
attr_accessor :local_name
# @return [String] raw content.
attr_accessor :content
# @return [String] description.
attr_accessor :desc
# @return [Hash] options.
attr_accessor :opts
##
# @param name (see #name=)
# @param content [String]
# @param desc [String] description
# @param opts [Hash] options
#
def initialize(name, content: '', desc: '', opts: {})
self.name = name
@content = content
@desc = desc
@opts = opts
end
##
# @return [String] the name in format +group_name:local_name+.
def name
[@group_name, @local_name].join(NAME_SEPARATOR)
end
##
# @param name [String, Array<String>] a String in format
# +group_name:local_name+, or an Array with the group_name and the
# local_name.
def name=(*name)
name.flatten!
@group_name, @local_name = name.one? ? name.first.split(NAME_SEPARATOR, 2) : name
end
##
# @param pattern [String] the glob pattern (e.g. +inline_*:with*+).
# @return [Boolean] +true+ if the name matches against the +pattern+,
# +false+ otherwise.
def name_match?(pattern)
globs = pattern.split(NAME_SEPARATOR, 2)
[group_name, local_name].zip(globs).all? do |name, glob|
File.fnmatch? glob || '*', name.to_s
end
end
##
# Returns value(s) of the named option.
#
# @param name [#to_sym] the option name.
# @return [Array<String>, Boolean] the option value.
#
def [](name)
@opts[name.to_sym]
end
##
# Sets or unsets the option.
#
# @param name [#to_sym] the option name.
# @param value [Array<String>, Boolean, String, nil] the option value;
# +Array+ and +Boolean+ are just assigned to the option, +nil+
# removes the option and others are added to the option as an
# array item.
#
def []=(name, value)
case value
when nil
@opts.delete(name.to_sym)
when Array, TrueClass, FalseClass
@opts[name.to_sym] = value.deep_dup
else
(@opts[name.to_sym] ||= []) << value.dup
end
end
##
# @return [Boolean] +true+ when the content is blank, +false+ otherwise.
def empty?
content.blank?
end
##
# @return [String] a copy of the content.
def to_s
content.dup
end
##
# @param other the object to compare with.
# @return [Boolean] +true+ if +self+ and +other+ equals in attributes
# +group_name+, +local_name+ and +content+ (compared using +==+),
# otherwise +false+.
def ==(other)
[:group_name, :local_name, :content].all? do |name|
other.respond_to?(name) &&
public_send(name) == other.public_send(name)
end
end
##
# @param other [Object] the object to compare with.
# @return [Boolean] +true+ if +self+ and +other+ are instances of the same
# class and all their attributes are equal (compared using +==+),
# otherwise +false+.
def eql?(other)
self.class == other.class &&
instance_values == other.instance_values
end
# :nocov:
def hash
self.class.hash ^ instance_values.hash
end
# :nocov:
private
def initialize_copy(source)
instance_variables.each do |name|
instance_variable_set name, instance_variable_get(name).deep_dup
end
end
end
end
end