Class: Megatest::State::TestSuite

Inherits:
Suite
  • Object
show all
Defined in:
lib/megatest/state.rb

Overview

A test suite is a group of tests. It’s a class that inherits Megatest::Test A test case is the smaller runable unit, it’s a block defined with ‘test` or a method with a name starting with `test_`.

Instance Attribute Summary collapse

Attributes inherited from Suite

#around_callbacks, #setup_callbacks, #teardown_callbacks

Instance Method Summary collapse

Methods inherited from Suite

#add_tags, #build_test_case, #on_around, #on_setup, #on_teardown, #own_tags, #tag?, #with_context

Constructor Details

#initialize(registry, test_suite, location) ⇒ TestSuite

Returns a new instance of TestSuite.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/megatest/state.rb', line 114

def initialize(registry, test_suite, location)
  super(registry)
  @klass = test_suite
  @source_file, @source_line = location
  @ancestors = nil
  @test_cases = if test_suite.is_a?(Class) && test_suite.superclass < ::Megatest::Test
    registry.suite(test_suite.superclass).test_cases.to_h do |t|
      test = t.inherited_by(self)
      [test, test]
    end
  else
    {}
  end
  @test_cases.each_key do |test|
    @registry.register_test_case(test)
  end
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass.



112
113
114
# File 'lib/megatest/state.rb', line 112

def klass
  @klass
end

#source_fileObject (readonly)

Returns the value of attribute source_file.



112
113
114
# File 'lib/megatest/state.rb', line 112

def source_file
  @source_file
end

#source_lineObject (readonly)

Returns the value of attribute source_line.



112
113
114
# File 'lib/megatest/state.rb', line 112

def source_line
  @source_line
end

Instance Method Details

#add_test(test) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/megatest/state.rb', line 199

def add_test(test)
  if duplicate = @test_cases[test]
    # It was late defined in an parent class we can just ignore it.
    return test if test.inherited?

    if duplicate.inherited?
      @test_cases.delete(duplicate)
      @registry.remove_test_case(duplicate)
    else
      # If the pre-existing test wasn't inherited, it means we're defining the
      # same test twice, that's a mistake.
      raise AlreadyDefinedError,
            "`#{test.id}` already defined at #{Megatest.relative_path(test.source_file)}:#{test.source_line}"
    end
  end

  @test_cases[test] = test
  @registry.register_test_case(test)
  test
end

#ancestorsObject



154
155
156
# File 'lib/megatest/state.rb', line 154

def ancestors
  @ancestors ||= @registry.ancestors(@klass)
end

#fixed_source_locationObject



180
181
182
183
184
185
186
187
# File 'lib/megatest/state.rb', line 180

def fixed_source_location
  Thread.each_caller_location do |location|
    if location.path == @source_file
      return [location.path, location.lineno]
    end
  end
  nil
end

#include_test_case(test_case, include_location) ⇒ Object



224
225
226
# File 'lib/megatest/state.rb', line 224

def include_test_case(test_case, include_location)
  add_test(test_case.included_by(self, include_location))
end

#inherit_test_case(test_case) ⇒ Object



220
221
222
# File 'lib/megatest/state.rb', line 220

def inherit_test_case(test_case)
  add_test(test_case.inherited_by(self))
end

#register_test_case(name, callable, tags) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/megatest/state.rb', line 162

def register_test_case(name, callable, tags)
  source_location = callable.source_location
  if !shared? && source_location[0] != @source_file
    # When a test class is reopened from a different file, or when a test is defined
    # using some sort of class method macro, the resulting `source_file` doesn't match
    # the test suite, hence can't be used to point to the test as it would
    # have a `source_file` that can't be used to run a single test file.
    #
    # So we need some work to try to figure out the actual test definition location,
    # and if we really can't, then we fallback to the suite location.
    source_location = fixed_source_location || [@source_file, @source_line]
  end

  test = build_test_case(name, callable, tags, source_location)
  add_test(test)
end

#shared?Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/megatest/state.rb', line 150

def shared?
  false
end

#tag(name) ⇒ Object



139
140
141
142
143
144
145
146
147
148
# File 'lib/megatest/state.rb', line 139

def tag(name)
  if @tags&.key?(name)
    @tags[name]
  else
    ancestors.each do |ancestor|
      return ancestor.tag(name) if ancestor.tag?(name)
    end
    nil
  end
end

#tagsObject



132
133
134
135
136
137
# File 'lib/megatest/state.rb', line 132

def tags
  tags = {}
  tags.merge!(*ancestors.reverse.map(&:own_tags).compact)
  tags.merge!(@tags) if @tags
  tags
end

#test_casesObject



158
159
160
# File 'lib/megatest/state.rb', line 158

def test_cases
  @test_cases.keys
end