File: mock.rb

package info (click to toggle)
ruby-em-http-request 0.3.0-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 424 kB
  • sloc: ruby: 2,381; ansic: 999; makefile: 2
file content (137 lines) | stat: -rw-r--r-- 3,826 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
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
module EventMachine
  OriginalHttpRequest = HttpRequest unless const_defined?(:OriginalHttpRequest)

  class MockHttpRequest < EventMachine::HttpRequest

    include HttpEncoding

    class RegisteredRequest < Struct.new(:uri, :method, :headers)
      def self.build(uri, method, headers)
        new(uri, method.to_s.upcase, headers || {})
      end
    end

    class FakeHttpClient < EventMachine::HttpClient
      attr_writer :response
      attr_reader :data
      def setup(response, uri)
        @uri = uri
        if response == :fail
          fail(self)
        else
          if response.respond_to?(:call)
            response.call(self)
            @state = :body
          else
            receive_data(response)
          end
          @state == :body ? succeed(self) : fail(self)
        end
      end

      def unbind
      end
    end

    @@registry = Hash.new
    @@registry_count = Hash.new{|h,k| h[k] = 0}

    def self.use
      activate!
      yield
    ensure
      deactivate!
    end

    def self.activate!
      EventMachine.send(:remove_const, :HttpRequest)
      EventMachine.send(:const_set, :HttpRequest, MockHttpRequest)
    end

    def self.deactivate!
      EventMachine.send(:remove_const, :HttpRequest)
      EventMachine.send(:const_set, :HttpRequest, OriginalHttpRequest)
    end

    def self.reset_counts!
      @@registry_count.clear
    end

    def self.reset_registry!
      @@registry.clear
    end

    @@pass_through_requests = true

    def self.pass_through_requests=(pass_through_requests)
      @@pass_through_requests = pass_through_requests
    end

    def self.pass_through_requests
      @@pass_through_requests
    end

    def self.parse_register_args(args, &proc)
      args << proc{|client| proc.call(client); ''} if proc
      headers, data = case args.size
      when 3
        args[2].is_a?(Hash) ?
          [args[2][:headers], args[2][:data]] :
          [{}, args[2]]
      when 4
        [args[2], args[3]]
      else
        raise
      end

      url = args[0]
      method = args[1]
      [headers, url, method, data]
    end

    def self.register(*args, &proc)
      headers, url, method, data = parse_register_args(args, &proc)
      @@registry[RegisteredRequest.build(url, method, headers)] = data
    end

    def self.register_file(*args)
      headers, url, method, data = parse_register_args(args)
      @@registry[RegisteredRequest.build(url, method, headers)] = File.read(data)
    end

    def self.count(url, method, headers = {})
      @@registry_count[RegisteredRequest.build(url, method, headers)]
    end

    def self.registered?(url, method, headers = {})
      @@registry.key?(RegisteredRequest.build(url, method, headers))
    end

    def self.registered_content(url, method, headers = {})
      @@registry[RegisteredRequest.build(url, method, headers)]
    end

    def self.increment_access(url, method, headers = {})
      @@registry_count[RegisteredRequest.build(url, method, headers)] += 1
    end

    alias_method :real_send_request, :send_request

    protected
    def send_request(&blk)
      query = "#{@req.uri.scheme}://#{@req.uri.host}:#{@req.uri.port}#{encode_query(@req.uri, @req.options[:query])}"
      headers = @req.options[:head]
      if self.class.registered?(query, @req.method, headers)
        self.class.increment_access(query, @req.method, headers)
        client = FakeHttpClient.new(nil)
        content = self.class.registered_content(query, @req.method, headers)
        client.setup(content, @req.uri)
        client
      elsif @@pass_through_requests
        real_send_request
      else
        raise "this request #{query} for method #{@req.method} with the headers #{@req.options[:head].inspect} isn't registered, and pass_through_requests is current set to false"
      end
    end
  end
end