Class: SeeingIsBelieving::EventStream::Producer

Inherits:
Object
  • Object
show all
Defined in:
lib/seeing_is_believing/event_stream/producer.rb

Defined Under Namespace

Modules: NullQueue

Constant Summary collapse

ErrnoEPIPE =

not actually tested, but we can see it is referenced below

Errno::EPIPE
StackErrors =
[SystemStackError]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resultstream) ⇒ Producer

Returns a new instance of Producer.



30
31
32
33
34
35
36
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 30

def initialize(resultstream)
  self.filename          = nil
  self.max_line_captures = Float::INFINITY
  self.recorded_results  = []
  self.queue             = Queue.new
  self.producer_thread   = build_producer_thread(resultstream)
end

Instance Attribute Details

#filenameObject

Returns the value of attribute filename.



28
29
30
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 28

def filename
  @filename
end

#max_line_capturesObject

Returns the value of attribute max_line_captures.



28
29
30
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 28

def max_line_captures
  @max_line_captures
end

#versionObject (readonly) Also known as: ver

Returns the value of attribute version.



38
39
40
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 38

def version
  @version
end

Instance Method Details

#file_loadedObject



54
55
56
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 54

def file_loaded
  queue << "file_loaded"
end

#finish!Object



130
131
132
133
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 130

def finish!
  queue << :break # note that consumer will continue reading until stream is closed, which is not the responsibility of the producer
  producer_thread.join
end

#record_exception(line_number, exception) ⇒ Object

records the exception, returns the exitstatus for that exception



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 96

def record_exception(line_number, exception)
  return exception.status if SystemExit === exception # TODO === is not in the list
  unless line_number
    if filename
      begin line_number = exception.backtrace.grep(/#{filename.to_s}/).first[/:\d+/][1..-1].to_i
      rescue NoMethodError
      end
    end
  end
  line_number ||= -1
  queue << [
    "exception",
    line_number.to_s,
    to_string_token(exception.class.name),
    to_string_token(exception.message),
    exception.backtrace.size.to_s,
    *exception.backtrace.map { |line| to_string_token line }
  ].join(" ")
  1 # exit status
end

#record_exec(args) ⇒ Object



122
123
124
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 122

def record_exec(args)
  queue << "exec #{to_string_token args.inspect}"
end

#record_filename(filename) ⇒ Object



117
118
119
120
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 117

def record_filename(filename)
  self.filename = filename
  queue << "filename #{to_string_token filename}"
end

#record_max_line_captures(max_line_captures) ⇒ Object



49
50
51
52
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 49

def record_max_line_captures(max_line_captures)
  self.max_line_captures = max_line_captures
  queue << "max_line_captures #{max_line_captures}"
end

#record_num_lines(num_lines) ⇒ Object



126
127
128
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 126

def record_num_lines(num_lines)
  queue << "num_lines #{num_lines}"
end

#record_result(type, line_number, value) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 60

def record_result(type, line_number, value)
  counts = recorded_results[line_number] ||= Hash.new(0)
  count  = counts[type]
  recorded_results[line_number][type] = count.next
  if count < max_line_captures
    begin
      if block_given?
        inspected = yield(value)
      else
        inspected = value.inspect
      end
      unless String === inspected
        inspected = inspected.to_str
        raise unless String === inspected
      end
    rescue *StackErrors
      # this is necessary because SystemStackError won't show the backtrace of the method we tried to call
      # which means there won't be anything showing the user where this came from
      # so we need to re-raise the error to get a backtrace that shows where we came from
      # otherwise it looks like the bug is in SiB and not the user's program, see https://github.com/JoshCheek/seeing_is_believing/issues/37
      raise SystemStackError, "Calling inspect blew the stack (is it recursive w/o a base case?)"
    rescue Exception
      begin
        inspected = Kernel.instance_method(:inspect).bind(value).call
      rescue Exception
        inspected = "#<no inspect available>"
      end
    end
    queue << "result #{line_number.to_s} #{type.to_s} #{to_string_token inspected}"
  elsif count == max_line_captures
    queue << "maxed_result #{line_number.to_s} #{type.to_s}"
  end
  value
end

#record_ruby_version(ruby_version) ⇒ Object



45
46
47
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 45

def record_ruby_version(ruby_version)
  queue << "ruby_version #{to_string_token ruby_version}"
end

#record_sib_version(sib_version) ⇒ Object



40
41
42
43
# File 'lib/seeing_is_believing/event_stream/producer.rb', line 40

def record_sib_version(sib_version)
  @version = sib_version
  queue << "sib_version #{to_string_token sib_version}"
end