1+ package com .azure .tools .apiview ;
2+
3+ import com .azure .tools .apiview .processor .Main ;
4+ import org .junit .jupiter .api .*;
5+ import org .junit .jupiter .params .*;
6+ import org .junit .jupiter .params .provider .*;
7+
8+ import java .net .URL ;
9+ import java .nio .file .*;
10+ import java .io .*;
11+ import java .util .stream .Stream ;
12+
13+ import static org .junit .jupiter .api .Assertions .*;
14+
15+ public class TestExpectedOutputs {
16+ // This is a flag to add a '-DELETE' suffix to the generated output file if the expected output file is missing.
17+ // By default we do, but if we want to regenerate a bunch of expected outputs, we can see this to false to save
18+ // having to rename.
19+ private static final boolean ADD_DELETE_PREFIX_FOR_MISSING_EXPECTED_OUTPUTS = true ;
20+
21+ private static final String root = "src/test/resources/" ;
22+ private static final File tempDir = new File (root + "temp" );
23+
24+ private static Stream <String > provideFileNames () {
25+ // This is a stream of local files or URLs to download the file from (or a combination of both). For each value,
26+ // if it starts with http, it'll try downloading the file into a temp location. If it sees no http, it'll look
27+ // for the file in the inputs directory. To prevent clogging up the repository with source jars, it is
28+ // preferable to download the source jars from known-good places.
29+ return Stream .of (
30+ ""
31+ // "https://repo1.maven.org/maven2/com/azure/azure-core/1.48.0/azure-core-1.48.0-sources.jar",
32+ // "https://repo1.maven.org/maven2/com/azure/azure-communication-chat/1.5.0/azure-communication-chat-1.5.0-sources.jar",
33+ // "https://repo1.maven.org/maven2/com/azure/azure-security-keyvault-keys/4.8.2/azure-security-keyvault-keys-4.8.2-sources.jar",
34+ // "https://repo1.maven.org/maven2/com/azure/azure-data-appconfiguration/1.6.0/azure-data-appconfiguration-1.6.0-sources.jar",
35+ // "https://repo1.maven.org/maven2/com/azure/azure-messaging-eventhubs/5.18.2/azure-messaging-eventhubs-5.18.2-sources.jar",
36+ // "https://repo1.maven.org/maven2/com/azure/azure-messaging-servicebus/7.15.2/azure-messaging-servicebus-7.15.2-sources.jar",
37+ // "https://repo1.maven.org/maven2/com/azure/azure-identity/1.12.0/azure-identity-1.12.0-sources.jar",
38+ // "https://repo1.maven.org/maven2/com/azure/azure-storage-blob/12.25.3/azure-storage-blob-12.25.3-sources.jar",
39+ // "https://repo1.maven.org/maven2/com/azure/azure-cosmos/4.57.0/azure-cosmos-4.57.0-sources.jar"
40+ );
41+ }
42+
43+ @ BeforeAll
44+ public static void setup () {
45+ tempDir .mkdirs ();
46+ }
47+
48+ @ ParameterizedTest
49+ @ MethodSource ("provideFileNames" )
50+ public void testGeneratedJson (String filenameOrUrl ) {
51+ if (filenameOrUrl .isEmpty ()) {
52+ return ;
53+ }
54+
55+ String filename ;
56+ Path inputFile ;
57+
58+ if (filenameOrUrl .startsWith ("http" )) {
59+ // download the file if it isn't local...
60+ filename = filenameOrUrl .substring (filenameOrUrl .lastIndexOf ('/' ) + 1 );
61+
62+ // download the file and save it to the temp directory
63+ String destinationFile = tempDir + "/" + filename ;
64+ downloadFile (filenameOrUrl , destinationFile );
65+
66+ // strip off the file extension
67+ filename = filename .substring (0 , filename .lastIndexOf ('.' ));
68+ inputFile = Paths .get (destinationFile );
69+ } else {
70+ // the file is local, so we can go straight to it
71+ filename = filenameOrUrl ;
72+ inputFile = Paths .get (root + "inputs/" + filename + ".jar" );
73+ }
74+
75+ final Path expectedOutputFile = Paths .get (root + "expected-outputs/" + filename + ".json" );
76+
77+ // Run the processor, receiving the name of the file that was generated
78+ final Path actualOutputFile = Main .run (inputFile .toFile (), tempDir ).toPath ();
79+
80+ if (expectedOutputFile .toFile ().exists ()) {
81+ try {
82+ // Compare the temporary file to the expected-outputs file
83+ assertArrayEquals (Files .readAllBytes (expectedOutputFile ), Files .readAllBytes (actualOutputFile ));
84+ } catch (IOException e ) {
85+ fail ("Failed to compare the actual output file with the expected output file." , e );
86+ }
87+ } else {
88+ // the test was never going to pass as we don't have an expected file to compare against.
89+ try {
90+ final String outputFile = root + "expected-outputs/" + filename + (ADD_DELETE_PREFIX_FOR_MISSING_EXPECTED_OUTPUTS ? "-DELETE" : "" ) + ".json" ;
91+ final Path suggestedOutputFile = Paths .get (outputFile );
92+
93+ if (!suggestedOutputFile .toFile ().getParentFile ().exists ()) {
94+ suggestedOutputFile .toFile ().getParentFile ().mkdirs ();
95+ }
96+ Files .move (actualOutputFile , suggestedOutputFile , StandardCopyOption .REPLACE_EXISTING );
97+ } catch (IOException e ) {
98+ // unable to move file
99+ e .printStackTrace ();
100+ }
101+ if (ADD_DELETE_PREFIX_FOR_MISSING_EXPECTED_OUTPUTS ) {
102+ fail ("Could not find expected output file for test. The output from the sources.jar was added into the " +
103+ "/expected-outputs directory, but with a '-DELETE' filename suffix. Please review and rename if it " +
104+ "should be included in the test suite." );
105+ } else {
106+ fail ("Could not find expected output file for test. The output from the sources.jar was added into the " +
107+ "/expected-outputs directory without any -DELETE suffix. It will be used next time the test is run!" );
108+
109+ }
110+ }
111+ }
112+
113+ @ AfterAll
114+ public static void tearDown () throws IOException {
115+ // Delete the temporary file
116+ if (tempDir .exists ()) {
117+ // delete everything in tempDir and then delete the directory
118+ Files .walk (tempDir .toPath ())
119+ .map (Path ::toFile )
120+ .forEach (File ::delete );
121+
122+ try {
123+ Files .delete (tempDir .toPath ());
124+ } catch (NoSuchFileException e ) {
125+ // ignore
126+ }
127+ }
128+ }
129+
130+ private static void downloadFile (String urlStr , String destinationFile ) {
131+ File file = new File (destinationFile );
132+ if (file .exists ()) {
133+ return ;
134+ }
135+ try (InputStream in = new URL (urlStr ).openStream ()) {
136+ Files .copy (in , file .toPath (), StandardCopyOption .REPLACE_EXISTING );
137+ } catch (IOException e ) {
138+ fail ("Failed to download and / or copy the given URL to the given destination { url: "
139+ + urlStr + ", destination: " + destinationFile + " }" );
140+ }
141+ }
142+ }
0 commit comments