Feature/mustache lambda tests (#3447)

* Mustache lambda tests

* If lambda key is already taken in additionalProperties, throw an exception.

* Test whether common lambdas are registered in additionalProperties.
This commit is contained in:
Michal Foksa
2019-08-11 04:15:40 +02:00
committed by Jim Schubert
parent ac85c8f901
commit 42d6420400
9 changed files with 315 additions and 10 deletions

View File

@@ -240,13 +240,10 @@ public class DefaultCodegen implements CodegenConfig {
}
if (additionalProperties.containsKey("lambda")) {
LOGGER.warn("A property named 'lambda' already exists. Mustache lambdas renamed from 'lambda' to '_lambda'. " +
"You'll likely need to use a custom template, " +
"see https://github.com/OpenAPITools/openapi-generator/blob/master/docs/templating.md. ");
additionalProperties.put("_lambda", lambdas);
} else {
additionalProperties.put("lambda", lambdas);
LOGGER.error("A property called 'lambda' already exists in additionalProperties");
throw new RuntimeException("A property called 'lambda' already exists in additionalProperties");
}
additionalProperties.put("lambda", lambdas);
}
// override with any special post-processing for all models

View File

@@ -18,6 +18,8 @@
package org.openapitools.codegen;
import com.google.common.collect.Sets;
import com.samskivert.mustache.Mustache.Lambda;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
@@ -30,14 +32,19 @@ import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import io.swagger.v3.parser.core.models.ParseOptions;
import org.openapitools.codegen.languages.features.CXFServerFeatures;
import org.openapitools.codegen.templating.mustache.CamelCaseLambda;
import org.openapitools.codegen.templating.mustache.IndentedLambda;
import org.openapitools.codegen.templating.mustache.LowercaseLambda;
import org.openapitools.codegen.templating.mustache.TitlecaseLambda;
import org.openapitools.codegen.templating.mustache.UppercaseLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.*;
import java.util.stream.Collectors;
@@ -888,6 +895,7 @@ public class DefaultCodegenTest {
Assert.assertEquals(codegenModel.vars.size(), 1);
}
@Test
public void modelWithSuffixDoNotContainInheritedVars() {
DefaultCodegen codegen = new DefaultCodegen();
@@ -903,4 +911,25 @@ public class DefaultCodegenTest {
Assert.assertEquals(codegenModel.vars.size(), 1);
}
@Test
@SuppressWarnings("unchecked")
public void commonLambdasRegistrationTest() {
DefaultCodegen codegen = new DefaultCodegen();
Object lambdasObj = codegen.additionalProperties.get("lambda");
assertNotNull(lambdasObj, "Expecting lambda in additionalProperties");
Map<String, Lambda> lambdas = (Map<String, Lambda>) lambdasObj;
assertTrue(lambdas.get("lowercase") instanceof LowercaseLambda, "Expecting LowercaseLambda class");
assertTrue(lambdas.get("uppercase") instanceof UppercaseLambda, "Expecting UppercaseLambda class");
assertTrue(lambdas.get("titlecase") instanceof TitlecaseLambda, "Expecting TitlecaseLambda class");
assertTrue(lambdas.get("camelcase") instanceof CamelCaseLambda, "Expecting CamelCaseLambda class");
assertTrue(lambdas.get("indented") instanceof IndentedLambda, "Expecting IndentedLambda class");
assertTrue(lambdas.get("indented_8") instanceof IndentedLambda, "Expecting IndentedLambda class");
assertTrue(lambdas.get("indented_12") instanceof IndentedLambda, "Expecting IndentedLambda class");
assertTrue(lambdas.get("indented_16") instanceof IndentedLambda, "Expecting IndentedLambda class");
}
}

View File

@@ -0,0 +1,63 @@
package org.openapitools.codegen.templating.mustache;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.openapitools.codegen.CodegenConfig;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class CamelCaseLambdaTest extends LambdaTest {
@Mock
CodegenConfig generator;
@BeforeMethod
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void camelCaseTest() {
// Given
Map<String, Object> ctx = context("camelcase", new CamelCaseLambda());
// When & Then
test("inputText", "{{#camelcase}}Input-text{{/camelcase}}", ctx);
}
@Test
public void camelCaseReservedWordTest() {
// Given
Map<String, Object> ctx = context("camelcase", new CamelCaseLambda().generator(generator));
when(generator.sanitizeName(anyString())).then(returnsFirstArg());
when(generator.reservedWords()).thenReturn(new HashSet<String>(Arrays.asList("reservedWord")));
when(generator.escapeReservedWord("reservedWord")).thenReturn("escapedReservedWord");
// When & Then
test("escapedReservedWord", "{{#camelcase}}reserved-word{{/camelcase}}", ctx);
}
@Test
public void camelCaseEscapeParamTest() {
// Given
Map<String, Object> ctx = context("camelcase", new CamelCaseLambda()
.generator(generator).escapeAsParamName(true));
when(generator.sanitizeName(anyString())).then(returnsFirstArg());
when(generator.reservedWords()).thenReturn(new HashSet<String>());
when(generator.toParamName("inputText")).thenReturn("inputTextAsParam");
// When & Then
test("inputTextAsParam", "{{#camelcase}}Input_text{{/camelcase}}", ctx);
}
}

View File

@@ -0,0 +1,35 @@
package org.openapitools.codegen.templating.mustache;
import java.util.Map;
import org.testng.annotations.Test;
public class IndentedLambdaTest extends LambdaTest {
String lineSeparator = System.lineSeparator();
@Test
public void defaultIndentTest() {
// Given
Map<String, Object> ctx = context("indented", new IndentedLambda());
String lineSeparator = System.lineSeparator();
// When & Then
// IndentedLambda applies indentation from second line on of a template.
test("first line" + lineSeparator + " second line",
"{{#indented}}first line" + lineSeparator +"second line{{/indented}}", ctx);
}
@Test
public void indentedCountTest() {
// Given
Map<String, Object> ctx = context("indented", new IndentedLambda(8, " "));
// When & Then
// IndentedLambda applies indentation from second line on of a template.
test("first line" + lineSeparator + " second line",
"{{#indented}}first line" + lineSeparator +"second line{{/indented}}", ctx);
}
}

View File

@@ -0,0 +1,44 @@
package org.openapitools.codegen.templating.mustache;
import static org.testng.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import com.samskivert.mustache.Mustache;
/**
* Simple framework to test Mustache Lambdas. It avoids
* <pre>compiler->compile->execute->assert</pre>
* boilerplate code.
*
* Inspired by <a href="https://github.com/samskivert/jmustache/blob/master/src/test/java/com/samskivert/mustache/SharedTests.java">Jmustache SharedTests.java</a>
*
*/
public abstract class LambdaTest {
protected String execute(String template, Object ctx) {
return execute(Mustache.compiler(), template, ctx);
}
protected String execute(Mustache.Compiler compiler, String template, Object ctx) {
return compiler.compile(template).execute(ctx);
}
protected void test(String expected, String template, Map<String, Object> ctx) {
test(Mustache.compiler(), expected, template, ctx);
}
protected void test(Mustache.Compiler compiler, String expected,String template, Map<String, Object> ctx) {
assertEquals(execute(compiler, template, ctx), expected);
}
protected static Map<String, Object> context(Object... data) {
Map<String, Object> ctx = new HashMap<String, Object>();
for (int ii = 0; ii < data.length; ii += 2) {
ctx.put(data[ii].toString(), data[ii + 1]);
}
return ctx;
}
}

View File

@@ -0,0 +1,49 @@
package org.openapitools.codegen.templating.mustache;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.openapitools.codegen.CodegenConfig;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class LowercaseLambdaTest extends LambdaTest {
@Mock
CodegenConfig generator;
@BeforeMethod
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void lowercaseTest() {
// Given
Map<String, Object> ctx = context("lowercase", new LowercaseLambda());
// When & Then
test("input text", "{{#lowercase}}InPut Text{{/lowercase}}", ctx);
}
@Test
public void lowercaseReservedWordTest() {
// Given
Map<String, Object> ctx = context("lowercase", new LowercaseLambda().generator(generator));
when(generator.sanitizeName(anyString())).then(returnsFirstArg());
when(generator.reservedWords()).thenReturn(new HashSet<String>(Arrays.asList("reserved")));
when(generator.escapeReservedWord("reserved")).thenReturn("escaped-reserved");
// When & Then
test("escaped-reserved", "{{#lowercase}}rEservEd{{/lowercase}}", ctx);
}
}

View File

@@ -0,0 +1,42 @@
package org.openapitools.codegen.templating.mustache;
import java.util.Map;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class OnChangeLambdaTest extends LambdaTest {
private Map<String, Object> ctx;
// OnChangeLambda holds internal state it is important that context is
// reinitialize before each test.
@BeforeMethod
public void setup() {
ctx = context("onchange", new OnChangeLambda());
}
@Test
public void firstValueIsReturnedTest() {
// Given
// When & Then
test("first", "{{#onchange}}first{{/onchange}}", ctx);
}
@Test
public void repeatingValueReturnedOnFirstOccurrenceTest() {
// Given
// When & Then
test("First", "{{#onchange}}First{{/onchange}}", ctx);
test("", "{{#onchange}}First{{/onchange}}", ctx);
test("Another", "{{#onchange}}Another{{/onchange}}", ctx);
test("", "{{#onchange}}Another{{/onchange}}", ctx);
test("", "{{#onchange}}Another{{/onchange}}", ctx);
test("First", "{{#onchange}}First{{/onchange}}", ctx);
}
}

View File

@@ -0,0 +1,28 @@
package org.openapitools.codegen.templating.mustache;
import java.util.Map;
import org.testng.annotations.Test;
public class TitlecaseLambdaTest extends LambdaTest {
@Test
public void titlecaseTest() {
// Given
Map<String, Object> ctx = context("titlecase", new TitlecaseLambda());
// When & Then
test("Once Upon A Time", "{{#titlecase}}once upon a time{{/titlecase}}", ctx);
}
@Test
public void titlecaseWithDelimiterTest() {
// Given
Map<String, Object> ctx = context("titlecase", new TitlecaseLambda("-"));
// When & Then
test("Once-Upon-A-Time", "{{#titlecase}}once-upon-a-time{{/titlecase}}", ctx);
}
}

View File

@@ -0,0 +1,18 @@
package org.openapitools.codegen.templating.mustache;
import java.util.Map;
import org.testng.annotations.Test;
public class UppercaseLambdaTest extends LambdaTest {
@Test
public void uppercaseTest() {
// Given
Map<String, Object> ctx = context("uppercase", new UppercaseLambda());
// When & Then
test("INPUT TEXT", "{{#uppercase}}InPut Text{{/uppercase}}", ctx);
}
}