brutal 1.6.0.beta3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,163 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative File.join("ruby", "filename")
4
-
5
- class Brutal
6
- module Format
7
- # Ruby format class
8
- class Ruby
9
- # Whitespace character.
10
- SPACE = " "
11
-
12
- # Hyphen-minus character.
13
- HYPHEN_MINUS = "-"
14
-
15
- # Two spaces per indentation level.
16
- INDENTATION = SPACE * 2
17
-
18
- # Specifies templates to challenge evaluated subjects & get results.
19
- attr_reader :actuals
20
-
21
- # Specifies a list of variables to populate the subject's template.
22
- attr_reader :contexts
23
-
24
- # Specifies a block of lines to be executed once before all examples.
25
- attr_reader :header
26
-
27
- # Specifies a block of lines to be executed before each example.
28
- attr_reader :before
29
-
30
- # Specifies the template of the code to be declined across contexts.
31
- attr_reader :subject
32
-
33
- # Specifies a block of lines to be executed after each example.
34
- attr_reader :after
35
-
36
- # Specifies a block of lines to be executed once after all examples.
37
- attr_reader :footer
38
-
39
- # Initialize a new scaffold generator.
40
- def initialize(header, before, subject, after, footer, *actuals, **contexts)
41
- header = "# Brutal test suite" if header.empty?
42
- before = "# Starting an example" if before.empty?
43
- after = "# Finishing an example" if after.empty?
44
- footer = "# End of the brutal test" if footer.empty?
45
-
46
- warn("Empty subject!") if subject.empty?
47
- warn("Empty actual values!") if actuals.empty?
48
- warn("Empty contexts!") if contexts.empty?
49
-
50
- @header = header
51
- @before = before
52
- @subject = subject
53
- @actuals = actuals
54
- @contexts = contexts
55
- @after = after
56
- @footer = footer
57
- end
58
-
59
- # Return a Ruby string that can be evaluated.
60
- def inspect(object)
61
- return object.to_s unless object.is_a?(::String)
62
-
63
- object.strip
64
- end
65
-
66
- # Return a string representation.
67
- #
68
- # @return [String]
69
- def to_s
70
- eval(header) # rubocop:disable Security/Eval
71
-
72
- ruby_lines.compact.join(separator_code)
73
- ensure
74
- eval(footer) # rubocop:disable Security/Eval
75
- end
76
-
77
- def attributes(*values)
78
- context_names.each_with_index.inject({}) do |h, (name, i)|
79
- h.merge(name.to_sym => inspect(values.fetch(i)))
80
- end
81
- end
82
-
83
- def context_names
84
- contexts.keys.sort
85
- end
86
-
87
- def contexts_values
88
- context_names.map { |context_name| contexts.fetch(context_name) }
89
- end
90
-
91
- def combinations_values
92
- Array(contexts_values[0]).product(*Array(contexts_values[1..]))
93
- end
94
-
95
- def ruby_lines
96
- [header_code] + actual_codes + [footer_code]
97
- end
98
-
99
- def actual_codes
100
- combinations_values.map do |values|
101
- actual_str = format(inspect(subject), **attributes(*values))
102
- string = actual_code(actual_str)
103
- actual = eval(actual_str) # rubocop:disable Security/Eval, Lint/UselessAssignment
104
-
105
- actuals.each do |actual_value|
106
- result_str = format(actual_value, subject: "actual")
107
- string += "raise if #{result_str} != #{eval(result_str).inspect}\n" # rubocop:disable Security/Eval
108
- end
109
-
110
- string
111
- end
112
- end
113
-
114
- def actual_code(actual_str)
115
- <<~CODE
116
- #{before_code}
117
- actual = begin
118
- #{actual_str.gsub(/^/, INDENTATION)}
119
- end
120
-
121
- #{after_code}
122
- CODE
123
- end
124
-
125
- def header_code
126
- <<~CODE
127
- #{header.chomp}
128
- CODE
129
- end
130
-
131
- def before_code
132
- <<~CODE
133
- #{before.chomp}
134
- CODE
135
- end
136
-
137
- def after_code
138
- <<~CODE
139
- #{after.chomp}
140
- CODE
141
- end
142
-
143
- def footer_code
144
- <<~CODE
145
- #{footer.chomp}
146
- CODE
147
- end
148
-
149
- def separator_code
150
- <<~CODE
151
-
152
- #{thematic_break_code}
153
- CODE
154
- end
155
-
156
- def thematic_break_code
157
- <<~CODE
158
- # #{HYPHEN_MINUS * 78}
159
- CODE
160
- end
161
- end
162
- end
163
- end
data/lib/brutal/format.rb DELETED
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Dir[File.join(File.dirname(__FILE__), "format", "*.rb")].sort.each do |fname|
4
- require_relative fname
5
- end
6
-
7
- class Brutal
8
- # A collection of formatter classes.
9
- module Format
10
- end
11
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Brutal
4
- class Manifest
5
- class File
6
- module Name
7
- # Suffix for configuration file names.
8
- SUFFIX = "_brutal.yaml"
9
-
10
- # Suffix pattern for configuration file names.
11
- SUFFIX_PATTERN = "*#{SUFFIX}"
12
-
13
- # Suffix regex for configuration file names.
14
- SUFFIX_REGEX = /#{SUFFIX}\z/.freeze
15
- end
16
- end
17
- end
18
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative File.join("file", "name")
4
-
5
- require "yaml"
6
-
7
- class Brutal
8
- class Manifest
9
- # YAML manifest file parser.
10
- class File
11
- attr_reader :yaml
12
-
13
- def initialize(pathname)
14
- unless pathname.fnmatch?(Name::SUFFIX_PATTERN, ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH)
15
- raise ::ArgumentError
16
- end
17
-
18
- @yaml = pathname.read
19
- end
20
-
21
- def parse
22
- ::YAML.safe_load(yaml, symbolize_names: false)
23
- end
24
- end
25
- end
26
- end