Class: Brutal::Format::Ruby

Inherits:
Object
  • Object
show all
Defined in:
lib/brutal/format/ruby.rb,
lib/brutal/format/ruby/filename.rb

Overview

Ruby format class

Defined Under Namespace

Modules: Filename

Constant Summary collapse

SPACE =

Whitespace character.

" "
HYPHEN_MINUS =

Hyphen-minus character.

"-"
INDENTATION =

Two spaces per indentation level.

SPACE * 2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(header, before, subject, after, footer, *actuals, **contexts) ⇒ Ruby

Initialize a new scaffold generator.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/brutal/format/ruby.rb', line 40

def initialize(header, before, subject, after, footer, *actuals, **contexts)
  header = "# Brutal test suite"      if header.empty?
  before = "# Starting a test"        if before.empty?
  after  = "# Finishing a test"       if after.empty?
  footer = "# End of the brutal test" if footer.empty?

  warn("Empty subject!")              if subject.empty?
  warn("Empty actual values!")        if actuals.empty?
  warn("Empty contexts!")             if contexts.empty?

  @header   = header
  @before   = before
  @subject  = subject
  @actuals  = actuals
  @contexts = contexts
  @after    = after
  @footer   = footer
end

Instance Attribute Details

#actualsObject (readonly)

Specifies templates to challenge evaluated subjects & get results.



19
20
21
# File 'lib/brutal/format/ruby.rb', line 19

def actuals
  @actuals
end

#afterObject (readonly)

Specifies a block of lines to be executed after each example.



34
35
36
# File 'lib/brutal/format/ruby.rb', line 34

def after
  @after
end

#beforeObject (readonly)

Specifies a block of lines to be executed before each example.



28
29
30
# File 'lib/brutal/format/ruby.rb', line 28

def before
  @before
end

#contextsObject (readonly)

Specifies a list of variables to populate the subject's template.



22
23
24
# File 'lib/brutal/format/ruby.rb', line 22

def contexts
  @contexts
end

Specifies a block of lines to be executed once after all examples.



37
38
39
# File 'lib/brutal/format/ruby.rb', line 37

def footer
  @footer
end

#headerObject (readonly)

Specifies a block of lines to be executed once before all examples.



25
26
27
# File 'lib/brutal/format/ruby.rb', line 25

def header
  @header
end

#subjectObject (readonly)

Specifies the template of the code to be declined across contexts.



31
32
33
# File 'lib/brutal/format/ruby.rb', line 31

def subject
  @subject
end

Instance Method Details

#actual_code(actual_str) ⇒ Object



121
122
123
124
125
126
127
128
# File 'lib/brutal/format/ruby.rb', line 121

def actual_code(actual_str)
  <<~CODE
    actual = begin
    #{actual_str.gsub(/^/, INDENTATION)}
    end

  CODE
end

#actual_codesObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/brutal/format/ruby.rb', line 99

def actual_codes
  combinations_values.map do |values|
    string = before_code
    eval(before_code) # rubocop:disable Security/Eval

    actual_str = format(inspect(subject), **attributes(*values))
    string += actual_code(actual_str)
    actual = eval(actual_str) # rubocop:disable Security/Eval, Lint/UselessAssignment

    actuals.each do |actual_value|
      result_str = format(actual_value, subject: "actual")
      result = eval(result_str) # rubocop:disable Security/Eval
      string += "raise if #{result_str} != #{result.inspect}\n"
    end

    string += after_code
    eval(after_code) # rubocop:disable Security/Eval

    string
  end
end

#after_codeObject



143
144
145
146
147
148
# File 'lib/brutal/format/ruby.rb', line 143

def after_code
  <<~CODE

    #{after.chomp}
  CODE
end

#attributes(*values) ⇒ Object



77
78
79
80
81
# File 'lib/brutal/format/ruby.rb', line 77

def attributes(*values)
  context_names.each_with_index.inject({}) do |h, (name, i)|
    h.merge(name.to_sym => inspect(values.fetch(i)))
  end
end

#before_codeObject



136
137
138
139
140
141
# File 'lib/brutal/format/ruby.rb', line 136

def before_code
  <<~CODE
    #{before.chomp}

  CODE
end

#combinations_valuesObject



91
92
93
# File 'lib/brutal/format/ruby.rb', line 91

def combinations_values
  Array(contexts_values[0]).product(*Array(contexts_values[1..]))
end

#context_namesObject



83
84
85
# File 'lib/brutal/format/ruby.rb', line 83

def context_names
  contexts.keys.sort
end

#contexts_valuesObject



87
88
89
# File 'lib/brutal/format/ruby.rb', line 87

def contexts_values
  context_names.map { |context_name| contexts.fetch(context_name) }
end


150
151
152
153
154
# File 'lib/brutal/format/ruby.rb', line 150

def footer_code
  <<~CODE
    #{footer.chomp}
  CODE
end

#header_codeObject



130
131
132
133
134
# File 'lib/brutal/format/ruby.rb', line 130

def header_code
  <<~CODE
    #{header.chomp}
  CODE
end

#inspect(object) ⇒ Object

Return a Ruby string that can be evaluated.



60
61
62
63
64
# File 'lib/brutal/format/ruby.rb', line 60

def inspect(object)
  return object.to_s unless object.is_a?(::String)

  object.strip
end

#ruby_linesObject



95
96
97
# File 'lib/brutal/format/ruby.rb', line 95

def ruby_lines
  [header_code] + actual_codes + [footer_code]
end

#separator_codeObject



156
157
158
159
160
161
# File 'lib/brutal/format/ruby.rb', line 156

def separator_code
  <<~CODE

    #{thematic_break_code}
  CODE
end

#thematic_break_codeObject



163
164
165
166
167
# File 'lib/brutal/format/ruby.rb', line 163

def thematic_break_code
  <<~CODE
    # #{HYPHEN_MINUS * 78}
  CODE
end

#to_sString

Return a string representation.

Returns:

  • (String)


69
70
71
72
73
74
75
# File 'lib/brutal/format/ruby.rb', line 69

def to_s
  eval(header) # rubocop:disable Security/Eval

  ruby_lines.compact.join(separator_code)
ensure
  eval(footer) # rubocop:disable Security/Eval
end