Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1712 from matthewdunsdon/1710-prevent-multiple-we…
Browse files Browse the repository at this point in the history
…ighted-insets

Prevent multiple weighted insets
  • Loading branch information
willsalt-sl authored Jan 5, 2021
2 parents bf492a5 + 71bf10a commit 74cb502
Show file tree
Hide file tree
Showing 70 changed files with 918 additions and 779 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.scottlogic.datahelix.generator.common.whitelist;
package com.scottlogic.datahelix.generator.common.distribution;

import com.scottlogic.datahelix.generator.common.RandomNumberGenerator;

Expand Down Expand Up @@ -54,16 +54,6 @@ public static <T> DistributedList<T> singleton(final T element) {
return DistributedList.uniform(Collections.singleton(element));
}

public static <T> DistributedList<T> weightedOrDefault(final Collection<T> underlyingSet) {
return new DistributedList<>(
underlyingSet.stream()
.map(element -> element instanceof WeightedElement
? (WeightedElement<T>) element
: WeightedElement.withDefaultWeight(element)
)
.collect(Collectors.toList()));
}

public static <T> DistributedList<T> uniform(final Collection<T> underlyingSet) {
return new DistributedList<>(
underlyingSet.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.scottlogic.datahelix.generator.common.whitelist;
package com.scottlogic.datahelix.generator.common.distribution;

import java.util.Objects;
import java.util.function.Function;
Expand Down Expand Up @@ -51,6 +51,10 @@ public double weight() {
return weight;
}

public <F> WeightedElement<F> withMappedValue(Function<E, F> parse) {
return new WeightedElement<F>(parse.apply(element), weight);
}

public static <T> WeightedElement<T> withDefaultWeight(final T element) {
return new WeightedElement<>(element, DEFAULT_WEIGHT);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright 2019-2021 Scott Logic Ltd
*
* 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 com.scottlogic.datahelix.generator.common.profile;

import java.util.Objects;
import java.util.function.Function;

public class InSetRecord {
private static final double DEFAULT_WEIGHT = 1.0;
private final Object element;
private final Double weight;

public InSetRecord(Object element) {
this(element, null);
}

public InSetRecord(Object element, double weight) {
this(element, (Double)weight);
}

public InSetRecord(Object element, Double weight) {
this.element = element;
this.weight = weight;
}

public Object getElement() {
return element;
}

public boolean hasWeightPresent() {
return weight != null;
}

public double getWeightValueOrDefault() {
return weight != null ? weight : DEFAULT_WEIGHT;
}

public InSetRecord mapValue(Function<Object, Object> parse) {
Object value = parse.apply(element);

return weight != null
? new InSetRecord(value, weight)
: new InSetRecord(value);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InSetRecord that = (InSetRecord) o;

if (!Objects.equals(element, that.element)) {
return false;
}
return weight == null || that.weight == null
? Objects.equals(weight, that.weight)
: Double.compare(weight, that.weight) == 0;
}

@Override
public int hashCode() {
return Objects.hash(element, weight);
}

@Override
public String toString() {
return "InSetRecord{" +
"element=" + element +
", weight=" + weight +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.scottlogic.datahelix.generator.common.whitelist;
package com.scottlogic.datahelix.generator.common.distribution;

import com.scottlogic.datahelix.generator.common.RandomNumberGenerator;
import org.junit.jupiter.api.Test;
Expand All @@ -25,7 +25,9 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;
import static com.scottlogic.datahelix.generator.common.distribution.WeightedElement.withDefaultWeight;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -54,8 +56,12 @@ public void testUniformGeneratesUniformDistribution() {

DistributedList<String> manualSet = new DistributedList<>(weightedElements);

List<String> elements = Arrays.asList("first", "second", "third");
DistributedList<String> uniformSet = DistributedList.uniform(elements);
List<WeightedElement<String>> elements = Arrays.asList(
withDefaultWeight("first"),
withDefaultWeight("second"),
withDefaultWeight("third")
);
DistributedList<String> uniformSet = new DistributedList(elements);

assertEquals(manualSet, uniformSet);
}
Expand All @@ -78,7 +84,7 @@ public void testWeightedOrDefaultPassesThroughWeightedElements() {
DistributedList<String> manualSet = new DistributedList<>(manualElements);

List<WeightedElement<String>> elements = Arrays.asList(first, second, third);
DistributedList<WeightedElement<String>> weightedSet = DistributedList.weightedOrDefault(elements);
DistributedList<WeightedElement<String>> weightedSet = new DistributedList(elements);

assertEquals(manualSet, weightedSet);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.scottlogic.datahelix.generator.common.whitelist;
package com.scottlogic.datahelix.generator.common.distribution;

import org.junit.jupiter.api.Test;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
import com.scottlogic.datahelix.generator.core.generation.fieldvaluesources.FieldValueSource;
import com.scottlogic.datahelix.generator.core.generation.fieldvaluesources.NullAppendingValueSource;

import java.util.Optional;

public abstract class FieldSpec {
public abstract boolean canCombineWithWhitelistValue(Object value);
public abstract boolean canCombineWithLegalValue(Object value);
public abstract FieldValueSource getFieldValueSource();
public abstract Optional<FieldSpec> merge(FieldSpec other, boolean useFinestGranularityAvailable);
public abstract FieldSpec withNotNull();

protected final boolean nullable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,23 @@

package com.scottlogic.datahelix.generator.core.fieldspecs;

import com.scottlogic.datahelix.generator.common.distribution.DistributedList;
import com.scottlogic.datahelix.generator.common.distribution.WeightedElement;
import com.scottlogic.datahelix.generator.common.profile.FieldType;
import com.scottlogic.datahelix.generator.common.profile.InSetRecord;
import com.scottlogic.datahelix.generator.common.util.Defaults;
import com.scottlogic.datahelix.generator.common.whitelist.DistributedList;
import com.scottlogic.datahelix.generator.core.generation.fieldvaluesources.FieldValueSource;
import com.scottlogic.datahelix.generator.core.restrictions.TypedRestrictions;
import com.scottlogic.datahelix.generator.core.restrictions.bool.BooleanRestrictions;

import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.scottlogic.datahelix.generator.core.restrictions.linear.LinearRestrictionsFactory.*;
import static com.scottlogic.datahelix.generator.core.restrictions.string.StringRestrictionsFactory.forMaxLength;
import static java.util.Collections.singletonList;

public class FieldSpecFactory {
private static final NullOnlyFieldSpec NULL_ONLY_FIELD_SPEC = new NullOnlyFieldSpec();
Expand All @@ -36,8 +41,29 @@ private FieldSpecFactory() {
throw new IllegalArgumentException("Should not instantiate factory");
}

public static WhitelistFieldSpec fromList(DistributedList<Object> whitelist) {
return new WhitelistFieldSpec(whitelist, true);
public static LegalValuesFieldSpec fromLegalValuesList(List<Object> legalValues) {
return new LegalValuesFieldSpec(legalValues, true);
}

public static LegalValuesFieldSpec fromSingleLegalValue(Object legalValue) {
return new LegalValuesFieldSpec(singletonList(legalValue), true);
}

public static FieldSpec fromInSetRecords(List<InSetRecord> inSetRecords) {
if (inSetRecords.stream().anyMatch(InSetRecord::hasWeightPresent)) {
DistributedList<Object> distributedList = new DistributedList<>(inSetRecords.stream()
.map(v -> new WeightedElement<>(v.getElement(), v.getWeightValueOrDefault()))
.collect(Collectors.toList()));

return new WeightedLegalValuesFieldSpec(distributedList, true);
} else {
List<Object> legalValues = inSetRecords.stream().map(InSetRecord::getElement).collect(Collectors.toList());
return new LegalValuesFieldSpec(legalValues, true);
}
}

public static WeightedLegalValuesFieldSpec fromList(DistributedList<Object> weightedLegalValues) {
return new WeightedLegalValuesFieldSpec(weightedLegalValues, true);
}

public static RestrictionsFieldSpec fromRestriction(TypedRestrictions restrictions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,10 @@

import com.scottlogic.datahelix.generator.core.generation.databags.DataBagValue;

import static com.scottlogic.datahelix.generator.common.whitelist.DistributedList.singleton;

public class FieldSpecHelper {
public FieldSpec getFieldSpecForValue(DataBagValue fieldValue) {
if (fieldValue.getValue() == null) {
return FieldSpecFactory.nullOnly();
}

return FieldSpecFactory.fromList(singleton(fieldValue.getValue()))
.withNotNull();
return (fieldValue.getValue() == null)
? FieldSpecFactory.nullOnly()
: FieldSpecFactory.fromSingleLegalValue(fieldValue.getValue()).withNotNull();
}
}
Loading

0 comments on commit 74cb502

Please sign in to comment.