File: support.rb

package info (click to toggle)
ruby-graphviz 1.0.8-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,124 kB
  • ctags: 695
  • sloc: ruby: 7,656; xml: 26; makefile: 17
file content (106 lines) | stat: -rw-r--r-- 2,656 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# comment out require rubygems line
# require 'rubygems'
require 'test/unit'
begin
require 'ruby-debug'
rescue LoadError
end
require 'stringio'

root = File.expand_path('../../lib',__FILE__)
$:.unshift(root) unless $:.include?(root)

require 'graphviz'

# hack so that the example scripts don't unnecessarily unshift @todo
class << $:
  def unshift path
    include?(path) ? self : super    # super will return self, too
  end
end

module TestSupport
  extend self

  # @todo move to app?
  def windows?
    /mswin|mingw/ =~ RUBY_PLATFORM
  end

  def dev_null
    windows? ? 'NUL' : '/dev/null'
  end
end

module IoHack

  #
  # this is a ridiculous hack to capture what was written to $stdout/$stderr for testing
  # an alternative is to use Open3.popen3 on external calls which has overhead
  # and OS dependencies.
  #
  # This hack would apparently not be as bad on 1.9, which would allow you to simply
  # set $stdout and $stderr to instances of StringIO
  #
  # I don't know what is the 'right way' to test this kind of thing
  #

  class IoHackStream < File
    #
    # pre 1.9 you can't assign $stdout and $stderr to anything other than
    # an IO::File instance.  what we *want* is to have them be StringIOs that
    # we can read from like strings for testing.  So this is a crazy proxy
    # around StringIO.    Note it makes *all* methods except a few protected,
    # which for me was failing silently when i forgot to make the appropriate
    # ones public.  hack!
    #

    except = %w(inspect kind_of?)
    except += except.map{|x| x.to_sym } # for Ruby 1.9
    these = ancestors[0].instance_methods
    # these = [1,2,3].map{|x| ancestors[x].instance_methods(false)}.flatten
    eraseme = (these - except)
    eraseme.each{ |name| protected name }
    attr_reader :io
    def initialize()
      @io = StringIO.new
      super(TestSupport.dev_null, 'r+') # probably doesn't matter the mode
    end
    these = %w(write << puts)
    these.each do |name|
      define_method(name) do |*a|
        @io.send(name, *a)
      end
    end
  end

  def fake_popen2 path
    push_io
    require path  # caller assumes responsibility for exceptions vis-a-vis stack
    pop_io
  end

  def io_stack
    @io_stack ||= []
  end

  def push_io
    io_stack.push [$stdout, $stderr]
    $stdout = IoHackStream.new
    $stderr = IoHackStream.new
    nil
  end

  def pop_io
    fail('stack empty') unless io_stack.any?
    result = [$stdout, $stderr]
    $stdout, $stderr = io_stack.pop
    result.each_with_index do |io,idx|
      if io.kind_of? IoHackStream
        io.io.seek(0)
        result[idx] = io.io.read
      end
    end
    result
  end
end