blob: 5ed04a78c793e9baadb60d8eccedc5c9ca46328f [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2020 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.data.impl;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import static org.eclipse.statet.rj.data.impl.AbstractRStore.DEFAULT_LONG_DATA_SEGMENT_LENGTH;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.rj.data.RCharacterStore;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;
@NonNullByDefault
public abstract class RCharacterStoreTest extends AbstractRStoreTest {
static class CharCaseData extends CaseData<RCharacterStore> {
static final Function<CharCaseData, RCharacterStore> REF_CONSTRUCTOR= new RCharacter32StoreTest()::createStore;
final String[] values;
public CharCaseData(final String label, final String[] values, final boolean[] nas) {
super(label, nas);
assert (values.length == this.length);
assert (nas.length == this.length);
this.values= values;
setReference(REF_CONSTRUCTOR.apply(this));
}
public CharCaseData(final String label, final String[] values) {
super(label, values.length);
assert (values.length == this.length);
this.values= values;
setReference(REF_CONSTRUCTOR.apply(this));
}
}
private static final Map<String, Boolean> LOGI_STRINGS;
static {
final var map= new LinkedHashMap<String, Boolean>();
for (final String s : List.<String>of("T", "TRUE", "True", "true")) {
map.put(s, Boolean.TRUE);
}
for (final String s : List.<String>of("F", "FALSE", "False", "false")) {
map.put(s, Boolean.FALSE);
}
LOGI_STRINGS= map;
}
protected static final List<CharCaseData> DEFAULT_DATA_SOURCES;
static {
final var datas= new ArrayList<CharCaseData>();
datas.add(new CharCaseData("empty", new @Nullable String[0]));
datas.add(new CharCaseData("single-empty", new String[] { "" }));
datas.add(new CharCaseData("single-1", new String[] { "1" }));
datas.add(new CharCaseData("single", new String[] { "abcdefghijkl" }));
datas.add(new CharCaseData("single-NA", new String[] { null }, new boolean[] { true }));
{ final String[] values= new String[LOGI_STRINGS.size() + 3];
final boolean[] nas= new boolean[values.length];
int i= 0;
for (final String string : LOGI_STRINGS.keySet()) {
values[i++]= string;
}
values[i++]= "TRue";
values[i++]= "falsE";
nas[i++]= true;
datas.add(new CharCaseData("logi", values, nas));
}
{ final Random rand= new Random(16857);
final String[] values= new String[100000];
for (int i= 0; i < values.length; i++) {
values[i]= Integer.toString(rand.nextInt());
}
datas.add(new CharCaseData("rand100000", values));
}
if (isBigDataEnabled(64)) {
final Random rand= new Random(46);
final String[] values= new String[DEFAULT_LONG_DATA_SEGMENT_LENGTH * 2 + 13];
for (int i= 0; i < values.length; i++) {
values[i]= Integer.toHexString(rand.nextInt());
}
datas.add(new CharCaseData("randMultiSeg", values));
}
DEFAULT_DATA_SOURCES= datas;
}
public RCharacterStoreTest() {
}
public static List<CharCaseData> provideCaseDatas() {
return new ArrayList<>(DEFAULT_DATA_SOURCES);
}
protected abstract RCharacterStore createStore(final CharCaseData data);
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getStoreType(final CharCaseData data) {
final RCharacterStore store= createStore(data);
assertEquals(RStore.CHARACTER, store.getStoreType());
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getBaseVectorRClassName(final CharCaseData data) {
final RCharacterStore store= createStore(data);
assertEquals(RObject.CLASSNAME_CHARACTER, store.getBaseVectorRClassName());
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void length(final CharCaseData data) {
final RCharacterStore store= createStore(data);
checkLength(data, store);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void isNA(final CharCaseData data) {
final RCharacterStore store= createStore(data);
checkIsNA(data, store);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void isMissing(final CharCaseData data) {
final RCharacterStore store= createStore(data);
checkIsMissingNonNum(data, store);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
@SuppressWarnings("boxing")
public void getLogi(final CharCaseData data) {
final RCharacterStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
try {
if (data.nas[i0]) {
// undefined
}
else {
final Boolean logi= LOGI_STRINGS.get(data.values[i0]);
if (logi != null) {
final boolean expected= logi.booleanValue();
assertEquals(expected, store.getLogi(i0), storeDiffersAt(i0));
assertEquals(expected, store.getLogi((long)i0), storeDiffersAt(i0));
}
else {
assertThrows(NumberFormatException.class, () -> store.getLogi(i0), storeDiffersAt(i0));
assertThrows(NumberFormatException.class, () -> store.getLogi((long)i0), storeDiffersAt(i0));
}
}
}
catch (final NumberFormatException e) {
fail(storeDiffersAt(i0).get(), e);
}
}
assertIndexOutOfBounds(data, store::getLogi, store::getLogi);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getInt(final CharCaseData data) {
final RCharacterStore store= createStore(data);
assertUnsupported(data, store::getInt, store::getInt);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getNum(final CharCaseData data) {
final RCharacterStore store= createStore(data);
assertUnsupported(data, store::getNum, store::getNum);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getChar(final CharCaseData data) {
final RCharacterStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
// undefined
}
else {
final String expected= data.values[i0];
assertEquals(expected, store.getChar(i0), storeDiffersAt(i0));
assertEquals(expected, store.getChar((long)i0), storeDiffersAt(i0));
}
}
assertIndexOutOfBounds(data, store::getChar, store::getChar);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void getRaw(final CharCaseData data) {
final RCharacterStore store= createStore(data);
assertUnsupported(data, store::getRaw, store::getRaw);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void get(final CharCaseData data) {
final RCharacterStore store= createStore(data);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
assertNull(store.get(i), storeDiffersAt(i0));
}
else {
final String expected= data.values[i0];
assertEquals(expected, store.get(i0));
assertEquals(expected, store.get((long)i0));
}
}
assertIndexOutOfBounds(data, store::get, store::get);
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void toArray(final CharCaseData data) {
final RCharacterStore store= createStore(data);
final @Nullable String[] array= store.toArray();
assertEquals(data.values.length, array.length);
for (int i= 0; i < data.length; i++) {
final int i0= i;
if (data.nas[i0]) {
assertNull(store.get(i), arrayDiffersAt(i0));
}
else {
final String expected= data.values[i0];
assertEquals(expected, array[i], arrayDiffersAt(i0));
}
}
}
@ParameterizedTest
@MethodSource("provideCaseDatas")
public void writeExternal(final CharCaseData data) throws IOException {
final RCharacterStore store= createStore(data);
if (store instanceof ExternalizableRStore) {
final byte[] ser= writeExternal(store);
assertArrayEquals(data.getExternalBytes(), ser);
}
}
}