1import errno 2import os 3import sys 4import textwrap 5import unittest 6 7from subprocess import Popen, PIPE 8from test import support 9from test.support.script_helper import assert_python_ok 10 11 12class TestTool(unittest.TestCase): 13 data = """ 14 15 [["blorpie"],[ "whoops" ] , [ 16 ],\t"d-shtaeou",\r"d-nthiouh", 17 "i-vhbjkhnth", {"nifty":87}, {"morefield" :\tfalse,"field" 18 :"yes"} ] 19 """ 20 21 expect_without_sort_keys = textwrap.dedent("""\ 22 [ 23 [ 24 "blorpie" 25 ], 26 [ 27 "whoops" 28 ], 29 [], 30 "d-shtaeou", 31 "d-nthiouh", 32 "i-vhbjkhnth", 33 { 34 "nifty": 87 35 }, 36 { 37 "field": "yes", 38 "morefield": false 39 } 40 ] 41 """) 42 43 expect = textwrap.dedent("""\ 44 [ 45 [ 46 "blorpie" 47 ], 48 [ 49 "whoops" 50 ], 51 [], 52 "d-shtaeou", 53 "d-nthiouh", 54 "i-vhbjkhnth", 55 { 56 "nifty": 87 57 }, 58 { 59 "morefield": false, 60 "field": "yes" 61 } 62 ] 63 """) 64 65 jsonlines_raw = textwrap.dedent("""\ 66 {"ingredients":["frog", "water", "chocolate", "glucose"]} 67 {"ingredients":["chocolate","steel bolts"]} 68 """) 69 70 jsonlines_expect = textwrap.dedent("""\ 71 { 72 "ingredients": [ 73 "frog", 74 "water", 75 "chocolate", 76 "glucose" 77 ] 78 } 79 { 80 "ingredients": [ 81 "chocolate", 82 "steel bolts" 83 ] 84 } 85 """) 86 87 def test_stdin_stdout(self): 88 args = sys.executable, '-m', 'json.tool' 89 with Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc: 90 out, err = proc.communicate(self.data.encode()) 91 self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) 92 self.assertEqual(err, b'') 93 94 def _create_infile(self, data=None): 95 infile = support.TESTFN 96 with open(infile, "w", encoding="utf-8") as fp: 97 self.addCleanup(os.remove, infile) 98 fp.write(data or self.data) 99 return infile 100 101 def test_infile_stdout(self): 102 infile = self._create_infile() 103 rc, out, err = assert_python_ok('-m', 'json.tool', infile) 104 self.assertEqual(rc, 0) 105 self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) 106 self.assertEqual(err, b'') 107 108 def test_non_ascii_infile(self): 109 data = '{"msg": "\u3053\u3093\u306b\u3061\u306f"}' 110 expect = textwrap.dedent('''\ 111 { 112 "msg": "\\u3053\\u3093\\u306b\\u3061\\u306f" 113 } 114 ''').encode() 115 116 infile = self._create_infile(data) 117 rc, out, err = assert_python_ok('-m', 'json.tool', infile) 118 119 self.assertEqual(rc, 0) 120 self.assertEqual(out.splitlines(), expect.splitlines()) 121 self.assertEqual(err, b'') 122 123 def test_infile_outfile(self): 124 infile = self._create_infile() 125 outfile = support.TESTFN + '.out' 126 rc, out, err = assert_python_ok('-m', 'json.tool', infile, outfile) 127 self.addCleanup(os.remove, outfile) 128 with open(outfile, "r") as fp: 129 self.assertEqual(fp.read(), self.expect) 130 self.assertEqual(rc, 0) 131 self.assertEqual(out, b'') 132 self.assertEqual(err, b'') 133 134 def test_jsonlines(self): 135 args = sys.executable, '-m', 'json.tool', '--json-lines' 136 with Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE) as proc: 137 out, err = proc.communicate(self.jsonlines_raw.encode()) 138 self.assertEqual(out.splitlines(), self.jsonlines_expect.encode().splitlines()) 139 self.assertEqual(err, b'') 140 141 def test_help_flag(self): 142 rc, out, err = assert_python_ok('-m', 'json.tool', '-h') 143 self.assertEqual(rc, 0) 144 self.assertTrue(out.startswith(b'usage: ')) 145 self.assertEqual(err, b'') 146 147 def test_sort_keys_flag(self): 148 infile = self._create_infile() 149 rc, out, err = assert_python_ok('-m', 'json.tool', '--sort-keys', infile) 150 self.assertEqual(rc, 0) 151 self.assertEqual(out.splitlines(), 152 self.expect_without_sort_keys.encode().splitlines()) 153 self.assertEqual(err, b'') 154 155 @unittest.skipIf(sys.platform =="win32", "The test is failed with ValueError on Windows") 156 def test_broken_pipe_error(self): 157 cmd = [sys.executable, '-m', 'json.tool'] 158 proc = Popen(cmd, stdout=PIPE, stdin=PIPE) 159 # bpo-39828: Closing before json.tool attempts to write into stdout. 160 proc.stdout.close() 161 proc.communicate(b'"{}"') 162 self.assertEqual(proc.returncode, errno.EPIPE) 163