petitest 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +105 -0
  7. data/Rakefile +6 -0
  8. data/lib/petitest/assertion_failure_error.rb +4 -0
  9. data/lib/petitest/assertion_failure_message.rb +35 -0
  10. data/lib/petitest/assertions.rb +46 -0
  11. data/lib/petitest/autorun.rb +8 -0
  12. data/lib/petitest/configuration.rb +26 -0
  13. data/lib/petitest/subscribers/base_subscriber.rb +21 -0
  14. data/lib/petitest/subscribers/json_report_subscriber.rb +38 -0
  15. data/lib/petitest/subscribers/progress_report_subscriber.rb +23 -0
  16. data/lib/petitest/subscribers/timer_subscriber.rb +26 -0
  17. data/lib/petitest/test_case.rb +125 -0
  18. data/lib/petitest/test_cases_runner.rb +58 -0
  19. data/lib/petitest/test_group.rb +51 -0
  20. data/lib/petitest/test_method.rb +25 -0
  21. data/lib/petitest/texts/base_text.rb +54 -0
  22. data/lib/petitest/texts/error_message_text.rb +20 -0
  23. data/lib/petitest/texts/errors_element_text.rb +54 -0
  24. data/lib/petitest/texts/errors_text.rb +45 -0
  25. data/lib/petitest/texts/failure_message_text.rb +20 -0
  26. data/lib/petitest/texts/failures_element_text.rb +54 -0
  27. data/lib/petitest/texts/failures_text.rb +45 -0
  28. data/lib/petitest/texts/filtered_backtrace_text.rb +20 -0
  29. data/lib/petitest/texts/raised_code_text.rb +48 -0
  30. data/lib/petitest/texts/test_case_result_character_text.rb +29 -0
  31. data/lib/petitest/texts/test_cases_result_margin_top_text.rb +24 -0
  32. data/lib/petitest/texts/test_cases_result_text.rb +45 -0
  33. data/lib/petitest/texts/test_counts_text.rb +96 -0
  34. data/lib/petitest/texts/times_text.rb +47 -0
  35. data/lib/petitest/version.rb +3 -0
  36. data/lib/petitest.rb +36 -0
  37. data/petitest.gemspec +24 -0
  38. metadata +108 -0
@@ -0,0 +1,54 @@
1
+ module Petitest
2
+ module Texts
3
+ class BaseText
4
+ ANSI_COLOR_CODE_BY_COLOR_TYPE = {
5
+ black: 30,
6
+ blue: 34,
7
+ bold: 1,
8
+ cyan: 36,
9
+ green: 32,
10
+ magenta: 35,
11
+ red: 31,
12
+ white: 37,
13
+ yellow: 33,
14
+ }
15
+
16
+ # @note Override
17
+ def to_s
18
+ raise ::NotImplementedError
19
+ end
20
+
21
+ private
22
+
23
+ # @param color_type [Symbol]
24
+ # @return [Integer]
25
+ def ansi_color_code_for(color_type)
26
+ ANSI_COLOR_CODE_BY_COLOR_TYPE[configured_color_name_for(color_type)] || ANSI_COLOR_CODE_BY_COLOR_TYPE[:white]
27
+ end
28
+
29
+ # @param color_type [Symbol]
30
+ # @return [Symbol, nil]
31
+ def configured_color_name_for(color_type)
32
+ ::Petitest.configuration.color_scheme[color_type]
33
+ end
34
+
35
+ # @param string [String]
36
+ # @param color_type [Symbol]
37
+ # @return [String]
38
+ def colorize(string, color_type)
39
+ if ::Petitest.configuration.colored
40
+ "\e[#{ansi_color_code_for(color_type)}m#{string}\e[0m"
41
+ else
42
+ string
43
+ end
44
+ end
45
+
46
+ # @param string [String]
47
+ # @param level [Integer]
48
+ # @return [String]
49
+ def indent(string, level)
50
+ string.gsub(/^(?!$)/, " " * level)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,20 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class ErrorMessageText < ::Petitest::Texts::BaseText
6
+ # @return [Petitest::TestCase]
7
+ attr_reader :test_case
8
+
9
+ # @param test_case [Petitest::TestCase]
10
+ def initialize(test_case:)
11
+ @test_case = test_case
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ colorize("#{test_case.error_class_name}: #{test_case.error_message}", :error)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,54 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class ErrorsElementText < ::Petitest::Texts::BaseText
6
+ # @return [Integer]
7
+ attr_reader :index
8
+
9
+ # @return [Petitest::TestCase]
10
+ attr_reader :test_case
11
+
12
+ # @param index [Integer]
13
+ # @param test_case [Petitest::TestCase]
14
+ def initialize(index:, test_case:)
15
+ @index = index
16
+ @test_case = test_case
17
+ end
18
+
19
+ # @note Override
20
+ def to_s
21
+ [
22
+ heading,
23
+ indent(body, 2)
24
+ ].join("\n")
25
+ end
26
+
27
+ private
28
+
29
+ # @return [String]
30
+ def body
31
+ [
32
+ ::Petitest::Texts::RaisedCodeText.new(test_case: test_case),
33
+ ::Petitest::Texts::ErrorMessageText.new(test_case: test_case),
34
+ ::Petitest::Texts::FilteredBacktraceText.new(test_case: test_case),
35
+ ].join("\n")
36
+ end
37
+
38
+ # @return [String]
39
+ def heading
40
+ "#{ordinal_number}) #{test_signature}"
41
+ end
42
+
43
+ # @return [Integer]
44
+ def ordinal_number
45
+ index + 1
46
+ end
47
+
48
+ # @return [String]
49
+ def test_signature
50
+ test_case.test_signature
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class ErrorsText < ::Petitest::Texts::BaseText
6
+ # @return [Array<Petitest::TestCase>]
7
+ attr_reader :test_cases
8
+
9
+ # @param test_cases [Array<Petitest::TestCase>]
10
+ def initialize(test_cases:)
11
+ @test_cases = test_cases
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ [
17
+ heading,
18
+ indent(body, 2),
19
+ ].join("\n\n")
20
+ end
21
+
22
+ private
23
+
24
+ # @return [String]
25
+ def body
26
+ errors_element_texts.join("\n\n")
27
+ end
28
+
29
+ # @return [Array<Petitest::Textx::FailuresElementText>]
30
+ def errors_element_texts
31
+ test_cases.map.with_index do |test_case, index|
32
+ ::Petitest::Texts::ErrorsElementText.new(
33
+ index: index,
34
+ test_case: test_case,
35
+ )
36
+ end
37
+ end
38
+
39
+ # @return [String]
40
+ def heading
41
+ "Errors:"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,20 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class FailureMessageText < ::Petitest::Texts::BaseText
6
+ # @return [Petitest::TestCase]
7
+ attr_reader :test_case
8
+
9
+ # @param test_case [Petitest::TestCase]
10
+ def initialize(test_case:)
11
+ @test_case = test_case
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ colorize(test_case.failure_message, :failure)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,54 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class FailuresElementText < ::Petitest::Texts::BaseText
6
+ # @return [Integer]
7
+ attr_reader :index
8
+
9
+ # @return [Petitest::TestCase]
10
+ attr_reader :test_case
11
+
12
+ # @param index [Integer]
13
+ # @param test_case [Petitest::TestCase]
14
+ def initialize(index:, test_case:)
15
+ @index = index
16
+ @test_case = test_case
17
+ end
18
+
19
+ # @note Override
20
+ def to_s
21
+ [
22
+ heading,
23
+ indent(body, 2)
24
+ ].join("\n")
25
+ end
26
+
27
+ private
28
+
29
+ # @return [String]
30
+ def body
31
+ [
32
+ ::Petitest::Texts::RaisedCodeText.new(test_case: test_case),
33
+ ::Petitest::Texts::FailureMessageText.new(test_case: test_case),
34
+ ::Petitest::Texts::FilteredBacktraceText.new(test_case: test_case),
35
+ ].join("\n")
36
+ end
37
+
38
+ # @return [String]
39
+ def heading
40
+ "#{ordinal_number}) #{test_signature}"
41
+ end
42
+
43
+ # @return [Integer]
44
+ def ordinal_number
45
+ index + 1
46
+ end
47
+
48
+ # @return [String]
49
+ def test_signature
50
+ test_case.test_signature
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class FailuresText < ::Petitest::Texts::BaseText
6
+ # @return [Array<Petitest::TestCase>]
7
+ attr_reader :test_cases
8
+
9
+ # @param test_cases [Array<Petitest::TestCase>]
10
+ def initialize(test_cases:)
11
+ @test_cases = test_cases
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ [
17
+ heading,
18
+ indent(body, 2),
19
+ ].join("\n\n")
20
+ end
21
+
22
+ private
23
+
24
+ # @return [String]
25
+ def body
26
+ failures_element_texts.join("\n\n")
27
+ end
28
+
29
+ # @return [Array<Petitest::Textx::FailuresElementText>]
30
+ def failures_element_texts
31
+ test_cases.map.with_index do |test_case, index|
32
+ ::Petitest::Texts::FailuresElementText.new(
33
+ index: index,
34
+ test_case: test_case,
35
+ )
36
+ end
37
+ end
38
+
39
+ # @return [String]
40
+ def heading
41
+ "Failures:"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,20 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class FilteredBacktraceText < ::Petitest::Texts::BaseText
6
+ # @return [Petitest::TestCase]
7
+ attr_reader :test_case
8
+
9
+ # @param test_case [Petitest::TestCase]
10
+ def initialize(test_case:)
11
+ @test_case = test_case
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ colorize(test_case.filtered_backtrace.join("\n").gsub(/^/, "# "), :detail)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,48 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class RaisedCodeText < ::Petitest::Texts::BaseText
6
+ # @return [Petitest::TestCase]
7
+ attr_reader :test_case
8
+
9
+ # @param test_case [Petitest::TestCase]
10
+ def initialize(test_case:)
11
+ @test_case = test_case
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ if content = caller_file_content
17
+ content.lines[caller_line_number - 1].strip
18
+ else
19
+ ""
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ # @return [String, nil]
26
+ def caller_file_content
27
+ if ::FileTest.file?(caller_path)
28
+ ::File.read(caller_path)
29
+ end
30
+ end
31
+
32
+ # @return [String]
33
+ def caller_line_number
34
+ caller_segments[1].to_i
35
+ end
36
+
37
+ # @return [String]
38
+ def caller_path
39
+ caller_segments[0]
40
+ end
41
+
42
+ # @return [Array<String>]
43
+ def caller_segments
44
+ @caller_segments ||= test_case.filtered_backtrace[0].split(":", 3)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class TestCaseResultCharacterText < ::Petitest::Texts::BaseText
6
+ # @return [Petitest::TestCase]
7
+ attr_reader :test_case
8
+
9
+ # @param test_case [Petitest::TestCase]
10
+ def initialize(test_case:)
11
+ @test_case = test_case
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ case
17
+ when test_case.aborted?
18
+ colorize("E", :error)
19
+ when test_case.failed?
20
+ colorize("F", :failure)
21
+ when test_case.skipped?
22
+ colorize("*", :skip)
23
+ else
24
+ "."
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class TestCasesResultMarginTopText < ::Petitest::Texts::BaseText
6
+ # @return [Array<Petitest::TestCase>]
7
+ attr_reader :test_cases
8
+
9
+ # @param test_cases [Array<Petitest::TestCase>]
10
+ def initialize(test_cases:)
11
+ @test_cases = test_cases
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ if test_cases.empty?
17
+ "\n"
18
+ else
19
+ "\n\n"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,45 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class TestCasesResultText < ::Petitest::Texts::BaseText
6
+ # @return [Time]
7
+ attr_reader :finished_at
8
+
9
+ # @return [Time]
10
+ attr_reader :started_at
11
+
12
+ # @return [Array<Petitest::TestCase>]
13
+ attr_reader :test_cases
14
+
15
+ # @param finished_at [Time]
16
+ # @param started_at [Time]
17
+ # @param test_cases [Array<Petitest::TestCase>]
18
+ def initialize(
19
+ finished_at:,
20
+ started_at:,
21
+ test_cases:
22
+ )
23
+ @finished_at = finished_at
24
+ @started_at = started_at
25
+ @test_cases = test_cases
26
+ end
27
+
28
+ # @note Override
29
+ def to_s
30
+ [
31
+ ::Petitest::Texts::TestCasesResultMarginTopText.new(test_cases: test_cases),
32
+ [
33
+ ::Petitest::Texts::FailuresText.new(test_cases: test_cases.select(&:failed?)),
34
+ ::Petitest::Texts::ErrorsText.new(test_cases: test_cases.select(&:aborted?)),
35
+ ::Petitest::Texts::TestCountsText.new(test_cases: test_cases),
36
+ ::Petitest::Texts::TimesText.new(
37
+ finished_at: finished_at,
38
+ started_at: started_at,
39
+ ),
40
+ ].join("\n\n"),
41
+ ].join
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,96 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class TestCountsText < ::Petitest::Texts::BaseText
6
+ # @return [Array<Petitest::TestCase>]
7
+ attr_reader :test_cases
8
+
9
+ # @param test_cases [Array<Petitest::TestCase>]
10
+ def initialize(test_cases:)
11
+ @test_cases = test_cases
12
+ end
13
+
14
+ # @note Override
15
+ def to_s
16
+ [
17
+ heading,
18
+ indent(body, 2),
19
+ ].join("\n\n")
20
+ end
21
+
22
+ private
23
+
24
+ # @return [String]
25
+ def body
26
+ [
27
+ text_of_count_of_test_cases,
28
+ text_of_count_of_passed_test_cases,
29
+ text_of_count_of_failed_test_cases,
30
+ text_of_count_of_aborted_test_cases,
31
+ text_of_count_of_skipped_test_cases,
32
+ ].join("\n")
33
+ end
34
+
35
+ # @return [Integer]
36
+ def count_of_aborted_test_cases
37
+ test_cases.select(&:aborted?).length
38
+ end
39
+
40
+ # @return [Integer]
41
+ def count_of_failed_test_cases
42
+ test_cases.select(&:failed?).length
43
+ end
44
+
45
+ # @return [Integer]
46
+ def count_of_passed_test_cases
47
+ test_cases.select(&:passed?).length
48
+ end
49
+
50
+ # @return [Integer]
51
+ def count_of_skipped_test_cases
52
+ test_cases.select(&:skipped?).length
53
+ end
54
+
55
+ # @return [Integer]
56
+ def count_of_test_cases
57
+ test_cases.length
58
+ end
59
+
60
+ # @return [String]
61
+ def heading
62
+ "Counts:"
63
+ end
64
+
65
+ # @return [Integer]
66
+ def max_digits_length
67
+ @max_digits_length ||= count_of_test_cases.to_s.length
68
+ end
69
+
70
+ # @return [String]
71
+ def text_of_count_of_aborted_test_cases
72
+ colorize("%#{max_digits_length}d errors" % count_of_aborted_test_cases, :error)
73
+ end
74
+
75
+ # @return [String]
76
+ def text_of_count_of_failed_test_cases
77
+ colorize("%#{max_digits_length}d failures" % count_of_failed_test_cases, :failure)
78
+ end
79
+
80
+ # @return [String]
81
+ def text_of_count_of_passed_test_cases
82
+ colorize("%#{max_digits_length}d passes" % count_of_passed_test_cases, :pass)
83
+ end
84
+
85
+ # @return [String]
86
+ def text_of_count_of_skipped_test_cases
87
+ colorize("%#{max_digits_length}d skips" % count_of_skipped_test_cases, :skip)
88
+ end
89
+
90
+ # @return [String]
91
+ def text_of_count_of_test_cases
92
+ "%#{max_digits_length}d tests" % count_of_test_cases
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,47 @@
1
+ require "petitest/texts/base_text"
2
+
3
+ module Petitest
4
+ module Texts
5
+ class TimesText < ::Petitest::Texts::BaseText
6
+ # @return [Time]
7
+ attr_reader :finished_at
8
+
9
+ # @return [Time]
10
+ attr_reader :started_at
11
+
12
+ # @param finished_at [Time]
13
+ # @param started_at [Time]
14
+ def initialize(
15
+ finished_at:,
16
+ started_at:
17
+ )
18
+ @finished_at = finished_at
19
+ @started_at = started_at
20
+ end
21
+
22
+ # @note Override
23
+ def to_s
24
+ [
25
+ heading,
26
+ indent(body, 2),
27
+ ].join("\n\n")
28
+ end
29
+
30
+ private
31
+
32
+ # @return [String]
33
+ def body
34
+ [
35
+ "Started: #{started_at.iso8601(6)}",
36
+ "Finished: #{finished_at.iso8601(6)}",
37
+ "Total: %.6fs" % (finished_at - started_at),
38
+ ].join("\n")
39
+ end
40
+
41
+ # @return [String]
42
+ def heading
43
+ "Times:"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module Petitest
2
+ VERSION = "0.1.0"
3
+ end
data/lib/petitest.rb ADDED
@@ -0,0 +1,36 @@
1
+ require "petitest/assertion_failure_error"
2
+ require "petitest/assertion_failure_message"
3
+ require "petitest/assertions"
4
+ require "petitest/configuration"
5
+ require "petitest/subscribers/base_subscriber"
6
+ require "petitest/subscribers/json_report_subscriber"
7
+ require "petitest/subscribers/progress_report_subscriber"
8
+ require "petitest/subscribers/timer_subscriber"
9
+ require "petitest/test_case"
10
+ require "petitest/test_cases_runner"
11
+ require "petitest/test_group"
12
+ require "petitest/test_method"
13
+ require "petitest/texts/base_text"
14
+ require "petitest/texts/error_message_text"
15
+ require "petitest/texts/errors_element_text"
16
+ require "petitest/texts/errors_text"
17
+ require "petitest/texts/failure_message_text"
18
+ require "petitest/texts/failures_element_text"
19
+ require "petitest/texts/failures_text"
20
+ require "petitest/texts/filtered_backtrace_text"
21
+ require "petitest/texts/raised_code_text"
22
+ require "petitest/texts/test_case_result_character_text"
23
+ require "petitest/texts/test_cases_result_margin_top_text"
24
+ require "petitest/texts/test_cases_result_text"
25
+ require "petitest/texts/test_counts_text"
26
+ require "petitest/texts/times_text"
27
+ require "petitest/version"
28
+
29
+ module Petitest
30
+ class << self
31
+ # @return [Petitest::Configuration]
32
+ def configuration
33
+ @configuration ||= ::Petitest::Configuration.new
34
+ end
35
+ end
36
+ end
data/petitest.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "petitest/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "petitest"
7
+ spec.version = Petitest::VERSION
8
+ spec.authors = ["Ryo Nakamura"]
9
+ spec.email = ["r7kamura@gmail.com"]
10
+ spec.summary = "A minimal solid testing framework for Ruby."
11
+ spec.homepage = "https://github.com/r7kamura/petitest"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
+ f.match(%r{^(test|spec|features)/})
16
+ end
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+ spec.required_ruby_version = ">= 2.1.0"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.14"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ end