Class: QED::Step

Inherits:
Object show all
Defined in:
lib/qed/step.rb

Overview

A Step consists of a flush region of text and the indented text the follows it. QED breaks all demos down into step for evaluation.

Steps form a doubly linkes list, each having access to the step before and the step after them. Potentially this could be used by very advnaced matchers, to vary executation by earlier or later content of a demo.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(demo, explain_lines, example_lines, last) ⇒ Step

Step up a new step.

Parameters:

  • demo (Demo)

    The demo to which the step belongs.

  • explain_lines (Array<Array<Integer,String>])

    The step's explaination text, broken down into an array of `[line number, line text]` entries.

  • example_lines (Array<Array<Integer,String>])

    The steps example text, broken down into an array of `[line number, line text]` entries.

  • last (Step)

    The previous step in the demo.


45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/qed/step.rb', line 45

def initialize(demo, explain_lines, example_lines, last)
  #QED.all_steps << self

  @demo = demo
  @file = demo.file

  #@lines = []

  @explain_lines = explain_lines
  @example_lines = example_lines

  @back_step = last
  @back_step.next_step = self if @back_step
end

Instance Attribute Details

#back_stepStep (readonly)

Previous step.

Returns:

  • (Step)

    previous step


23
24
25
# File 'lib/qed/step.rb', line 23

def back_step
  @back_step
end

#demoDemo (readonly)

Ths demo to which the step belongs.

Returns:


16
17
18
# File 'lib/qed/step.rb', line 16

def demo
  @demo
end

#example_linesArray<Array<Integer,String>] (readonly)

The steps example text, broken down into an array of `[line number, line text]` entries.

Returns:

  • (Array<Array<Integer,String>])

    example_lines


70
71
72
# File 'lib/qed/step.rb', line 70

def example_lines
  @example_lines
end

#explain_linesArray<Array<Integer,String>] (readonly)

The step's explaination text, broken down into an array of `[line number, line text]` entries.

Returns:

  • (Array<Array<Integer,String>])

    explain_lines


64
65
66
# File 'lib/qed/step.rb', line 64

def explain_lines
  @explain_lines
end

#next_stepStep

Next step.

Returns:

  • (Step)

    next step


27
28
29
# File 'lib/qed/step.rb', line 27

def next_step
  @next_step
end

Instance Method Details

#argumentsObject

Returns any extra arguments the step passes along to rules.


171
172
173
# File 'lib/qed/step.rb', line 171

def arguments
  []
end

#assertive?Boolean

Returns:

  • (Boolean)

214
215
216
# File 'lib/qed/step.rb', line 214

def assertive?
  @assertive ||= !text.strip.end_with?('^')
end

#clean_exampleObject

Clean up the example text, removing unccesseary white lines and triple quote brackets, but keep indention intact.


178
179
180
181
182
183
184
# File 'lib/qed/step.rb', line 178

def clean_example
  str = example.chomp.sub(/\A\n/,'')
  if md = /\A["]{3,}(.*?)["]{3,}\Z/.match(str)
    str = md[1]
  end
  str.rstrip
end

#code?Boolean

Is the example text code to be evaluated?

Returns:

  • (Boolean)

126
127
128
# File 'lib/qed/step.rb', line 126

def code?
  !data? && example?
end

#data?Boolean

Any commentary ending in `:` will mark the example text as a plain text sample and not code to be evaluated.

Returns:

  • (Boolean)

121
122
123
# File 'lib/qed/step.rb', line 121

def data?
  @is_data ||= explain.strip.end_with?(':')
end

#exampleObject Also known as: code, data


158
159
160
161
162
163
164
165
166
# File 'lib/qed/step.rb', line 158

def example
  @example ||= (
    if data?
      @example_lines.map{ |lineno, line| line }.join("")
    else
      tweak_code
    end
  )
end

#example?Boolean Also known as: has_example?

Does the block have an example?

Returns:

  • (Boolean)

152
153
154
# File 'lib/qed/step.rb', line 152

def example?
  ! example.strip.empty?
end

#example_linenoObject


147
148
149
# File 'lib/qed/step.rb', line 147

def example_lineno
  @example_lines.first ? @example_lines.first.first : 1
end

#explainObject Also known as: description, text

Description text.


85
86
87
# File 'lib/qed/step.rb', line 85

def explain
  @explain ||= @explain_lines.map{ |lineno, line| line }.join("")
end

#explain_linenoObject


143
144
145
# File 'lib/qed/step.rb', line 143

def explain_lineno
  @explain_lines.first ? @explain_lines.first.first : 1
end

#fileString

Ths file to which the step belongs.

Returns:


75
76
77
# File 'lib/qed/step.rb', line 75

def file
  demo.file
end

#heading?Boolean

A step is a heading if it's description starts with a '=' or '#'.

Returns:

  • (Boolean)

115
116
117
# File 'lib/qed/step.rb', line 115

def heading?
  @is_heading ||= (/\A[=#]/ =~ explain)
end

#inspectObject

TODO: object_hexid


208
209
210
211
# File 'lib/qed/step.rb', line 208

def inspect
  str = text[0,24].gsub("\n"," ")
  %[\#<Step:#{object_id} "#{str} ...">]
end

#linenoObject

First line of example text.


131
132
133
134
135
136
137
138
139
140
141
# File 'lib/qed/step.rb', line 131

def lineno
  @lineno ||= (
    if @example_lines.first
      @example_lines.first.first
    elsif @explain_lines.first
      @explain_lines.first.first
     else
      1
    end
  )
end

#sample_textObject

When the text is sample text and passed to an adivce block, this provides the prepared form of the example text, removing white lines, triple quote brackets and indention.


199
200
201
202
203
204
205
# File 'lib/qed/step.rb', line 199

def sample_text
  str = example.tabto(0).chomp.sub(/\A\n/,'')
  if md = /\A["]{3,}(.*?)["]{3,}\Z/.match(str)
    str = md[1]
  end
  str.rstrip
end

#to_sObject

Full text of block including both explination and example text.


80
81
82
# File 'lib/qed/step.rb', line 80

def to_s
  (@explain_lines + @example_lines).map{ |lineno, line| line }.join("")
end

#tweak_codeObject (private)


228
229
230
231
232
233
234
235
236
237
238
# File 'lib/qed/step.rb', line 228

def tweak_code
  code = @example_lines.map{ |lineno, line| line }.join("")

  #code.gsub!(/\n\s*\#\ ?\=\>(.*?)$/, ' == \1 ? assert(true) : assert(false, %{not returned -- \1})')   # TODO: what kind of error ?
  #code.gsub!(/\s*\#\ ?\=\>(.*?)$/,   ' == \1 ? assert(true) : assert(false, %{not returned -- \1})')

  code.gsub!(/\n\s*\#\ ?\=\>\s*(.*?)$/, '.must_return(\1)')
  code.gsub!(/\s*\#\ ?\=\>\s*(.*?)$/, '.must_return(\1)')

  code
end

#typeObject


110
111
112
# File 'lib/qed/step.rb', line 110

def type
  assertive? ? :test : :proc
end