11#! /usr/bin/env python3
2+ from pathlib import Path
23import argparse
34import errno
4- import fnmatch
55import json
66import os
77import random
@@ -28,119 +28,133 @@ else:
2828 }
2929
3030
31- ROOT_DIR = os .path .abspath (
32- os .path .join (os .path .dirname (__file__ ), os .pardir ).rstrip ("__pycache__" ),
33- )
34- SUITE_ROOT_DIR = os .path .join (ROOT_DIR , "tests" )
35- REMOTES_DIR = os .path .join (ROOT_DIR , "remotes" )
36-
31+ ROOT_DIR = Path (__file__ ).parent .parent
32+ SUITE_ROOT_DIR = ROOT_DIR / "tests"
33+ REMOTES_DIR = ROOT_DIR / "remotes"
3734
38- with open (os .path .join (ROOT_DIR , "test-schema.json" )) as schema :
39- TESTSUITE_SCHEMA = json .load (schema )
35+ TESTSUITE_SCHEMA = json .loads ((ROOT_DIR / "test-schema.json" ).read_text ())
4036
4137
4238def files (paths ):
4339 """
44- Each test file in the provided paths.
40+ Each test file in the provided paths, as an array of test cases .
4541 """
4642 for path in paths :
47- with open (path ) as test_file :
48- yield json .load (test_file )
43+ yield json .loads (path .read_text ())
4944
5045
51- def groups (paths ):
46+ def cases (paths ):
5247 """
53- Each test group within each file in the provided paths.
48+ Each test case within each file in the provided paths.
5449 """
5550 for test_file in files (paths ):
56- for group in test_file :
57- yield group
51+ yield from test_file
5852
5953
60- def cases (paths ):
54+ def tests (paths ):
6155 """
62- Each individual test case within all groups within the provided paths.
56+ Each individual test within all cases within the provided paths.
6357 """
64- for test_group in groups (paths ):
65- for test in test_group ["tests" ]:
66- test ["schema" ] = test_group ["schema" ]
58+ for case in cases (paths ):
59+ for test in case ["tests" ]:
60+ test ["schema" ] = case ["schema" ]
6761 yield test
6862
6963
7064def collect (root_dir ):
7165 """
7266 All of the test file paths within the given root directory, recursively.
7367 """
74- for root , _ , files in os .walk (root_dir ):
75- for filename in fnmatch .filter (files , "*.json" ):
76- yield os .path .join (root , filename )
68+ return root_dir .glob ("**/*.json" )
7769
7870
7971class SanityTests (unittest .TestCase ):
8072 @classmethod
8173 def setUpClass (cls ):
82- print ("Looking for tests in %s" % SUITE_ROOT_DIR )
83- print ("Looking for remotes in %s" % REMOTES_DIR )
74+ print (f"Looking for tests in { SUITE_ROOT_DIR } " )
75+ print (f"Looking for remotes in { REMOTES_DIR } " )
76+
8477 cls .test_files = list (collect (SUITE_ROOT_DIR ))
85- cls .remote_files = list (collect (REMOTES_DIR ))
86- print ("Found %s test files" % len (cls .test_files ))
87- print ("Found %s remote files" % len (cls .remote_files ))
8878 assert cls .test_files , "Didn't find the test files!"
79+ print (f"Found { len (cls .test_files )} test files" )
80+
81+ cls .remote_files = list (collect (REMOTES_DIR ))
8982 assert cls .remote_files , "Didn't find the remote files!"
83+ print (f"Found { len (cls .remote_files )} remote files" )
9084
9185 def test_all_test_files_are_valid_json (self ):
86+ """
87+ All test files contain valid JSON.
88+ """
9289 for path in self .test_files :
93- with open (path ) as test_file :
94- try :
95- json .load (test_file )
96- except ValueError as error :
97- self .fail ("%s contains invalid JSON (%s)" % (path , error ))
90+ try :
91+ json .loads (path .read_text ())
92+ except ValueError as error :
93+ self .fail (f"{ path } contains invalid JSON ({ error } )" )
9894
9995 def test_all_remote_files_are_valid_json (self ):
96+ """
97+ All remote files contain valid JSON.
98+ """
10099 for path in self .remote_files :
101- with open (path ) as remote_file :
102- try :
103- json .load (remote_file )
104- except ValueError as error :
105- self .fail ("%s contains invalid JSON (%s)" % (path , error ))
100+ try :
101+ json .loads (path .read_text ())
102+ except ValueError as error :
103+ self .fail (f"{ path } contains invalid JSON ({ error } )" )
106104
107105 def test_all_descriptions_have_reasonable_length (self ):
108- for case in cases (self .test_files ):
109- description = case ["description" ]
106+ """
107+ All tests have reasonably long descriptions.
108+ """
109+ for count , test in enumerate (tests (self .test_files )):
110+ description = test ["description" ]
110111 self .assertLess (
111112 len (description ),
112113 70 ,
113- "%r is too long! (keep it to less than 70 chars)" % (
114- description ,
115- ),
114+ f"{ description !r} is too long! (keep it to less than 70 chars)"
116115 )
116+ print (f"Found { count } tests." )
117117
118118 def test_all_descriptions_are_unique (self ):
119- for group in groups (self .test_files ):
120- descriptions = set (test ["description" ] for test in group ["tests" ])
119+ """
120+ All test cases have unique test descriptions in their tests.
121+ """
122+ for count , case in enumerate (cases (self .test_files )):
123+ descriptions = set (test ["description" ] for test in case ["tests" ])
121124 self .assertEqual (
122125 len (descriptions ),
123- len (group ["tests" ]),
124- "%r contains a duplicate description" % ( group ,)
126+ len (case ["tests" ]),
127+ f" { case !r } contains a duplicate description",
125128 )
129+ print (f"Found { count } test cases." )
126130
127131 @unittest .skipIf (jsonschema is None , "Validation library not present!" )
128132 def test_all_schemas_are_valid (self ):
129- for version in os .listdir (SUITE_ROOT_DIR ):
130- Validator = VALIDATORS .get (version )
133+ """
134+ All schemas are valid under their metaschemas.
135+ """
136+ for version in SUITE_ROOT_DIR .iterdir ():
137+ if not version .is_dir ():
138+ continue
139+
140+ Validator = VALIDATORS .get (version .name )
131141 if Validator is not None :
132- test_files = collect (os . path . join ( SUITE_ROOT_DIR , version ) )
142+ test_files = collect (version )
133143 for case in cases (test_files ):
134144 try :
135145 Validator .check_schema (case ["schema" ])
136146 except jsonschema .SchemaError as error :
137- self .fail ("%s contains an invalid schema (%s)" %
138- (case , error ))
147+ self .fail (
148+ f"{ case } contains an invalid schema ({ error } )" ,
149+ )
139150 else :
140- warnings .warn ("No schema validator for %s" % schema )
151+ warnings .warn (f "No schema validator for { version . name } " )
141152
142153 @unittest .skipIf (jsonschema is None , "Validation library not present!" )
143154 def test_suites_are_valid (self ):
155+ """
156+ All test files are valid under test-schema.json.
157+ """
144158 Validator = jsonschema .validators .validator_for (TESTSUITE_SCHEMA )
145159 validator = Validator (TESTSUITE_SCHEMA )
146160 for tests in files (self .test_files ):
@@ -153,7 +167,7 @@ class SanityTests(unittest.TestCase):
153167def main (arguments ):
154168 if arguments .command == "check" :
155169 suite = unittest .TestLoader ().loadTestsFromTestCase (SanityTests )
156- result = unittest .TextTestRunner (verbosity = 2 ).run (suite )
170+ result = unittest .TextTestRunner ().run (suite )
157171 sys .exit (not result .wasSuccessful ())
158172 elif arguments .command == "flatten" :
159173 selected_cases = [case for case in cases (collect (arguments .version ))]
@@ -166,20 +180,17 @@ def main(arguments):
166180 remotes = {}
167181 for path in collect (REMOTES_DIR ):
168182 relative_path = os .path .relpath (path , REMOTES_DIR )
169- with open (path ) as schema_file :
170- remotes [relative_path ] = json .load (schema_file )
183+ remotes [relative_path ] = json .loads (path .read_text ())
171184 json .dump (remotes , sys .stdout , indent = 4 , sort_keys = True )
172185 elif arguments .command == "dump_remotes" :
173186 if arguments .update :
174187 shutil .rmtree (arguments .out_dir , ignore_errors = True )
175188
176189 try :
177190 shutil .copytree (REMOTES_DIR , arguments .out_dir )
178- except OSError as e :
179- if e .errno == errno .EEXIST :
180- print ("%s already exists. Aborting." % arguments .out_dir )
181- sys .exit (1 )
182- raise
191+ except FileExistsError :
192+ print (f"{ arguments .out_dir } already exists. Aborting." )
193+ sys .exit (1 )
183194 elif arguments .command == "serve" :
184195 try :
185196 import flask
0 commit comments