nablarch.test.core.entity.CharsetTestVariation Maven / Gradle / Ivy
The newest version!
package nablarch.test.core.entity;
import nablarch.core.util.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static nablarch.core.util.StringUtil.isNullOrEmpty;
/**
* 文字種のバリデーションテストの種類。
*
* @param テスト対象エンティティの型
* @author T.Kawasaki
*/
public class CharsetTestVariation {
/** 未入力許容可否のカラム名 */
private static final String ALLOW_EMPTY = "allowEmpty";
/** プロパティ名のカラム名 */
private static final String PROPERTY_NAME = "propertyName";
/** 桁数不正時のメッセージIDのカラム名 */
private static final String MESSAGE_ID_WHEN_INVALID_LENGTH = "messageIdWhenInvalidLength";
/** 未入力時のメッセージIDのカラム名 */
private static final String MESSAGE_ID_WHEN_EMPTY_INPUT = "messageIdWhenEmptyInput";
/** 文字が適応不可の場合のメッセージIDのカラム名 */
private static final String MESSAGE_ID_WHEN_NOT_APPLICABLE = "messageIdWhenNotApplicable";
/** 最長桁数のカラム名 */
private static final String MAX = "max";
/** 最短桁数のカラム名 */
private static final String MIN = "min";
/** Bean Validationのメッセージ補完用属性キーのカラム名 */
private static final String INTERPOLATE_KEY_PREFIX = "interpolateKey_";
/** Bean Validationのメッセージ補完用属性値のカラム名 */
private static final String INTERPOLATE_VALUE_PREFIX = "interpolateValue_";
/** 必須カラム */
private static final List REQUIRED_COLUMNS = Arrays.asList(
ALLOW_EMPTY,
PROPERTY_NAME,
MESSAGE_ID_WHEN_NOT_APPLICABLE,
MAX,
MIN
);
/** 文字種以外のカラム */
private static final List COLUMNS_EXCEPT_CHARSET = new ArrayList();
static {
COLUMNS_EXCEPT_CHARSET.addAll(REQUIRED_COLUMNS);
COLUMNS_EXCEPT_CHARSET.add(MESSAGE_ID_WHEN_INVALID_LENGTH);
COLUMNS_EXCEPT_CHARSET.add(MESSAGE_ID_WHEN_EMPTY_INPUT);
COLUMNS_EXCEPT_CHARSET.add(INTERPOLATE_KEY_PREFIX);
COLUMNS_EXCEPT_CHARSET.add(INTERPOLATE_VALUE_PREFIX);
}
/** OKマーク */
private static final String OK = "o";
/** 未入力を許容するか */
private final boolean isEmptyAllowed;
/** 桁数不正時のメッセージID */
private final String messageIdWhenInvalidLength;
/** 未入力時のメッセージID */
private final String messageIdWhenEmptyInput;
/** 適用不可時に期待するメッセージID */
private final String messageIdWhenNotApplicable;
/** 最大桁数 */
private final int max;
/** 最小桁数 */
private final int min;
/** 最大桁数欄は空欄か */
private final boolean isMaxEmpty;
/** 最小桁数欄は空欄か */
private final boolean isMinEmpty;
/** Bean Validationのメッセージ補完用属性のマップ */
private final Map options;
/** 文字種テスト情報のマップ */
private final Map charsetTestMap;
/** 単項目バリデーションテスト */
private final SingleValidationTester tester;
/** BeanValidationのグループ */
private final Class> group;
/**
* コンストラクタ。
*
* @param entityClass テスト対象エンティティクラス
* @param beanValidationGroup Bean Validationのグループ
* @param rowData 1行分のテストデータ
*/
public CharsetTestVariation(Class entityClass, Class> beanValidationGroup, Map rowData) {
// 必須カラム存在チェック
checkRequiredColumns(rowData);
// 最初に文字種の情報を抽出する
charsetTestMap = createCharsetMap(rowData);
// 未入力を許容するか
isEmptyAllowed = rowData.get(ALLOW_EMPTY).equals(OK);
// 桁数不正時のメッセージID
messageIdWhenInvalidLength = rowData.get(MESSAGE_ID_WHEN_INVALID_LENGTH);
// 未入力時のメッセージID
messageIdWhenEmptyInput = rowData.get(MESSAGE_ID_WHEN_EMPTY_INPUT);
// 文字種バリデーション失敗時のメッセージID
messageIdWhenNotApplicable = rowData.get(MESSAGE_ID_WHEN_NOT_APPLICABLE);
// 最長桁数(Nablarch Validationで最長桁数が指定されていない場合は実行時エラーとする)
String maxStr = rowData.get(MAX);
isMaxEmpty = isNullOrEmpty(maxStr);
if(isMaxEmpty &&
EntityTestConfiguration.getConfig().getValidationTestStrategy() instanceof NablarchValidationTestStrategy) {
// Nablarch Validationでは最大桁数の指定が必須。Bean Validationでは任意項目。
throw new IllegalArgumentException("max must be specified.");
}
max = isMaxEmpty ? Integer.MAX_VALUE : Integer.parseInt(maxStr);
// 最短桁数
String minStr = rowData.get(MIN);
isMinEmpty = isNullOrEmpty(minStr);
min = isMinEmpty
? (isEmptyAllowed ? 0 : 1) // 未入力許可時は最短0桁、必須の場合は1桁
: Integer.parseInt(minStr);
// Bean Validationのグループ
group = beanValidationGroup;
// Bean Validationのメッセージ補完用属性のマップ
options = createInterpolationMap(rowData);
// 単項目バリデーションテスト用クラス
tester = new SingleValidationTester(entityClass, rowData.get(PROPERTY_NAME));
}
/**
* 必須カラムの存在チェックを行う。
*
* @param testData テストデータ
*/
private void checkRequiredColumns(Map testData) {
if (testData == null) {
throw new IllegalArgumentException("testData must not be null.");
}
for (String column : REQUIRED_COLUMNS) {
if (!testData.containsKey(column)) {
throw new IllegalArgumentException(
"column [" + column + " is required. but was "
+ testData.keySet());
}
}
}
/**
* テストデータから文字種情報を抽出する。
*
* @param rowData 1行分のテストデータ
* @return 文字種情報のマップ
*/
private Map createCharsetMap(Map rowData) {
Map charsetMap = new HashMap();
boolean isCharset = true;
for(Map.Entry entry : rowData.entrySet()) {
String inputKey = entry.getKey();
for(String definedKey : COLUMNS_EXCEPT_CHARSET) {
if(inputKey.startsWith(definedKey)) {
isCharset = false;
break;
}
}
if(isCharset) {
charsetMap.put(inputKey, entry.getValue());
}
isCharset = true;
}
return charsetMap;
}
/**
* Bean Validationのメッセージ補完用属性情報を抽出する。
*
* @param rowData 1行分のテストデータ
* @return メッセージ補完用属性情報のマップ
*/
private Map createInterpolationMap(Map rowData) {
Map result = new HashMap();
for(int i = 1;; i++) {
String keyOfInterpolateKey = INTERPOLATE_KEY_PREFIX + i;
String keyOfInterpolateValue = INTERPOLATE_VALUE_PREFIX + i;
// i番目の補完用属性のキーがいずれか見つからない場合、その時点で抽出を終了する。
if(!(rowData.containsKey(keyOfInterpolateKey) && rowData.containsKey(keyOfInterpolateValue))) {
break;
}
String interpolateKey = rowData.get(keyOfInterpolateKey);
String interpolateValue = rowData.get(keyOfInterpolateValue);
if(StringUtil.isNullOrEmpty(interpolateKey)) {
continue;
}
result.put(interpolateKey, interpolateValue);
}
return result;
}
/**
* 適応可能なタイプを取得する。
*
* @return 適応可能なタイプ
*/
private String getApplicableType() {
for (Map.Entry e : charsetTestMap.entrySet()) {
if (e.getValue().equals(OK)) {
return e.getKey();
}
}
throw new IllegalStateException("can't find applicable charset type in [" + charsetTestMap + "]");
}
/** 全種類のテストを行う。 */
public void testAll() {
testMaxLength(); // 最長桁
testOverLimit(); // 最長桁 + 1
testMinLength(); // 最短桁
testUnderLimit(); // 最短桁 - 1
testEmptyInput(); // 未入力
testAllCharsetVariation(); // 文字種
}
/** 最長桁数のテストを行う。 */
public void testMaxLength() {
// maxが空の場合は、最大値に制限が無いことを意味するため、テストしない。
if(isMaxEmpty) {
return;
}
testValidationWithValidCharset(max, null, "max length test.");
}
/** 最短桁数のテストを行う。 */
public void testMinLength() {
testValidationWithValidCharset(min, null, "minimum length test.");
}
/** 最長桁数超過のテストを行う。 */
public void testOverLimit() {
// 最長桁がInteger.MAX_VALUEの場合はテストしない (オーバーフローしてしまうため)
if (max == Integer.MAX_VALUE) {
return;
}
Integer minLocal = isMinEmpty ? null : min;
String expectedMessageString = StringUtil.isNullOrEmpty(messageIdWhenInvalidLength)
? EntityTestConfiguration.getConfig().getOverLimitMessageId(max, minLocal) // デフォルトのメッセージを出力
: messageIdWhenInvalidLength; // テストケースで明示的に指定したメッセージを出力
testValidationWithValidCharset(max + 1, expectedMessageString, "over limit length test.");
}
/** 最短桁数不足のテストを行う。 */
public void testUnderLimit() {
// 最短桁が0桁の場合はテストしない(負の桁でテストできないので)
// 最短桁1桁の場合はテストしない(0桁のテストは未入力のテストでやる)
if (min <= 1) {
return;
}
Integer maxLocal = isMaxEmpty ? null : max;
String expectedMessageString = StringUtil.isNullOrEmpty(messageIdWhenInvalidLength)
? EntityTestConfiguration.getConfig().getUnderLimitMessageId(maxLocal, min) // デフォルトのメッセージを出力
: messageIdWhenInvalidLength; // テストケースで明示的に指定したメッセージを出力
testValidationWithValidCharset(min - 1, expectedMessageString, "under limit length test.");
}
/** 未入力のテストを行う。 */
public void testEmptyInput() {
String expectedRequiredMessage = StringUtil.isNullOrEmpty(messageIdWhenEmptyInput)
? EntityTestConfiguration.getConfig().getEmptyInputMessageId() // デフォルトのメッセージを出力
: messageIdWhenEmptyInput; // テストケースで明示的に指定したメッセージを出力
String expectedMessageString = (isEmptyAllowed)
? "" // 必須項目でない場合(メッセージが出ないこと)
: expectedRequiredMessage; // 必須項目の場合(メッセージが出力されること)
testValidationWithValidCharset(0, expectedMessageString, "empty input test.");
}
/** 適応可能な文字種のテストを行う。 */
public void testAllCharsetVariation() {
for (Map.Entry e : charsetTestMap.entrySet()) {
// 文字種
String charsetType = e.getKey();
// 期待するメッセージID
String expectedMessageString = e.getValue().equals(OK)
? "" // メッセージが出ないこと
: messageIdWhenNotApplicable; // 適用不可時のメッセージID
// 入力値
String param = generate(charsetType, Math.max(1, isMaxEmpty ? min : max));
// 単項目バリデーションを実行
tester.testSingleValidation(group, options, param, expectedMessageString, "charset type=[" + charsetType + "]");
}
}
/**
* 文字列を生成する。
*
* @param charsetType 生成する文字種
* @param length 文字列長
* @return 生成した文字列
*/
private String generate(String charsetType, int length) {
return EntityTestConfiguration.getConfig().getCharacterGenerator().generate(charsetType, length);
}
/**
* 適応可能な文字でバリデーションを行う。
*
* @param length 文字列長
* @param expectedMessageString 期待するメッセージ文字列
* @param msgOnFail テスト失敗時のメッセージ
*/
private void testValidationWithValidCharset(int length, String expectedMessageString,
String... msgOnFail) {
String charsetType = getApplicableType(); // 文字種
String param = generate(charsetType, length); // 入力値
tester.testSingleValidation(group, options, param, expectedMessageString, msgOnFail);
}
/**
* 固定長のプロパティであるかどうか判定する。
* 最短桁カラムが空欄の場合は、固定長とみなさない(偽を返却する。)
* 最長桁と最短桁が同値の場合、固定長とみなす(真を返却する)。
*
* @return 判定結果
*/
private boolean isFixedLength() {
return !isMinEmpty && min == max;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy