Module: MRspec::DeclareMinitests

Extended by:
DeclareMinitests
Included in:
DeclareMinitests
Defined in:
lib/mrspec/declare_minitests.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.call(rspec, minitest, klasses) ⇒ Object



9
10
11
12
# File 'lib/mrspec/declare_minitests.rb', line 9

def self.call(rspec, minitest, klasses)
  init_minitest minitest
  wrap_classes rspec, klasses
end

Instance Method Details

#example_name(method_name) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/mrspec/declare_minitests.rb', line 23

def example_name(method_name)
  # remove test_, and turn underscores into spaces
  #   https://github.com/seattlerb/minitest/blob/f1081566ec6e9e391628bde3a26fb057ad2576a8/lib/minitest/test.rb#L62
  # remove test_0001_, where the number increments
  #   https://github.com/seattlerb/minitest/blob/f1081566ec6e9e391628bde3a26fb057ad2576a8/lib/minitest/spec.rb#L218-222
  method_name.to_s.sub(/^test_(?:\d{4}_)?/, '').tr('_', ' ')
end

#get_tests(klass) ⇒ Object



63
64
65
66
67
# File 'lib/mrspec/declare_minitests.rb', line 63

def get_tests(klass)
  klass.runnable_methods
       .map { |mname| [mname, *klass.instance_method(mname).source_location] }
       .sort_by { |name, file, line| line }
end

#group_name(klass) ⇒ Object



14
15
16
17
18
19
20
21
# File 'lib/mrspec/declare_minitests.rb', line 14

def group_name(klass)
  if klass.name
    klass.name.to_s.sub(/^Test/, '').sub(/Test$/, '')
  else
    inspection = Kernel.instance_method(:inspect).bind(klass).call
    "Anonymous Minitest for class #{inspection}"
  end
end

#init_minitest(minitest) ⇒ Object



31
32
33
34
35
# File 'lib/mrspec/declare_minitests.rb', line 31

def init_minitest(minitest)
  minitest.reporter = minitest::CompositeReporter.new # we're not using the reporter, but some plugins, (eg minitest/pride) expect it to be there
  minitest.load_plugins
  minitest.init_plugins minitest.process_args([])
end

#initial_metadata(tests, existing_metadat, offset) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/mrspec/declare_minitests.rb', line 69

def (tests, existing_metadat, offset)
  # There is a disagreement here:
  # In RSpec, each describe block is its own example group, so the group will
  # all be defined in the same file. In Minitest, the example group is a class,
  # which can be reopened, thus the group can exist in multiple files.
  # I'm just going to ignore it for now, but prob the right thing to do is
  # to split the test methods into groups based on what file they are defined
  # in, and then what class they are defined in (currently, it is only what
  # class they are defined in)
  #
  # Leaving mrspec stuff in the backtrace, though, that way if we can't
  # successfully guess the caller, then it's more helpful as someone tries
  # to figure out wtf happened
  guessed_caller_entry = nil
  tests
    .select { |name, file, line| file && line }
    .take(1)
    .each { |_, file, line| guessed_caller_entry = "#{file}:#{line+offset}" }

   = {}
  [:caller] = [guessed_caller_entry, *caller] if guessed_caller_entry
  .merge! existing_metadat

  
end

#wrap_class(rspec, klass) ⇒ Object



41
42
43
44
45
46
# File 'lib/mrspec/declare_minitests.rb', line 41

def wrap_class(rspec, klass)
  tests    = get_tests(klass)
   =  tests, klass., -1
  group    = rspec.describe group_name(klass), 
  tests.each { |mname, file, line| wrap_test group, klass, mname, file, line }
end

#wrap_classes(rspec, klasses) ⇒ Object



37
38
39
# File 'lib/mrspec/declare_minitests.rb', line 37

def wrap_classes(rspec, klasses)
  klasses.each { |klass| wrap_class rspec, klass }
end

#wrap_test(example_group, klass, mname, file, line) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/mrspec/declare_minitests.rb', line 48

def wrap_test(example_group, klass, mname, file, line)
   =  [[mname, file, line]],
                              klass.[mname.intern],
                              0

  example = example_group.example example_name(mname),  do
    instance = Minitest.run_one_method klass, mname
    next              if instance.passed?
    pending 'skipped' if instance.skipped?
    error = instance.failure.error
    raise error unless error.kind_of? Minitest::Assertion
    raise MinitestAssertionForRSpec.new error
  end
end