Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.cucumber.core.snippets;

import org.apiguardian.api.API;

import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

import static java.util.stream.Collectors.joining;

@API(status = API.Status.INTERNAL)
public final class GherkinKeywordNormalizer {

private GherkinKeywordNormalizer() {
/* no-op */
}

public static String normalizeKeyword(String language, String keyword) {
// Exception: Use the symbol names for the Emoj language.
// Emoji are not legal identifiers in Java.
if ("em".equals(language)) {
return normalizeEmojiKeyword(keyword);
}
return normalizeKeyword(keyword);
}

public static String normalizeLanguage(String language) {
return language.replaceAll("[\\s-]", "_").toLowerCase();
}

public static String capitalize(String str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't quite belong. Please make private and duplicate as needed.

return str.substring(0, 1).toUpperCase() + str.substring(1);
}

private static String normalizeKeyword(String keyword) {
return normalize(keyword.replaceAll("[\\s',!\u00AD’]", ""));
}

private static String normalizeEmojiKeyword(String keyword) {
String titleCasedName = getCodePoints(keyword).mapToObj(Character::getName)
.map(s -> s.split(" "))
.flatMap(Arrays::stream)
.map(String::toLowerCase)
.map(GherkinKeywordNormalizer::capitalize)
.collect(joining(" "));
return normalizeKeyword(titleCasedName);
}

private static String normalize(CharSequence s) {
return Normalizer.normalize(s, Normalizer.Form.NFC);
}

private static IntStream getCodePoints(String s) {
int length = s.length();
List<Integer> codePoints = new ArrayList<>();
for (int offset = 0; offset < length;) {
int codepoint = s.codePointAt(offset);
codePoints.add(codepoint);
offset += Character.charCount(codepoint);
}
return codePoints.stream().mapToInt(value -> value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,16 @@
import io.cucumber.plugin.event.StepArgument;

import java.lang.reflect.Type;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static io.cucumber.core.snippets.GherkinKeywordNormalizer.normalizeKeyword;
import static io.cucumber.core.snippets.SnippetType.CAMELCASE;
import static java.util.stream.Collectors.joining;

public final class SnippetGenerator {

Expand Down Expand Up @@ -72,7 +68,7 @@ private String createSnippet(
List<String> parameterNames = toParameterNames(expression, parameterNameGenerator);
Map<String, Type> arguments = arguments(step, parameterNames, expression.getParameterTypes());
return snippet.template().format(new String[] {
getNormalizedKeyWord(language, keyword),
normalizeKeyword(language, keyword),
snippet.escapePattern(source),
functionName,
snippet.arguments(arguments),
Expand All @@ -88,48 +84,6 @@ private List<String> toParameterNames(GeneratedExpression expression, Identifier
.collect(Collectors.toList());
}

private static String capitalize(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}

private static String getNormalizedKeyWord(String language, String keyword) {
// Exception: Use the symbol names for the Emoj language.
// Emoji are not legal identifiers in Java.
if ("em".equals(language)) {
return getNormalizedEmojiKeyWord(keyword);
}
return getNormalizedKeyWord(keyword);
}

private static String getNormalizedEmojiKeyWord(String keyword) {
String titleCasedName = getCodePoints(keyword).mapToObj(Character::getName)
.map(s -> s.split(" "))
.flatMap(Arrays::stream)
.map(String::toLowerCase)
.map(SnippetGenerator::capitalize)
.collect(joining(" "));
return getNormalizedKeyWord(titleCasedName);
}

private static IntStream getCodePoints(String s) {
int length = s.length();
List<Integer> codePoints = new ArrayList<>();
for (int offset = 0; offset < length;) {
int codepoint = s.codePointAt(offset);
codePoints.add(codepoint);
offset += Character.charCount(codepoint);
}
return codePoints.stream().mapToInt(value -> value);
}

private static String getNormalizedKeyWord(String keyword) {
return normalize(keyword.replaceAll("[\\s',!\u00AD’]", ""));
}

static String normalize(CharSequence s) {
return Normalizer.normalize(s, Normalizer.Form.NFC);
}

private String functionName(String sentence, IdentifierGenerator functionNameGenerator) {
String functionName = Stream.of(sentence)
.map(DEFAULT_ARGUMENT_PATTERN::replaceMatchesWithSpace)
Expand Down
46 changes: 5 additions & 41 deletions cucumber-java/src/codegen/java/GenerateI18n.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Normalizer;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static io.cucumber.core.snippets.GherkinKeywordNormalizer.normalizeKeyword;
import static io.cucumber.core.snippets.GherkinKeywordNormalizer.normalizeLanguage;
import static java.nio.file.Files.newBufferedWriter;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.util.stream.Collectors.joining;

/* This class generates the cucumber-java Interfaces and package-info
* based on the languages and keywords from the GherkinDialects
Expand Down Expand Up @@ -79,8 +78,8 @@ private void writeKeyWordAnnotations(GherkinDialect dialect) {
}

private void writeKeyWordAnnotation(GherkinDialect dialect, String keyword) {
String normalizedLanguage = getNormalizedLanguage(dialect);
String normalizedKeyword = getNormalizedKeyWord(dialect, keyword);
String normalizedLanguage = normalizeLanguage(dialect.getLanguage());
String normalizedKeyword = normalizeKeyword(dialect.getLanguage(), keyword);

Map<String, String> binding = new LinkedHashMap<>();
binding.put("lang", normalizedLanguage);
Expand All @@ -103,39 +102,8 @@ private void writeKeyWordAnnotation(GherkinDialect dialect, String keyword) {
}
}

private static String capitalize(String s) {
return s.substring(0, 1).toUpperCase() + s.substring(1);
}

private static String getNormalizedKeyWord(GherkinDialect dialect, String keyword) {
// Exception: Use the symbol names for the Emoj language.
// Emoji are not legal identifiers in Java.
if (dialect.getLanguage().equals("em")) {
return getNormalizedEmojiKeyWord(keyword);
}
return getNormalizedKeyWord(keyword);
}

private static String getNormalizedEmojiKeyWord(String keyword) {
String titleCasedName = keyword.codePoints().mapToObj(Character::getName)
.map(s -> s.split(" "))
.flatMap(Arrays::stream)
.map(String::toLowerCase)
.map(DialectWriter::capitalize)
.collect(joining(" "));
return getNormalizedKeyWord(titleCasedName);
}

private static String getNormalizedKeyWord(String keyword) {
return normalize(keyword.replaceAll("[\\s',!\u00AD’]", ""));
}

private static String normalize(CharSequence s) {
return Normalizer.normalize(s, Normalizer.Form.NFC);
}

private void writePackageInfo(GherkinDialect dialect) {
String normalizedLanguage = getNormalizedLanguage(dialect);
String normalizedLanguage = normalizeLanguage(dialect.getLanguage());
String languageName = dialect.getName();
if (!dialect.getName().equals(dialect.getNativeName())) {
languageName += " - " + dialect.getNativeName();
Expand All @@ -155,9 +123,5 @@ private void writePackageInfo(GherkinDialect dialect) {
}
}

private static String getNormalizedLanguage(GherkinDialect dialect) {
return dialect.getLanguage().replaceAll("[\\s-]", "_").toLowerCase();
}

}
}
45 changes: 5 additions & 40 deletions cucumber-java8/src/codegen/java/GenerateI18n.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Normalizer;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static io.cucumber.core.snippets.GherkinKeywordNormalizer.capitalize;
import static io.cucumber.core.snippets.GherkinKeywordNormalizer.normalizeKeyword;
import static io.cucumber.core.snippets.GherkinKeywordNormalizer.normalizeLanguage;
import static java.nio.file.Files.newBufferedWriter;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

/* This class generates the cucumber-java Interfaces and package-info
Expand Down Expand Up @@ -69,7 +69,7 @@ void writeDialect(GherkinDialect dialect) {
}

private void writeInterface(GherkinDialect dialect) {
String normalizedLanguage = getNormalizedLanguage(dialect);
String normalizedLanguage = normalizeLanguage(dialect.getLanguage());
String languageName = dialect.getName();
if (!dialect.getName().equals(dialect.getNativeName())) {
languageName += " - " + dialect.getNativeName();
Expand Down Expand Up @@ -98,43 +98,8 @@ private static List<String> extractKeywords(GherkinDialect dialect) {
.filter(it -> !it.contains(String.valueOf('*')))
.filter(it -> !it.matches("^\\d.*"))
.distinct()
.map(keyword -> getNormalizedKeyWord(dialect, keyword))
.map(keyword -> normalizeKeyword(dialect.getLanguage(), keyword))
.collect(toList());
}

private static String capitalize(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}

private static String getNormalizedKeyWord(GherkinDialect dialect, String keyword) {
// Exception: Use the symbol names for the Emoj language.
// Emoji are not legal identifiers in Java.
if (dialect.getLanguage().equals("em")) {
return getNormalizedEmojiKeyWord(keyword);
}
return getNormalizedKeyWord(keyword);
}

private static String getNormalizedEmojiKeyWord(String keyword) {
String titleCasedName = keyword.codePoints().mapToObj(Character::getName)
.map(s -> s.split(" "))
.flatMap(Arrays::stream)
.map(String::toLowerCase)
.map(DialectWriter::capitalize)
.collect(joining(" "));
return getNormalizedKeyWord(titleCasedName);
}

private static String getNormalizedKeyWord(String keyword) {
return normalize(keyword.replaceAll("[\\s',!\u00AD’]", ""));
}

static String normalize(CharSequence s) {
return Normalizer.normalize(s, Normalizer.Form.NFC);
}

private static String getNormalizedLanguage(GherkinDialect dialect) {
return dialect.getLanguage().replaceAll("[\\s-]", "_").toLowerCase();
}
}
}