class FitnesseNode

@attr_reader [FitnesseRoot] root The root of the Fitnesse tree of which this node is a part. @attr_reader [FitnesseNode,FitnesseRoot] parent The parent of this node (which may be the root object) @attr_reader [Array<FitnesseNode>] children The child nodes of this node. @attr_reader [Pathname] path The path of this node’s folder. @attr_reader [Array<String>] path_as_array The path relative to the root, as an array of strings. @attr_reader [String] name The name of this node. This is the “short” name of the node itself, not the fully qualified name. @attr_reader [Rexml::Document] properties The properties XML document of this node. @attr_reader [SortedSet<String>] explicit_tags The set of tags that have been explicitly set on this node.

Attributes

children[R]
explicit_tags[R]
name[R]
parent[R]
path[R]
path_as_array[R]
properties[R]
root[R]

Public Class Methods

new(root, parent, name) click to toggle source
# File lib/fitquery/fitnesse_node.rb, line 23
def initialize(root, parent, name)
  @root = root
  @parent = parent
  @children = {}
  @is_root = name == :root
  @name = name.to_s
  @path = name == :root ? parent.path : Pathname.new(parent.path.join(name))
  @path_as_array = []
  @path.relative_path_from(@root.path).descend{|partial| @path_as_array.push(partial.basename.to_s)}

  begin
    File.open(@path.join('properties.xml'), 'r') {|f| @properties = REXML::Document.new f     }
  rescue
    @properties = nil
  end
  begin
    tags_element = @properties.get_elements('/properties/Suites')
    unless tags_element.nil?
      @explicit_tags = SortedSet.new(tags_element.first.text.split(',').map{|tag| tag.strip })
    end
  rescue
    @explicit_tags = SortedSet.new([])
  end
  @path.children.each do |sub|
    next unless sub.directory?
    rel_path = sub.relative_path_from(@root.path)
    next if @root.blacklist.any? {|blacklisted| rel_path.fnmatch?(blacklisted) }
    child_node = FitnesseNode.new(@root, self, sub.basename)
    @children[child_node.name] = child_node unless child_node.nil?
  end
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/fitquery/fitnesse_node.rb, line 205
def <=>(other)
  if depth == other.depth
    name <=> other.name
  else
    depth <=> other.depth
  end
end
content() click to toggle source

Get the content of the node. Uses lazy loading to avoid slowing down the initial parsing of the tree.

# File lib/fitquery/fitnesse_node.rb, line 193
def content
  @content ||= IO::read(@path.join('content.txt'))
end
depth() click to toggle source

Gets the depth of this node, i.e. the number of levels down the tree from the root node. @return [Integer] The depth of the node

# File lib/fitquery/fitnesse_node.rb, line 127
def depth
  @path_as_array.length
end
dotted_name() click to toggle source
# File lib/fitquery/fitnesse_node.rb, line 121
def dotted_name
  full_name('.')
end
each(&block) click to toggle source

Yield this node and its children.

# File lib/fitquery/fitnesse_node.rb, line 68
def each(&block)
  traverse(:pre, &block)
end
effective_tags() click to toggle source

Determines the set of tags that are set on this node or any of its ancestors. @return [SortedSet<String>] The set of tags that apply to this node.

# File lib/fitquery/fitnesse_node.rb, line 91
def effective_tags
  if @parent.respond_to?(:effective_tags)
    @parent.effective_tags + @explicit_tags
  else
    @explicit_tags
  end
end
effectively_skipped?() click to toggle source

@return [Boolean] Does this node have the Prune property set on it or on any of its ancestors?

# File lib/fitquery/fitnesse_node.rb, line 105
def effectively_skipped?
  if @parent.respond_to?(:effectively_skipped?)
    @parent.effectively_skipped? || explicitly_skipped?
  else
    explicitly_skipped?
  end
end
explicitly_skipped?() click to toggle source

@return [Boolean] Does this node have the Prune property explicitly set on it?

# File lib/fitquery/fitnesse_node.rb, line 100
def explicitly_skipped?
  @properties.nil? ? false : (@properties.get_elements('/properties/Prune').count > 0)
end
find() { |self| ... } click to toggle source

Yield this node and its children, but provides a way to stop further recursion down this node’s branch of the tree. @example Ignore all nodes that are the children of a node which is marked as skipped.

start_node.find {|node|
  Find.prune if node.explicitly_skipped?
  # only gets to here if none of the current node's ancestors have been skipped.
}
# File lib/fitquery/fitnesse_node.rb, line 78
def find(&block)
  catch(:prune) do
    yield self
    unless @children.nil?
      @children.each_value do |child|
        child.find(&block)
      end
    end
  end
end
full_name(sep = nil) click to toggle source

Gets the fully qualified name of this node. @param sep [String] Sets the preferred separator string for the name. If nil, the name will use the system default file path separator. @return [String] The fully qualified name of the node, consisting of the names of each node in the tree leading to this one.

# File lib/fitquery/fitnesse_node.rb, line 116
def full_name(sep = nil)
  separator = sep.nil? ? File::SEPARATOR : sep
  @path_as_array.join(separator)
end
has_tag?(tag, explicit_only = false) click to toggle source

Determine whether this node has a particular tag on it. @param tag [String,Regexp] The tag to find. If a string, the search will be case insensitive.

If a regular expression is used, the regex's case sensitivity flag will be respected.

@param explicit_only [Boolean] Specify whether to search within the explicit tags or the effective tags of this node.

# File lib/fitquery/fitnesse_node.rb, line 167
def has_tag?(tag, explicit_only = false)
  tag_set = explicit_only ? explicit_tags : effective_tags
  if tag.instance_of?(Regexp)
    pattern = tag
  elsif tag.instance_of?(String)
    pattern = /^#{tag}$/i
  end
  tag_set.any? {|t| t.match(pattern) }
end
indented_name(indent_string = ' ') click to toggle source

Gets the name of the node, prefixed with a number of characters determined by the node’s depth. Handy for displaying the node in a simple tree representation. @param indent_string [String] The string from which to construct the indentation. @return [String] The indented name. @example A node with a full name of ‘Root/Foo/Bar/Baz’

node.indented_name('-')  =>  '---Baz'
# File lib/fitquery/fitnesse_node.rb, line 137
def indented_name(indent_string = ' ')
  indent = indent_string * depth
  indent + @name.to_s
end
root?() click to toggle source
# File lib/fitquery/fitnesse_node.rb, line 197
def root?
  @is_root
end
runable?()
Alias for: runnable?
runnable?() click to toggle source

@return [Boolean] Is this node runnable? I.e. is it either a test or a suite which is not skipped?

# File lib/fitquery/fitnesse_node.rb, line 158
def runnable?
  !static? && !effectively_skipped? && (test? || suite?)
end
Also aliased as: runable?
set_tag(tag) click to toggle source

Set a new explicit tag on the node and write it to the properties file immediately. @param tag [String] The tag to add.

# File lib/fitquery/fitnesse_node.rb, line 179
def set_tag(tag)
  File.open(@path.join('properties.xml'), 'w') do |f|
    @explicit_tags.add(tag)
    suites_elements = @properties.get_elements('/properties/Suites')
    tags_element = suites_elements.empty? ? @properties.root.add_element('Suites') : suites_elements.first
    tags_element.text = @explicit_tags.to_a.join(', ')
    formatter = REXML::Formatters::Default.new
    formatter.write(@properties, f)
  end
rescue => ex
  STDERR.puts(ex.message)
end
static?() click to toggle source

@return [Boolean] Is this node defined as a Static page?

# File lib/fitquery/fitnesse_node.rb, line 153
def static?
  @properties.nil? ? false : (@properties.get_elements('/properties/Static').count > 0)
end
suite?() click to toggle source

@return [Boolean] Is this node defined as a Suite?

# File lib/fitquery/fitnesse_node.rb, line 148
def suite?
  @properties.nil? ? false : (@properties.get_elements('/properties/Suite').count > 0)
end
test?() click to toggle source

@return [Boolean] Is this node defined as a Test?

# File lib/fitquery/fitnesse_node.rb, line 143
def test?
  @properties.nil? ? false : (@properties.get_elements('/properties/Test').count > 0)
end
to_s() click to toggle source
# File lib/fitquery/fitnesse_node.rb, line 201
def to_s
  full_name
end
traverse(order = :pre) { |self| ... } click to toggle source

Yield this node and its children. @param order [Symbol] Use :pre to yield this node before its children, or :post to yield the children first.

# File lib/fitquery/fitnesse_node.rb, line 57
def traverse(order = :pre, &block)
  yield self if order == :pre
  unless @children.nil?
    @children.each_value do |child|
      child.traverse(&block)
    end
  end
  yield self if order == :post
end