Class: YARD::TaggedTestCaseHandler

Inherits:
Handlers::Ruby::Base
  • Object
show all
Defined in:
lib/yard/tagged_test_case_handler.rb

Overview

Intercept all tagged test case definitions in order to document test case taggings automatically.

Instance Method Summary collapse

Instance Method Details

#processObject

Process the method call to ‘test do … end` as a dynamic method definition.



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
# File 'lib/yard/tagged_test_case_handler.rb', line 13

def process
  # Retrieve the currently-active statement and its parameters
  stmt   = self.statement
  params = stmt.parameters

  # Move the AST pointer to the first parameter that is either a string or
  # an identifier (e.g., inner symbol)
  name = params.first.jump(:tstring_content, :ident).source

  # Create a new method object in the namespace with the correct name
  object = YARD::CodeObjects::MethodObject.new(self.namespace, "test_#{name}")

  # Parse the block between the `test do` and `end` and attribute it to the
  # method object above
  self.parse_block(stmt.last.last, owner: object)

  # Annotate it as a dynamic object with custom attributes
  object.dynamic = true

  # The options s-exp looks like:
  #
  #   s(s(:assoc, s(:label, 'Key1'), s(...)),
  #     s(:assoc, s(:label, 'Key2'), s(...))
  #   )
  #
  # if one exists (nil otherwise)
  if opts_sexp = params[1]
    object['test_case_attrs'] = opts_sexp.inject(Hash.new) do |hsh, kv|
      key_sexp, value_sexp = kv.jump(:assoc)

      if (string_sexp = value_sexp.jump(:tstring_content)) && (string_sexp.type == :tstring_content)
        hsh[key_sexp.first] = string_sexp.first
      elsif (array_sexp = value_sexp.jump(:array)) && (array_sexp.type == :array)
        hsh[key_sexp.first] = array_sexp.first.map { |sexp| sexp.jump(:tstring_content, :ident).first }
      else
        raise ArgumentError, "Cannot parse and render: #{kv.inspect}"
      end

      hsh
    end
  end

  # Register the object
  self.register(object)
end