File: parser_spec.rb

package info (click to toggle)
ruby-httparty 0.13.7-1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 736 kB
  • sloc: ruby: 4,741; xml: 425; sh: 35; makefile: 11
file content (173 lines) | stat: -rw-r--r-- 5,593 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))

RSpec.describe HTTParty::Parser do
  describe ".SupportedFormats" do
    it "returns a hash" do
      expect(HTTParty::Parser::SupportedFormats).to be_instance_of(Hash)
    end
  end

  describe ".call" do
    it "generates an HTTParty::Parser instance with the given body and format" do
      expect(HTTParty::Parser).to receive(:new).with('body', :plain).and_return(double(parse: nil))
      HTTParty::Parser.call('body', :plain)
    end

    it "calls #parse on the parser" do
      parser = double('Parser')
      expect(parser).to receive(:parse)
      allow(HTTParty::Parser).to receive_messages(new: parser)
      parser = HTTParty::Parser.call('body', :plain)
    end
  end

  describe ".formats" do
    it "returns the SupportedFormats constant" do
      expect(HTTParty::Parser.formats).to eq(HTTParty::Parser::SupportedFormats)
    end

    it "returns the SupportedFormats constant for subclasses" do
      class MyParser < HTTParty::Parser
        SupportedFormats = {"application/atom+xml" => :atom}
      end
      expect(MyParser.formats).to eq({"application/atom+xml" => :atom})
    end
  end

  describe ".format_from_mimetype" do
    it "returns a symbol representing the format mimetype" do
      expect(HTTParty::Parser.format_from_mimetype("text/plain")).to eq(:plain)
    end

    it "returns nil when the mimetype is not supported" do
      expect(HTTParty::Parser.format_from_mimetype("application/atom+xml")).to be_nil
    end
  end

  describe ".supported_formats" do
    it "returns a unique set of supported formats represented by symbols" do
      expect(HTTParty::Parser.supported_formats).to eq(HTTParty::Parser::SupportedFormats.values.uniq)
    end
  end

  describe ".supports_format?" do
    it "returns true for a supported format" do
      allow(HTTParty::Parser).to receive_messages(supported_formats: [:json])
      expect(HTTParty::Parser.supports_format?(:json)).to be_truthy
    end

    it "returns false for an unsupported format" do
      allow(HTTParty::Parser).to receive_messages(supported_formats: [])
      expect(HTTParty::Parser.supports_format?(:json)).to be_falsey
    end
  end

  describe "#parse" do
    before do
      @parser = HTTParty::Parser.new('body', :json)
    end

    it "attempts to parse supported formats" do
      allow(@parser).to receive_messages(supports_format?: true)
      expect(@parser).to receive(:parse_supported_format)
      @parser.parse
    end

    it "returns the unparsed body when the format is unsupported" do
      allow(@parser).to receive_messages(supports_format?: false)
      expect(@parser.parse).to eq(@parser.body)
    end

    it "returns nil for an empty body" do
      allow(@parser).to receive_messages(body: '')
      expect(@parser.parse).to be_nil
    end

    it "returns nil for a nil body" do
      allow(@parser).to receive_messages(body: nil)
      expect(@parser.parse).to be_nil
    end

    it "returns nil for a 'null' body" do
      allow(@parser).to receive_messages(body: "null")
      expect(@parser.parse).to be_nil
    end

    it "returns nil for a body with spaces only" do
      allow(@parser).to receive_messages(body: "   ")
      expect(@parser.parse).to be_nil
    end

    it "does not raise exceptions for bodies with invalid encodings" do
      allow(@parser).to receive_messages(body: "\x80")
      allow(@parser).to receive_messages(supports_format?: false)
      expect(@parser.parse).to_not be_nil
    end
  end

  describe "#supports_format?" do
    it "utilizes the class method to determine if the format is supported" do
      expect(HTTParty::Parser).to receive(:supports_format?).with(:json)
      parser = HTTParty::Parser.new('body', :json)
      parser.send(:supports_format?)
    end
  end

  describe "#parse_supported_format" do
    it "calls the parser for the given format" do
      parser = HTTParty::Parser.new('body', :json)
      expect(parser).to receive(:json)
      parser.send(:parse_supported_format)
    end

    context "when a parsing method does not exist for the given format" do
      it "raises an exception" do
        parser = HTTParty::Parser.new('body', :atom)
        expect do
          parser.send(:parse_supported_format)
        end.to raise_error(NotImplementedError, "HTTParty::Parser has not implemented a parsing method for the :atom format.")
      end

      it "raises a useful exception message for subclasses" do
        atom_parser = Class.new(HTTParty::Parser) do
          def self.name
            'AtomParser'
          end
        end
        parser = atom_parser.new 'body', :atom
        expect do
          parser.send(:parse_supported_format)
        end.to raise_error(NotImplementedError, "AtomParser has not implemented a parsing method for the :atom format.")
      end
    end
  end

  context "parsers" do
    subject do
      HTTParty::Parser.new('body', nil)
    end

    it "parses xml with MultiXml" do
      expect(MultiXml).to receive(:parse).with('body')
      subject.send(:xml)
    end

    it "parses json with JSON" do
      expect(JSON).to receive(:parse).with('body', :quirks_mode => true, :allow_nan => true)
      subject.send(:json)
    end

    it "parses html by simply returning the body" do
      expect(subject.send(:html)).to eq('body')
    end

    it "parses plain text by simply returning the body" do
      expect(subject.send(:plain)).to eq('body')
    end

    it "parses csv with CSV" do
      expect(CSV).to receive(:parse).with('body')
      subject.send(:csv)
    end
  end
end