/*
* Copyright (C) 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.swift.generator;
import com.facebook.swift.testing.TestingUtils;
import java.net.URI;
import java.nio.file.Path;
import java.util.Iterator;
import com.google.common.collect.Lists;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static com.facebook.swift.testing.TestingUtils.getResourcePath;
import static com.facebook.swift.testing.TestingUtils.listDataProvider;
import static com.facebook.swift.testing.TestingUtils.listMatchingFiles;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.tools.Diagnostic.Kind;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.FileAssert.fail;
public class SwiftGeneratorTest {
private static final String outputFolderRoot = System.getProperty("test.output.directory");
@BeforeClass
public static void ensureRootFolder() {
Path outputPath = Paths.get(outputFolderRoot);
// Clean up output if it already exists
if (Files.isDirectory(outputPath)) {
try {
TestingUtils.deleteRecursively(outputPath);
} catch (IOException ex) {
fail("Unable to delete Swift output directory "
+ outputFolderRoot
+ " due to " + ex);
}
}
if (!outputPath.toFile().mkdirs()) {
fail("Unable to create Swift output directory " + outputFolderRoot);
}
}
@DataProvider
public Iterator<Object[]> thriftProvider()
throws Exception {
Path inputBase;
List<GenerationPaths> testFiles = Lists.newArrayList();
inputBase = getResourcePath("").resolve("basic");
for (Path input: listMatchingFiles(inputBase, "**/*.thrift")) {
testFiles.add(new GenerationPaths(input.toUri(), inputBase.toUri(), new URI[] {}));
}
inputBase = getResourcePath("").resolve("include_path_tests");
for (Path input: listMatchingFiles(inputBase, "**/*.thrift")) {
testFiles.add(
new GenerationPaths(
input.toUri(),
inputBase.toUri(),
new URI[] {
// Generate an absolute URI include path
getResourcePath("").resolve("include_path_1").toUri(),
// as well as a relative URI include path
URI.create("../include_path_2/"),
}));
}
return listDataProvider(testFiles);
}
@Test(dataProvider = "thriftProvider")
public void testGenerate(GenerationPaths paths) throws Exception {
// Create a nice output directory for these generated files
Path rootPath = getResourcePath("");
Path relativePath = rootPath.relativize(Paths.get(paths.getInputFile()));
String testPath = relativePath.toString().replace(
relativePath.getFileSystem().getSeparator(),
"_");
File outputDirectory = new File(outputFolderRoot, testPath);
File sourceDirectory = new File(outputDirectory, "source");
File classesDirectory = new File(outputDirectory, "classes");
final SwiftGeneratorConfig config = SwiftGeneratorConfig.builder()
.inputBase(paths.getInputBase())
.includeSearchPaths(Arrays.asList(paths.getIncludeSearchPaths()))
.outputFolder(sourceDirectory)
.generateIncludedCode(true)
.codeFlavor("java-immutable")
.defaultPackage("com.facebook.swift")
.addTweak(SwiftGeneratorTweak.ADD_CLOSEABLE_INTERFACE)
.addTweak(SwiftGeneratorTweak.EXTEND_RUNTIME_EXCEPTION)
.addTweak(SwiftGeneratorTweak.ADD_THRIFT_EXCEPTION)
.addTweak(SwiftGeneratorTweak.USE_PLAIN_JAVA_NAMESPACE)
.build();
final SwiftGenerator generator = new SwiftGenerator(config);
generator.parse(Collections.singletonList(paths.getInputFile()));
assertCompilation(
sourceDirectory.toPath(),
classesDirectory.toPath());
}
private void assertCompilation(Path sourceDirectory, Path outputDirectory) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<File> files = TestingUtils
.listMatchingFiles(
sourceDirectory,
"**/*.java")
.stream()
.map(p -> p.toFile())
.collect(Collectors.toList());
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
StandardJavaFileManager fileManager = compiler.
getStandardFileManager(diagnostics, null, null);
// Make sure the output directory exists
outputDirectory.toFile().mkdirs();
CompilationTask task = compiler.getTask(
null,
fileManager,
diagnostics,
Arrays.asList(
"-d",
outputDirectory.toAbsolutePath().toString()),
null,
fileManager.
getJavaFileObjectsFromFiles(files));
task.call();
// Make sure no errors
assertEquals(
0,
diagnostics.getDiagnostics()
.stream()
.filter(e -> e.getKind() == Kind.ERROR)
.count());
}
private static class GenerationPaths
{
private final URI inputFile;
private final URI inputBase;
private final URI[] includeSearchPaths;
private GenerationPaths(URI inputFile, URI inputBase, URI[] includeSearchPaths)
{
this.inputFile = inputFile;
this.inputBase = inputBase;
this.includeSearchPaths = includeSearchPaths;
}
public URI[] getIncludeSearchPaths()
{
return includeSearchPaths;
}
public URI getInputBase()
{
return inputBase;
}
public URI getInputFile()
{
return inputFile;
}
}
}