Class: Scampi::Context

Inherits:
Object show all
Defined in:
lib/scampi/context.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &block) ⇒ Context

Returns a new instance of Context.



5
6
7
8
9
10
11
# File 'lib/scampi/context.rb', line 5

def initialize(name, &block)
  @name = name
  @block = block
  @items = []
  @before = []
  @after = []
end

Instance Attribute Details

#blockObject (readonly)

Returns the value of attribute block.



3
4
5
# File 'lib/scampi/context.rb', line 3

def block
  @block
end

#nameObject (readonly)

Returns the value of attribute name.



3
4
5
# File 'lib/scampi/context.rb', line 3

def name
  @name
end

Instance Method Details

#after(&block) ⇒ Object



80
# File 'lib/scampi/context.rb', line 80

def after(&block);  @items << [:after, block];  @after  << block; end

#before(&block) ⇒ Object



79
# File 'lib/scampi/context.rb', line 79

def before(&block); @items << [:before, block]; @before << block; end

#behaves_like(*names) ⇒ Object



82
83
84
# File 'lib/scampi/context.rb', line 82

def behaves_like(*names)
  names.each { |name| instance_eval(&Shared[name]) }
end

#change?(&block) ⇒ Boolean

Returns:

  • (Boolean)


164
# File 'lib/scampi/context.rb', line 164

def change?(&block) = lambda{}.change?(&block)

#countObject

Count total specs recursively.



26
27
28
29
30
31
32
33
34
# File 'lib/scampi/context.rb', line 26

def count
  @items.sum { |item|
    case item[0]
    when :spec  then 1
    when :child then item[1].count
    else 0
    end
  }
end

#describe(*args, &block) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/scampi/context.rb', line 148

def describe(*args, &block)
  context = Scampi::Context.new(args.join(' '), &block)
  (parent_context = self).methods(false).each { |e|
    (class << context; self; end).send(:define_method, e) { |*args2, &block2|
      parent_context.send(e, *args2, &block2)
    }
  }
  @before.each { |b| context.before(&b) }
  @after.each  { |b| context.after(&b) }
  context.register
  @items << [:child, context]
  context
end

#execute(indent = 0) ⇒ Object

Phase 2: run all registered specs in order, emitting TAP subtests. indent is the nesting depth (0 = inside a top-level describe). Returns true if all specs/children passed, false otherwise.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/scampi/context.rb', line 39

def execute(indent = 0)
  prefix = "    " * indent
  inner  = "    " * (indent + 1)

  plan = @items.count { |item| item[0] == :spec || item[0] == :child }

  puts "#{prefix}# Subtest: #{@name}"
  puts "#{inner}1..#{plan}"

  befores = []
  afters  = []
  local_n = 0
  all_passed = true

  @items.each { |item|
    case item[0]
    when :before
      befores << item[1]
    when :after
      afters << item[1]
    when :spec
      Counter[:specifications] += 1
      local_n += 1
      passed = run_requirement(item[1], item[2], befores, afters, indent + 1, local_n)
      all_passed = false  unless passed
    when :child
      local_n += 1
      child_passed = item[1].execute(indent + 1)
      if child_passed
        puts "#{inner}#{"ok".green} #{local_n} - #{item[1].name}"
      else
        puts "#{inner}#{"not ok".red} #{local_n} - #{item[1].name}"
      end
      all_passed = false  unless child_passed
    end
  }

  all_passed
end

#it(description, &block) ⇒ Object



86
87
88
89
90
# File 'lib/scampi/context.rb', line 86

def it(description, &block)
  return  unless description =~ RestrictName
  block ||= proc { should.flunk "not implemented" }
  @items << [:spec, description, block]
end

#raise?(*args, &block) ⇒ Boolean

Returns:

  • (Boolean)


162
# File 'lib/scampi/context.rb', line 162

def raise?(*args, &block) = block.raise?(*args)

#registerObject

Phase 1: evaluate block to discover specs and children. Nothing is executed — it and describe just queue.



15
16
17
18
19
20
21
22
23
# File 'lib/scampi/context.rb', line 15

def register
  tap do
    if name =~ RestrictContext
      instance_eval(&block)
    else
      self
    end
  end
end

#run_requirement(description, spec, befores, afters, indent = 0, local_n = 1) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/scampi/context.rb', line 100

def run_requirement(description, spec, befores, afters, indent = 0, local_n = 1)
  Scampi.handle_requirement(description, indent, local_n) do
    begin
      Counter[:depth] += 1
      rescued = false
      begin
        befores.each { |block| instance_eval(&block) }
        prev_req = Counter[:requirements]
        instance_eval(&spec)
      rescue Object => e
        rescued = true
        raise e
      ensure
        if Counter[:requirements] == prev_req and not rescued
          raise Error.new(:missing,
                          "empty specification: #{@name} #{description}")
        end
        begin
          afters.each { |block| instance_eval(&block) }
        rescue Object => e
          raise e  unless rescued
        end
      end
    rescue SystemExit, Interrupt
      raise
    rescue Object => e
      ErrorLog << "#{e.class}: #{e.message}\n"
      e.backtrace.find_all { |line| line !~ /bin\/scampi|\/scampi\.rb:\d+/ }.
        each_with_index { |line, i|
        ErrorLog << "\t#{line}#{i==0 ? ": #@name - #{description}" : ""}\n"
      }
      ErrorLog << "\n"

      if e.kind_of? Error
        Counter[e.count_as] += 1
        e.count_as.to_s.upcase
      else
        Counter[:errors] += 1
        "ERROR: #{e.class}"
      end
    else
      ""
    ensure
      Counter[:depth] -= 1
    end
  end
end

#should(*args, &block) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/scampi/context.rb', line 92

def should(*args, &block)
  if Counter[:depth] == 0
    it('should ' + args.first, &block)
  else
    super(*args, &block)
  end
end

#throw?(*args, &block) ⇒ Boolean

Returns:

  • (Boolean)


163
# File 'lib/scampi/context.rb', line 163

def throw?(*args, &block) = block.throw?(*args)