
jmms.testing.fake.FakeExpr Maven / Gradle / Ivy
/*
* Copyright 2018 the original author or authors.
*
* 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 jmms.testing.fake;
import leap.lang.Randoms;
import leap.lang.Strings;
import leap.lang.json.JSON;
import leap.lang.reflect.Reflection;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class FakeExpr {
public static boolean isExpr(String s) {
return null != s && s.length() > 0 && s.indexOf("{{") >= 0 && s.indexOf("}}") >= 0;
}
private final DefaultFaker faker;
private final List nodes = new ArrayList<>();
public FakeExpr(DefaultFaker faker) {
this.faker = faker;
}
FakeExpr parse(String s) {
try {
int end = s.length() - 1;
StringBuilder t = new StringBuilder();
boolean lastNode = false;
for (int pos = 0; pos < s.length(); pos++) {
char c = s.charAt(pos);
if (c == '{' && pos < end && s.charAt(pos + 1) == '{') {
int close = s.indexOf("}}", pos + 1);
if (close > 0) {
if (t.length() > 0) {
nodes.add(new Text(t.toString()));
t.delete(0, t.length());
}
String expr = s.substring(pos + 2, close);
parseExpr(expr);
pos = close + 1;
lastNode = true;
continue;
}
} else if (c == '[' && pos < end && s.charAt(pos + 1) == '[') {
int close = s.indexOf("]]", pos + 1);
if (close > 0) {
if (t.length() > 0) {
nodes.add(new Text(t.toString()));
t.delete(0, t.length());
}
String expr = s.substring(pos + 2, close);
nodes.add(new Group(new FakeExpr(faker).parse(expr)));
pos = close + 1;
lastNode = true;
continue;
}
}
if (lastNode && t.length() == 0) {
if (c == '(' && pos < end && s.charAt(pos + 1) == '{') {
int close = s.indexOf("})", pos + 1);
if (close > 0) {
String expr = s.substring(pos + 1, close + 1);
nodes.get(nodes.size() - 1).withOptions(JSON.decode(expr, FakeOptions.class));
pos = close + 1;
lastNode = false;
continue;
}
}
}
lastNode = false;
t.append(c);
}
if (t.length() > 0) {
nodes.add(new Text(t.toString()));
}
}catch (RuntimeException e) {
throw new IllegalStateException("<- " + s + " -> , " + e.getMessage(), e);
}
return this;
}
void eval(Object sample, StringBuilder s) {
for(Node node : nodes) {
node.eval(sample, s);
}
}
private void parseExpr(String expr) {
//regex
if(expr.startsWith("^") && expr.endsWith("$")) {
nodes.add(new Regex(expr));
return;
}
//sample
if(expr.equalsIgnoreCase("sample")) {
nodes.add(new Sample());
return;
}
//samples
if(expr.startsWith("[") && expr.endsWith("]")) {
List list = JSON.decode(expr);
nodes.add(new Samples(list));
return;
}
//chars
if(expr.indexOf('#') >= 0 || expr.indexOf('?') >= 0 || expr.indexOf('*') >= 0) {
parseChars(expr);
return;
}
//fake
String key = expr;
String locale = null;
FakeOptions opts = null;
String[] parts = Strings.split(expr, "::");
if(parts.length == 2) {
key = parts[0];
locale = parts[1];
}
int left = key.indexOf('(');
if(left > 0) {
String json = key.substring(left+1,key.length()-1).trim();
key = key.substring(0, left);
if(Strings.isDigits(json)) {
FakeMethods.FakeMethod fm = faker.methods.get(key);
Class> type = FakeOptions.class;
if(null != fm) {
type = fm.getOptionsType();
}
opts = (FakeOptions)Reflection.newInstance(type);
opts.setLen(Integer.parseInt(json));
}else {
String[] nums = Strings.split(json, ',');
if(nums.length == 2 && Strings.isDigits(nums[0]) && Strings.isDigits(nums[1])) {
FakeMethods.FakeMethod fm = faker.methods.get(key);
Class> type = FakeOptions.class;
if(null != fm) {
type = fm.getOptionsType();
}
opts = (FakeOptions)Reflection.newInstance(type);
opts.setMinLen(Integer.parseInt(nums[0]));
opts.setMaxLen(Integer.parseInt(nums[1]));
}else {
if(!json.startsWith("{")) {
json = "{" + json + "}";
}
FakeMethods.FakeMethod fm = faker.methods.get(key);
Class> type = FakeOptions.class;
if(null != fm) {
type = fm.getOptionsType();
}
opts = (FakeOptions)JSON.decode(json, type);
}
}
}
if(null != opts) {
opts.setLocale(locale);
}
nodes.add(new Fake(key, locale, opts));
}
private void parseChars(String chars) {
for(int i=0;i 0) {
s.append(join);
}
expr.eval(sample, s);
}
}
}
}
private static class Text extends Node {
private final String str;
public Text(String str) {
this.str = str;
}
@Override
void eval(Object sample, StringBuilder s) {
s.append(str);
}
}
private static class Sample extends Node {
@Override
void eval(Object sample, StringBuilder s) {
if(null != sample) {
s.append(sample.toString());
}
}
}
private static class Samples extends Node {
private final List list;
private final Random random = new Random();
public Samples(List list) {
this.list = list;
}
@Override
void eval(Object sample, StringBuilder s) {
if(list.isEmpty()) {
return;
}
Object item = list.get(random.nextInt(list.size()));
if(null != item) {
s.append(item.toString());
}
}
}
private class Fake extends Node {
private final String key;
private final String locale;
private final FakeOptions opts;
public Fake(String key, String locale, FakeOptions opts) {
this.key = key;
this.locale = locale;
this.opts = null == opts ? FakeOptions.locale(locale) : opts;
}
@Override
void eval(Object sample, StringBuilder s) {
Object v = faker.tryFake(key, opts);
if(null != v) {
s.append(v.toString());
}else {
s.append("{{").append(key);
if(null != locale) {
s.append("::").append(locale);
}
s.append("}}");
}
}
}
private static class FixedChar extends Node {
private final char c;
public FixedChar(char c) {
this.c = c;
}
@Override
void eval(Object sample, StringBuilder s) {
s.append(c);
}
}
private static abstract class Chars extends Node {
protected int minLen = 1;
protected int maxLen = 1;
@Override
void eval(Object sample, StringBuilder s) {
int len = minLen == maxLen ? minLen : Randoms.nextInt(minLen, maxLen);
for(int i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy