* Most filters will now accept a file path argument instead of only reading
authorRobert Collins <robertc@robertcollins.net>
Sun, 25 Aug 2013 10:38:56 +0000 (22:38 +1200)
committerRobert Collins <robertc@robertcollins.net>
Sun, 25 Aug 2013 10:38:56 +0000 (22:38 +1200)
  from stdin. (Robert Collins, #409206)

NEWS
filters/subunit-1to2
filters/subunit-2to1
filters/subunit-filter
filters/subunit-ls
filters/subunit2pyunit
python/subunit/filters.py
python/subunit/tests/__init__.py
python/subunit/tests/test_filters.py [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 98b0320901c314ddb3c2a9eafe0e03c1cb255d02..78c251e4cd1f6d733e52c6f375346ca7aae60615 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,12 @@ BUG FIXES
 * V2 parser errors now set appropriate mime types for the encapsulated packet
   data and the error message. (Robert Collins)
 
+IMPROVEMENTS
+~~~~~~~~~~~~
+
+* Most filters will now accept a file path argument instead of only reading
+  from stdin. (Robert Collins, #409206)
+
 0.0.15
 ------
 
index bfb6658c35e8c559ebf321a4a5a76227c3e59af3..9725820cfc5f4f9b59aa23d57c82d2a050ded270 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 from testtools import ExtendedToStreamDecorator
 
 from subunit import StreamResultToBytes
-from subunit.filters import run_tests_from_stream
+from subunit.filters import find_stream, run_tests_from_stream
 
 
 def make_options(description):
@@ -33,7 +33,7 @@ def make_options(description):
 def main():
     parser = make_options(__doc__)
     (options, args) = parser.parse_args()
-    run_tests_from_stream(sys.stdin,
+    run_tests_from_stream(find_stream(sys.stdin, args),
         ExtendedToStreamDecorator(StreamResultToBytes(sys.stdout)))
     sys.exit(0)
 
index 36632dd3b3fe420e576615d1d54dcd63f42d8dbd..0072307f0fb7954da6e0096ec4dc2364c8237adf 100755 (executable)
@@ -22,7 +22,7 @@ import sys
 from testtools import StreamToExtendedDecorator
 
 from subunit import ByteStreamToStreamResult, TestProtocolClient
-from subunit.filters import run_tests_from_stream
+from subunit.filters import find_stream, run_tests_from_stream
 
 
 def make_options(description):
@@ -33,7 +33,8 @@ def make_options(description):
 def main():
     parser = make_options(__doc__)
     (options, args) = parser.parse_args()
-    case = ByteStreamToStreamResult(sys.stdin, non_subunit_name='stdout')
+    case = ByteStreamToStreamResult(
+        find_stream(sys.stdin, args), non_subunit_name='stdout')
     result = StreamToExtendedDecorator(TestProtocolClient(sys.stdout))
     # What about stdout chunks?
     result.startTestRun()
index 521b1988a0138e3fbaacf39cb24e0838d47ddde1..e9e2bb06325bfd5f23424248ab5cb676a149a526 100755 (executable)
@@ -38,7 +38,7 @@ from subunit import (
     StreamResultToBytes,
     read_test_list,
     )
-from subunit.filters import filter_by_result
+from subunit.filters import filter_by_result, find_stream
 from subunit.test_results import (
     and_predicates,
     make_tag_filter,
@@ -156,7 +156,8 @@ def main():
         output_path=None,
         passthrough=(not options.no_passthrough),
         forward=False,
-        protocol_version=2)
+        protocol_version=2,
+        input_stream=find_stream(sys.stdin, args))
     sys.exit(0)
 
 
index be4b29f3f03f744f4e87067cf063120083759237..8c6a1e7e8f54f701a4dd4240a76852e54e26aaf4 100755 (executable)
@@ -24,7 +24,7 @@ from testtools import (
     StreamSummary)
 
 from subunit import ByteStreamToStreamResult
-from subunit.filters import run_tests_from_stream
+from subunit.filters import find_stream, run_tests_from_stream
 from subunit.test_results import (
     CatFiles,
     TestIdPrintingResult,
@@ -41,7 +41,8 @@ parser.add_option("--exists", action="store_true",
 parser.add_option("--no-passthrough", action="store_true",
     help="Hide all non subunit input.", default=False, dest="no_passthrough")
 (options, args) = parser.parse_args()
-test = ByteStreamToStreamResult(sys.stdin, non_subunit_name="stdout")
+test = ByteStreamToStreamResult(
+    find_stream(sys.stdin, args), non_subunit_name="stdout")
 result = TestIdPrintingResult(sys.stdout, options.times, options.exists)
 if not options.no_passthrough:
     result = StreamResultRouter(result)
index 4737d6772bc066928e2cea296d94e14a967ffb93..d10ceea6f0991c4708efeba036751f1142643fc9 100755 (executable)
@@ -24,6 +24,7 @@ import unittest
 from testtools import StreamToExtendedDecorator, DecorateTestCaseResult, StreamResultRouter
 
 from subunit import ByteStreamToStreamResult
+from subunit.filters import find_stream
 from subunit.test_results import CatFiles
 
 parser = OptionParser(description=__doc__)
@@ -33,7 +34,8 @@ parser.add_option("--progress", action="store_true",
     help="Use bzrlib's test reporter (requires bzrlib)",
         default=False)
 (options, args) = parser.parse_args()
-test = ByteStreamToStreamResult(sys.stdin, non_subunit_name='stdout')
+test = ByteStreamToStreamResult(
+    find_stream(sys.stdin, args), non_subunit_name='stdout')
 def wrap_result(result):
     result = StreamToExtendedDecorator(result)
     if not options.no_passthrough:
index 5ad3c53d8094b05ccb4130dc7b4e467b566dd0c7..0a0a185c3e3858ee741d3fd97caddf887b058d04 100644 (file)
@@ -179,7 +179,8 @@ def run_filter_script(result_factory, description, post_run_hook=None,
     result = filter_by_result(
         result_factory, options.output_to, not options.no_passthrough,
         options.forward, protocol_version=protocol_version,
-        passthrough_subunit=passthrough_subunit)
+        passthrough_subunit=passthrough_subunit,
+        input_stream=find_stream(sys.stdin, args))
     if post_run_hook:
         post_run_hook(result)
     if not safe_hasattr(result, 'wasSuccessful'):
@@ -188,3 +189,18 @@ def run_filter_script(result_factory, description, post_run_hook=None,
         sys.exit(0)
     else:
         sys.exit(1)
+
+
+def find_stream(stdin, argv):
+    """Find a stream to use as input for filters.
+
+    :param stdin: Standard in - used if no files are named in argv.
+    :param argv: Command line arguments after option parsing. If one file
+        is named, that is opened in read only binary mode and returned.
+        A missing file will raise an exception, as will multiple file names.
+    """
+    assert len(argv) < 2, "Too many filenames."
+    if argv:
+        return open(argv[0], 'rb')
+    else:
+        return stdin
index 3552eff26e4afa6ac69156f931e888bd4d250b5f..a3caa38ce4d9aef242c4d8f465cee2352805b085 100644 (file)
@@ -19,6 +19,7 @@ from unittest import TestLoader
 from subunit.tests import (
     test_chunked,
     test_details,
+    test_filters,
     test_progress_model,
     test_run,
     test_subunit_filter,
@@ -34,6 +35,7 @@ def test_suite():
     loader = TestLoader()
     result = loader.loadTestsFromModule(test_chunked)
     result.addTest(loader.loadTestsFromModule(test_details))
+    result.addTest(loader.loadTestsFromModule(test_filters))
     result.addTest(loader.loadTestsFromModule(test_progress_model))
     result.addTest(loader.loadTestsFromModule(test_test_results))
     result.addTest(loader.loadTestsFromModule(test_test_protocol))
diff --git a/python/subunit/tests/test_filters.py b/python/subunit/tests/test_filters.py
new file mode 100644 (file)
index 0000000..0a5e7c7
--- /dev/null
@@ -0,0 +1,35 @@
+#
+#  subunit: extensions to Python unittest to get test results from subprocesses.
+#  Copyright (C) 2013  Robert Collins <robertc@robertcollins.net>
+#
+#  Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
+#  license at the users choice. A copy of both licenses are available in the
+#  project source as Apache-2.0 and BSD. You may not use this file except in
+#  compliance with one of these two licences.
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
+#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+#  license you chose for the specific language governing permissions and
+#  limitations under that license.
+#
+
+import sys
+from tempfile import NamedTemporaryFile
+
+from testtools import TestCase
+
+from subunit.filters import find_stream
+
+
+class TestFindStream(TestCase):
+
+    def test_no_argv(self):
+        self.assertEqual('foo', find_stream('foo', []))
+
+    def test_opens_file(self):
+        f = NamedTemporaryFile()
+        f.write(b'foo')
+        f.flush()
+        stream = find_stream('bar', [f.name])
+        self.assertEqual(b'foo', stream.read())