587
589
return application
588
590
return result, applicationFactory
590
inputRead, appFactory = appFactoryFactory(
591
lambda input: [input.read(1), input.read()])
593
Request, appFactory, DummyChannel,
594
'GET', '1.1', [], [''], None, [],
597
inputRead.addCallback(
598
self.assertEqual, ['h', 'ello, world\nhow are you\n'])
600
# COMPATIBILITY NOTE: the size argument is excluded from the WSGI
601
# specification, but is provided here anyhow, because useful libraries
602
# such as python stdlib's cgi.py assume their input file-like-object
603
# supports readline with a size argument. If you use it, be aware your
604
# application may not be portable to other conformant WSGI servers.
605
inputReadline, appFactory = appFactoryFactory(
606
lambda input: [input.readline(), input.readline(None),
607
input.readline(-1), input.readline(20),
608
input.readline(5), input.readline(5),
611
Request, appFactory, DummyChannel,
612
'GET', '1.1', [], [''], None, [],
618
inputReadline.addCallback(
620
'hello, world\n', 'how are you\n', 'I am great\n',
621
'goodbye now\n', 'no da', 'ta he', 're\n'])
623
inputReadlineNonePOST, appFactory = appFactoryFactory(
624
lambda input: [input.readline(), input.readline(-1),
625
input.readline(None), input.readline(),
629
Request, appFactory, DummyChannel,
630
'POST', '1.1', [], [''], None, [
631
('Content-Type', 'multipart/form-data; boundary=---------------------------168072824752491622650073'),
632
('Content-Length', '130'),
634
"\n".join((["-----------------------------168072824752491622650073\n"
635
"Content-Disposition: form-data; name=\"search-query\"\n\n"
636
"this-is-my-search-query\n"])),
638
inputReadlineNonePOST.addCallback(
640
'-----------------------------168072824752491622650073\n',
641
'Content-Disposition: form-data; name="search-query"\n',
643
'this-is-my-search-query\n',
647
inputReadlinesNoArg, appFactory = appFactoryFactory(
648
lambda input: input.readlines())
650
Request, appFactory, DummyChannel,
651
'GET', '1.1', [], [''], None, [],
654
inputReadlinesNoArg.addCallback(
655
self.assertEqual, ["foo\n", "bar\n"])
658
inputReadlinesNone, appFactory = appFactoryFactory(
659
lambda input: input.readlines(None))
661
Request, appFactory, DummyChannel,
662
'GET', '1.1', [], [''], None, [],
665
inputReadlinesNone.addCallback(
666
self.assertEqual, ["foo\n", "bar\n"])
669
inputReadlinesLength, appFactory = appFactoryFactory(
670
lambda input: input.readlines(6))
672
Request, appFactory, DummyChannel,
673
'GET', '1.1', [], [''], None, [],
676
inputReadlinesLength.addCallback(
677
self.assertEqual, ["foo\n", "bar\n"])
680
inputIter, appFactory = appFactoryFactory(
681
lambda input: list(input))
683
Request, appFactory, DummyChannel,
684
'GET', '1.1', [], [''], None, [],
687
inputIter.addCallback(
688
self.assertEqual, ['foo\n', 'bar\n'])
690
return gatherResults([
691
inputRead, inputReadline, inputReadlineNonePOST,
692
inputReadlinesNoArg, inputReadlinesNone, inputReadlinesLength,
591
d, appFactory = appFactoryFactory(reader)
593
CustomizedRequest, appFactory, DummyChannel,
594
'PUT', '1.1', [], [''], None, [],
599
def test_readAll(self):
601
Calling L{_InputStream.read} with no arguments returns the entire input
604
bytes = "some bytes are here"
605
d = self._renderAndReturnReaderResult(lambda input: input.read(), bytes)
606
d.addCallback(self.assertEquals, bytes)
610
def test_readSome(self):
612
Calling L{_InputStream.read} with an integer returns that many bytes
613
from the input stream, as long as it is less than or equal to the total
614
number of bytes available.
616
bytes = "hello, world."
617
d = self._renderAndReturnReaderResult(lambda input: input.read(3), bytes)
618
d.addCallback(self.assertEquals, "hel")
622
def test_readMoreThan(self):
624
Calling L{_InputStream.read} with an integer that is greater than the
625
total number of bytes in the input stream returns all bytes in the
628
bytes = "some bytes are here"
629
d = self._renderAndReturnReaderResult(
630
lambda input: input.read(len(bytes) + 3), bytes)
631
d.addCallback(self.assertEquals, bytes)
635
def test_readTwice(self):
637
Calling L{_InputStream.read} a second time returns bytes starting from
638
the position after the last byte returned by the previous read.
640
bytes = "some bytes, hello"
644
d = self._renderAndReturnReaderResult(read, bytes)
645
d.addCallback(self.assertEquals, bytes[3:])
649
def test_readNone(self):
651
Calling L{_InputStream.read} with C{None} as an argument returns all
652
bytes in the input stream.
654
bytes = "the entire stream"
655
d = self._renderAndReturnReaderResult(
656
lambda input: input.read(None), bytes)
657
d.addCallback(self.assertEquals, bytes)
661
def test_readNegative(self):
663
Calling L{_InputStream.read} with a negative integer as an argument
664
returns all bytes in the input stream.
666
bytes = "all of the input"
667
d = self._renderAndReturnReaderResult(
668
lambda input: input.read(-1), bytes)
669
d.addCallback(self.assertEquals, bytes)
673
def test_readline(self):
675
Calling L{_InputStream.readline} with no argument returns one line from
678
bytes = "hello\nworld"
679
d = self._renderAndReturnReaderResult(
680
lambda input: input.readline(), bytes)
681
d.addCallback(self.assertEquals, "hello\n")
685
def test_readlineSome(self):
687
Calling L{_InputStream.readline} with an integer returns at most that
688
many bytes, even if it is not enough to make up a complete line.
690
COMPATIBILITY NOTE: the size argument is excluded from the WSGI
691
specification, but is provided here anyhow, because useful libraries
692
such as python stdlib's cgi.py assume their input file-like-object
693
supports readline with a size argument. If you use it, be aware your
694
application may not be portable to other conformant WSGI servers.
696
bytes = "goodbye\nworld"
697
d = self._renderAndReturnReaderResult(
698
lambda input: input.readline(3), bytes)
699
d.addCallback(self.assertEquals, "goo")
703
def test_readlineMoreThan(self):
705
Calling L{_InputStream.readline} with an integer which is greater than
706
the number of bytes in the next line returns only the next line.
708
bytes = "some lines\nof text"
709
d = self._renderAndReturnReaderResult(
710
lambda input: input.readline(20), bytes)
711
d.addCallback(self.assertEquals, "some lines\n")
715
def test_readlineTwice(self):
717
Calling L{_InputStream.readline} a second time returns the line
718
following the line returned by the first call.
720
bytes = "first line\nsecond line\nlast line"
723
return input.readline()
724
d = self._renderAndReturnReaderResult(readline, bytes)
725
d.addCallback(self.assertEquals, "second line\n")
729
def test_readlineNone(self):
731
Calling L{_InputStream.readline} with C{None} as an argument returns
732
one line from the input stream.
734
bytes = "this is one line\nthis is another line"
735
d = self._renderAndReturnReaderResult(
736
lambda input: input.readline(None), bytes)
737
d.addCallback(self.assertEquals, "this is one line\n")
741
def test_readlineNegative(self):
743
Calling L{_InputStream.readline} with a negative integer as an argument
744
returns one line from the input stream.
746
bytes = "input stream line one\nline two"
747
d = self._renderAndReturnReaderResult(
748
lambda input: input.readline(-1), bytes)
749
d.addCallback(self.assertEquals, "input stream line one\n")
753
def test_readlines(self):
755
Calling L{_InputStream.readlines} with no arguments returns a list of
756
all lines from the input stream.
758
bytes = "alice\nbob\ncarol"
759
d = self._renderAndReturnReaderResult(
760
lambda input: input.readlines(), bytes)
761
d.addCallback(self.assertEquals, ["alice\n", "bob\n", "carol"])
765
def test_readlinesSome(self):
767
Calling L{_InputStream.readlines} with an integer as an argument
768
returns a list of lines from the input stream with the argument serving
769
as an approximate bound on the total number of bytes to read.
771
bytes = "123\n456\n789\n0"
772
d = self._renderAndReturnReaderResult(
773
lambda input: input.readlines(5), bytes)
775
# Make sure we got enough lines to make 5 bytes. Anything beyond
777
self.assertEquals(lines[:2], ["123\n", "456\n"])
778
d.addCallback(cbLines)
782
def test_readlinesMoreThan(self):
784
Calling L{_InputStream.readlines} with an integer which is greater than
785
the total number of bytes in the input stream returns a list of all
786
lines from the input.
788
bytes = "one potato\ntwo potato\nthree potato"
789
d = self._renderAndReturnReaderResult(
790
lambda input: input.readlines(100), bytes)
793
["one potato\n", "two potato\n", "three potato"])
797
def test_readlinesAfterRead(self):
799
Calling L{_InputStream.readlines} after a call to L{_InputStream.read}
800
returns lines starting at the byte after the last byte returned by the
803
bytes = "hello\nworld\nfoo"
804
def readlines(input):
806
return input.readlines()
807
d = self._renderAndReturnReaderResult(readlines, bytes)
808
d.addCallback(self.assertEquals, ["orld\n", "foo"])
812
def test_readlinesNone(self):
814
Calling L{_InputStream.readlines} with C{None} as an argument returns
815
all lines from the input.
817
bytes = "one fish\ntwo fish\n"
818
d = self._renderAndReturnReaderResult(
819
lambda input: input.readlines(None), bytes)
820
d.addCallback(self.assertEquals, ["one fish\n", "two fish\n"])
824
def test_readlinesNegative(self):
826
Calling L{_InputStream.readlines} with a negative integer as an
827
argument returns a list of all lines from the input.
829
bytes = "red fish\nblue fish\n"
830
d = self._renderAndReturnReaderResult(
831
lambda input: input.readlines(-1), bytes)
832
d.addCallback(self.assertEquals, ["red fish\n", "blue fish\n"])
836
def test_iterable(self):
838
Iterating over L{_InputStream} produces lines from the input stream.
840
bytes = "green eggs\nand ham\n"
841
d = self._renderAndReturnReaderResult(lambda input: list(input), bytes)
842
d.addCallback(self.assertEquals, ["green eggs\n", "and ham\n"])
846
def test_iterableAfterRead(self):
848
Iterating over L{_InputStream} after calling L{_InputStream.read}
849
produces lines from the input stream starting from the first byte after
850
the last byte returned by the C{read} call.
852
bytes = "green eggs\nand ham\n"
856
d = self._renderAndReturnReaderResult(iterate, bytes)
857
d.addCallback(self.assertEquals, ["en eggs\n", "and ham\n"])
862
class InputStreamStringIOTests(InputStreamTestMixin, TestCase):
864
Tests for L{_InputStream} when it is wrapped around a L{StringIO.StringIO}.
866
def getFileType(self):
867
return StringIO.StringIO
871
class InputStreamCStringIOTests(InputStreamTestMixin, TestCase):
873
Tests for L{_InputStream} when it is wrapped around a
874
L{cStringIO.StringIO}.
876
def getFileType(self):
877
return cStringIO.StringIO
881
class InputStreamTemporaryFileTests(InputStreamTestMixin, TestCase):
883
Tests for L{_InputStream} when it is wrapped around a L{tempfile.TemporaryFile}.
885
def getFileType(self):
886
return tempfile.TemporaryFile