From 89840f17bf8f0429364797a2ca8192c03cee21e4 Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Fri, 6 Sep 2019 11:07:22 +0100 Subject: [PATCH 1/7] remove UnderlyingConstraint from Dynamic constraints --- .../delayed/DelayedAtomicConstraint.java | 4 +-- .../delayed/DynamicNotConstraint.java | 8 +++--- .../delayed/IsAfterDynamicDateConstraint.java | 22 +++++++-------- .../IsBeforeDynamicDateConstraint.java | 22 +++++++-------- .../IsEqualToDynamicDateConstraint.java | 27 ++++++++---------- .../ConstraintToFieldMapper.java | 2 +- .../fieldspecs/FieldRelationsFactory.java | 8 +++--- .../reader/AtomicConstraintTypeReaderMap.java | 28 ++++++------------- .../constraintreaders/EqualToFieldReader.java | 8 +++--- .../EqualToFieldReaderTest.java | 2 +- 10 files changed, 57 insertions(+), 74 deletions(-) diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java index 86aa3e114..369325346 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java @@ -29,10 +29,10 @@ static void validateFieldsAreDifferent(Field first, Field second) { } } - AtomicConstraint underlyingConstraint(); - Field field(); + Field getOtherField(); + default DynamicNotConstraint negate() { return new DynamicNotConstraint(this); } diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java index 3e40766cf..4c4031879 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java @@ -34,13 +34,13 @@ public DynamicNotConstraint(DelayedAtomicConstraint negatedConstraint) { } @Override - public AtomicConstraint underlyingConstraint() { - return negatedConstraint.underlyingConstraint(); + public Field field() { + return negatedConstraint.field(); } @Override - public Field field() { - return negatedConstraint.field(); + public Field getOtherField() { + return negatedConstraint.getOtherField(); } @Override diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java index 403a556de..bb4ec9a0f 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java @@ -22,29 +22,27 @@ public class IsAfterDynamicDateConstraint implements DelayedAtomicConstraint { - private final AtomicConstraint underlyingConstraint; - private final Field field; - private final boolean inclusive; + private final Field otherField; - public IsAfterDynamicDateConstraint(AtomicConstraint underlyingConstraint, - Field field, - boolean inclusive) { - DelayedAtomicConstraint.validateFieldsAreDifferent(underlyingConstraint.getField(), field); - this.underlyingConstraint = underlyingConstraint; + public IsAfterDynamicDateConstraint(Field field, + boolean inclusive, + Field otherField) { + this.otherField = otherField; + DelayedAtomicConstraint.validateFieldsAreDifferent(otherField, field); this.field = field; this.inclusive = inclusive; } @Override - public AtomicConstraint underlyingConstraint() { - return underlyingConstraint; + public Field field() { + return field; } @Override - public Field field() { - return field; + public Field getOtherField() { + return otherField; } public boolean inclusive() { diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java index b8c33a9ea..e2929af97 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java @@ -21,29 +21,29 @@ public class IsBeforeDynamicDateConstraint implements DelayedAtomicConstraint { - private final AtomicConstraint underlyingConstraint; - private final Field field; private final boolean inclusive; - public IsBeforeDynamicDateConstraint(AtomicConstraint underlyingConstraint, - Field field, - boolean inclusive) { - DelayedAtomicConstraint.validateFieldsAreDifferent(underlyingConstraint.getField(), field); - this.underlyingConstraint = underlyingConstraint; + private final Field otherField; + + public IsBeforeDynamicDateConstraint(Field field, + boolean inclusive, + Field otherField) { + DelayedAtomicConstraint.validateFieldsAreDifferent(otherField, field); this.field = field; this.inclusive = inclusive; + this.otherField = otherField; } @Override - public AtomicConstraint underlyingConstraint() { - return underlyingConstraint; + public Field field() { + return field; } @Override - public Field field() { - return field; + public Field getOtherField() { + return otherField; } public boolean inclusive() { diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java index 9d9c7c33b..b4653e7f0 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java @@ -22,37 +22,34 @@ public class IsEqualToDynamicDateConstraint implements DelayedAtomicConstraint { - private final AtomicConstraint underlyingConstraint; - private final Field field; - private final TemporalAdjusterGenerator unit; - private final int offset; + private final Field otherField; - public IsEqualToDynamicDateConstraint(AtomicConstraint underlyingConstraint, - Field field, + public IsEqualToDynamicDateConstraint(Field field, TemporalAdjusterGenerator unit, - int offset) { - DelayedAtomicConstraint.validateFieldsAreDifferent(underlyingConstraint.getField(), field); - this.underlyingConstraint = underlyingConstraint; + int offset, + Field otherField) { + this.otherField = otherField; + DelayedAtomicConstraint.validateFieldsAreDifferent(otherField, field); this.field = field; this.unit = unit; this.offset = offset; } - public IsEqualToDynamicDateConstraint(AtomicConstraint underlyingConstraint, Field field) { - this(underlyingConstraint, field, null, 0); + public IsEqualToDynamicDateConstraint(Field field, Field otherField) { + this(field, null, 0, otherField); } @Override - public AtomicConstraint underlyingConstraint() { - return underlyingConstraint; + public Field field() { + return field; } @Override - public Field field() { - return field; + public Field getOtherField(){ + return otherField; } public TemporalAdjusterGenerator unit() { diff --git a/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java b/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java index 02591ccc0..54a2ee438 100644 --- a/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java +++ b/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java @@ -66,7 +66,7 @@ private Stream mapDelayedConstraintsToFields(ConstraintNode return node.getDelayedAtomicConstraints().stream() .map(constraint -> new ConstraintToFields( new RootLevelConstraint(constraint), - SetUtils.setOf(constraint.field(), constraint.underlyingConstraint().getField()))); + SetUtils.setOf(constraint.field(), constraint.getOtherField()))); } private Stream mapDecisionsToFields(ConstraintNode node) { diff --git a/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java b/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java index f6b0b1ba3..faa1b8d3c 100644 --- a/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java +++ b/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java @@ -42,14 +42,14 @@ private FieldSpecRelations construct(DelayedAtomicConstraint constraint, boolean private FieldSpecRelations constructBeforeDate(IsBeforeDynamicDateConstraint constraint) { return new BeforeDateRelation( - constraint.underlyingConstraint().getField(), + constraint.getOtherField(), constraint.field(), constraint.inclusive()); } private FieldSpecRelations constructAfterDate(IsAfterDynamicDateConstraint constraint) { return new AfterDateRelation( - constraint.underlyingConstraint().getField(), + constraint.getOtherField(), constraint.field(), constraint.inclusive()); } @@ -57,13 +57,13 @@ private FieldSpecRelations constructAfterDate(IsAfterDynamicDateConstraint const private FieldSpecRelations constructEqualToDate(IsEqualToDynamicDateConstraint constraint) { if (constraint.unit() != null) { return new EqualToOffsetDateRelation( - constraint.underlyingConstraint().getField(), + constraint.getOtherField(), constraint.field(), constraint.unit(), constraint.offset()); } else { return new EqualToDateRelation( - constraint.underlyingConstraint().getField(), + constraint.getOtherField(), constraint.field()); } } diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java index a055191ce..c6a476ed9 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java @@ -43,47 +43,35 @@ public Map getDelayedMapEntries() map.put(IS_BEFORE_FIELD_DATE_TIME, (dto, fields) -> new IsBeforeDynamicDateConstraint( - new IsBeforeConstantDateTimeConstraint( - fields.getByName(dto.field), - OffsetDateTime.MIN - ), fields.getByName((String)dto.value), - false + false, + fields.getByName(dto.field) ) ); map.put(IS_BEFORE_OR_EQUAL_TO_FIELD_DATE_TIME, (dto, fields) -> new IsBeforeDynamicDateConstraint( - new IsBeforeOrEqualToConstantDateTimeConstraint( - fields.getByName(dto.field), - OffsetDateTime.MIN - ), fields.getByName((String)dto.value), - true + true, + fields.getByName(dto.field) ) ); map.put(IS_AFTER_FIELD_DATE_TIME, (dto, fields) -> new IsAfterDynamicDateConstraint( - new IsAfterConstantDateTimeConstraint( - fields.getByName(dto.field), - OffsetDateTime.MAX - ), fields.getByName((String)dto.value), - false + false, + fields.getByName(dto.field) )); map.put(IS_AFTER_OR_EQUAL_TO_FIELD_DATE_TIME, (dto, fields) -> new IsAfterDynamicDateConstraint( - new IsAfterOrEqualToConstantDateTimeConstraint( - fields.getByName(dto.field), - OffsetDateTime.MAX - ), fields.getByName((String)dto.value), - true + true, + fields.getByName(dto.field) ) ); diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java index e2fa485f1..3a4567a8d 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java @@ -35,8 +35,8 @@ public Constraint apply(ConstraintDTO dto, ProfileFields fields) { } return new IsEqualToDynamicDateConstraint( - new EqualToConstraint(fields.getByName(dto.field), "to be overriden"), - fields.getByName((String)dto.value) + fields.getByName((String)dto.value), + fields.getByName(dto.field) ); } @@ -49,10 +49,10 @@ private Constraint createOffsetConstraint(ConstraintDTO dto, ProfileFields field ); return new IsEqualToDynamicDateConstraint( - new EqualToConstraint(fields.getByName(dto.field), "to be overriden"), fields.getByName((String)dto.value), unit, - dto.offset + dto.offset, + fields.getByName(dto.field) ); } } diff --git a/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java b/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java index cfbc94b58..943de449d 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java @@ -40,7 +40,7 @@ public void setUp() { public void apply_noOffset_createsTwoEqualFields() { IsEqualToDynamicDateConstraint constraint = createConstraint(equalToFieldReader, dto, fields); - assertEquals(new Field(FIRST), constraint.underlyingConstraint().getField()); + assertEquals(new Field(FIRST), constraint.getOtherField()); assertEquals(new Field(SECOND), constraint.field()); assertNull(constraint.unit()); } From e2d91f1cb924ea6569d7f8212be3c48d9e9172f7 Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Fri, 6 Sep 2019 14:20:38 +0100 Subject: [PATCH 2/7] Replace multiple delayedConstraints with one generic delayed constraint --- .../AtomicConstraintType.java | 2 +- .../delayed/DelayedAtomicConstraint.java | 46 ++++++++++++-- .../delayed/DynamicNotConstraint.java | 8 +-- .../delayed/IsAfterDynamicDateConstraint.java | 52 ---------------- .../IsBeforeDynamicDateConstraint.java | 52 ---------------- .../IsEqualToDynamicDateConstraint.java | 62 ------------------- .../ConstraintToFieldMapper.java | 2 +- .../fieldspecs/FieldRelationsFactory.java | 57 +++++++++-------- .../violate/AtomicConstraintTypeMapper.java | 2 +- .../violate/ViolateCommandLine.java | 2 +- .../violate/ViolateConfigSource.java | 2 +- .../testframework/steps/GeneralTestStep.java | 2 +- .../steps/TypeRegistryConfiguration.java | 2 +- .../utils/CucumberGenerationConfigSource.java | 2 +- .../utils/CucumberTestState.java | 3 +- .../ViolationFiltersProviderTest.java | 2 +- .../reader/AtomicConstraintTypeReaderMap.java | 46 ++++++-------- .../profile/reader/MainConstraintReader.java | 2 +- .../atomic/AtomicConstraintFactory.java | 2 +- .../atomic/AtomicConstraintValueReader.java | 1 - .../atomic/ConstraintValueValidator.java | 4 +- .../constraintreaders/EqualToFieldReader.java | 17 ++--- .../profile/dto/AtomicConstraintTypeTest.java | 1 + .../AtomicConstraintReaderMapTests.java | 2 +- .../EqualToFieldReaderTest.java | 6 +- 25 files changed, 124 insertions(+), 255 deletions(-) rename {profile/src/main/java/com/scottlogic/deg/profile/dto => common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail}/AtomicConstraintType.java (97%) delete mode 100644 common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java delete mode 100644 common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java delete mode 100644 common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java diff --git a/profile/src/main/java/com/scottlogic/deg/profile/dto/AtomicConstraintType.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java similarity index 97% rename from profile/src/main/java/com/scottlogic/deg/profile/dto/AtomicConstraintType.java rename to common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java index 26717a99b..1d8840967 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/dto/AtomicConstraintType.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.scottlogic.deg.profile.dto; +package com.scottlogic.deg.common.profile.constraintdetail; import java.util.Arrays; diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java index 369325346..7f93cf497 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DelayedAtomicConstraint.java @@ -17,11 +17,31 @@ package com.scottlogic.deg.common.profile.constraints.delayed; +import com.scottlogic.deg.common.date.TemporalAdjusterGenerator; import com.scottlogic.deg.common.profile.Field; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.common.profile.constraints.Constraint; -import com.scottlogic.deg.common.profile.constraints.atomic.AtomicConstraint; -public interface DelayedAtomicConstraint extends Constraint { +public class DelayedAtomicConstraint implements Constraint { + + private final Field field; + private final AtomicConstraintType underlyingConstraint; + private final Field otherField; + + private final TemporalAdjusterGenerator offsetGenerator; + + private final Integer offsetUnit; + public DelayedAtomicConstraint(Field field, AtomicConstraintType underlyingConstraint, Field otherField, TemporalAdjusterGenerator offsetGenerator, Integer offsetUnit) { + this.field = field; + this.underlyingConstraint = underlyingConstraint; + this.otherField = otherField; + this.offsetGenerator = offsetGenerator; + this.offsetUnit = offsetUnit; + } + + public DelayedAtomicConstraint(Field field, AtomicConstraintType underlyingConstraint, Field otherField) { + this(field, underlyingConstraint, otherField, null, null); + } static void validateFieldsAreDifferent(Field first, Field second) { if (first.equals(second)) { @@ -29,12 +49,28 @@ static void validateFieldsAreDifferent(Field first, Field second) { } } - Field field(); + public Field getField(){ + return field; + } + + public AtomicConstraintType getUnderlyingConstraint(){ + return underlyingConstraint; + } - Field getOtherField(); + public Field getOtherField(){ + return otherField; + } - default DynamicNotConstraint negate() { + public DelayedAtomicConstraint negate() { return new DynamicNotConstraint(this); } + public TemporalAdjusterGenerator getOffsetGenerator() { + return offsetGenerator; + } + + public Integer getOffsetUnit() { + return offsetUnit; + } + } diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java index 4c4031879..a5eea38f2 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/DynamicNotConstraint.java @@ -18,15 +18,15 @@ package com.scottlogic.deg.common.profile.constraints.delayed; import com.scottlogic.deg.common.profile.Field; -import com.scottlogic.deg.common.profile.constraints.atomic.AtomicConstraint; import java.util.Objects; -public class DynamicNotConstraint implements DelayedAtomicConstraint { +public class DynamicNotConstraint extends DelayedAtomicConstraint { private final DelayedAtomicConstraint negatedConstraint; public DynamicNotConstraint(DelayedAtomicConstraint negatedConstraint) { + super(negatedConstraint.getField(), negatedConstraint.getUnderlyingConstraint(), negatedConstraint.getOtherField()); if (negatedConstraint instanceof DynamicNotConstraint) { throw new IllegalArgumentException("Nested DynamicNotConstraint not allowed"); } @@ -34,8 +34,8 @@ public DynamicNotConstraint(DelayedAtomicConstraint negatedConstraint) { } @Override - public Field field() { - return negatedConstraint.field(); + public Field getField() { + return negatedConstraint.getField(); } @Override diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java deleted file mode 100644 index bb4ec9a0f..000000000 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsAfterDynamicDateConstraint.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2019 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.deg.common.profile.constraints.delayed; - -import com.scottlogic.deg.common.profile.Field; -import com.scottlogic.deg.common.profile.constraints.atomic.AtomicConstraint; - -public class IsAfterDynamicDateConstraint implements DelayedAtomicConstraint { - - private final Field field; - private final boolean inclusive; - private final Field otherField; - - public IsAfterDynamicDateConstraint(Field field, - boolean inclusive, - Field otherField) { - this.otherField = otherField; - DelayedAtomicConstraint.validateFieldsAreDifferent(otherField, field); - this.field = field; - this.inclusive = inclusive; - } - - @Override - public Field field() { - return field; - } - - @Override - public Field getOtherField() { - return otherField; - } - - public boolean inclusive() { - return inclusive; - } - -} diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java deleted file mode 100644 index e2929af97..000000000 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsBeforeDynamicDateConstraint.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2019 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.deg.common.profile.constraints.delayed; - -import com.scottlogic.deg.common.profile.Field; -import com.scottlogic.deg.common.profile.constraints.atomic.AtomicConstraint; - -public class IsBeforeDynamicDateConstraint implements DelayedAtomicConstraint { - - private final Field field; - - private final boolean inclusive; - - private final Field otherField; - - public IsBeforeDynamicDateConstraint(Field field, - boolean inclusive, - Field otherField) { - DelayedAtomicConstraint.validateFieldsAreDifferent(otherField, field); - this.field = field; - this.inclusive = inclusive; - this.otherField = otherField; - } - - @Override - public Field field() { - return field; - } - - @Override - public Field getOtherField() { - return otherField; - } - - public boolean inclusive() { - return inclusive; - } -} diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java deleted file mode 100644 index b4653e7f0..000000000 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraints/delayed/IsEqualToDynamicDateConstraint.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2019 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.deg.common.profile.constraints.delayed; - -import com.scottlogic.deg.common.date.TemporalAdjusterGenerator; -import com.scottlogic.deg.common.profile.Field; -import com.scottlogic.deg.common.profile.constraints.atomic.AtomicConstraint; - -public class IsEqualToDynamicDateConstraint implements DelayedAtomicConstraint { - - private final Field field; - private final TemporalAdjusterGenerator unit; - private final int offset; - private final Field otherField; - - public IsEqualToDynamicDateConstraint(Field field, - TemporalAdjusterGenerator unit, - int offset, - Field otherField) { - this.otherField = otherField; - DelayedAtomicConstraint.validateFieldsAreDifferent(otherField, field); - this.field = field; - this.unit = unit; - this.offset = offset; - } - - public IsEqualToDynamicDateConstraint(Field field, Field otherField) { - this(field, null, 0, otherField); - } - - @Override - public Field field() { - return field; - } - - @Override - public Field getOtherField(){ - return otherField; - } - - public TemporalAdjusterGenerator unit() { - return unit; - } - - public int offset() { - return offset; - } -} diff --git a/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java b/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java index 54a2ee438..b513067ca 100644 --- a/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java +++ b/generator/src/main/java/com/scottlogic/deg/generator/decisiontree/treepartitioning/ConstraintToFieldMapper.java @@ -66,7 +66,7 @@ private Stream mapDelayedConstraintsToFields(ConstraintNode return node.getDelayedAtomicConstraints().stream() .map(constraint -> new ConstraintToFields( new RootLevelConstraint(constraint), - SetUtils.setOf(constraint.field(), constraint.getOtherField()))); + SetUtils.setOf(constraint.getField(), constraint.getOtherField()))); } private Stream mapDecisionsToFields(ConstraintNode node) { diff --git a/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java b/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java index faa1b8d3c..389594e2e 100644 --- a/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java +++ b/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java @@ -19,52 +19,57 @@ import com.scottlogic.deg.common.profile.constraints.delayed.*; import com.scottlogic.deg.generator.fieldspecs.relations.*; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class FieldRelationsFactory { public FieldSpecRelations construct(DelayedAtomicConstraint constraint) { - return construct(constraint, false); - } - - private FieldSpecRelations construct(DelayedAtomicConstraint constraint, boolean negate) { if (constraint instanceof DynamicNotConstraint) { - return construct(constraint.negate(), !negate); - } else if (constraint instanceof IsAfterDynamicDateConstraint) { - return constructAfterDate((IsAfterDynamicDateConstraint) constraint); - } else if (constraint instanceof IsBeforeDynamicDateConstraint) { - return constructBeforeDate((IsBeforeDynamicDateConstraint) constraint); - } else if (constraint instanceof IsEqualToDynamicDateConstraint) { - return constructEqualToDate((IsEqualToDynamicDateConstraint) constraint); - } else { - throw new IllegalArgumentException("Unsupported field spec relations: " + constraint.getClass()); + throw new NotImplementedException(); + } + + switch (constraint.getUnderlyingConstraint()) { + case IS_EQUAL_TO_CONSTANT: + return constructEqualToDate(constraint); + case IS_BEFORE_CONSTANT_DATE_TIME: + return constructBeforeDate(constraint, false); + case IS_BEFORE_OR_EQUAL_TO_CONSTANT_DATE_TIME: + return constructBeforeDate(constraint, true); + case IS_AFTER_CONSTANT_DATE_TIME: + return constructAfterDate(constraint, false); + case IS_AFTER_OR_EQUAL_TO_CONSTANT_DATE_TIME: + return constructAfterDate(constraint, true); } + + throw new IllegalArgumentException("Unsupported field spec relations: " + constraint.getUnderlyingConstraint()); + } - private FieldSpecRelations constructBeforeDate(IsBeforeDynamicDateConstraint constraint) { + private FieldSpecRelations constructBeforeDate(DelayedAtomicConstraint constraint, boolean inclusive) { return new BeforeDateRelation( + constraint.getField(), constraint.getOtherField(), - constraint.field(), - constraint.inclusive()); + inclusive); } - private FieldSpecRelations constructAfterDate(IsAfterDynamicDateConstraint constraint) { + private FieldSpecRelations constructAfterDate(DelayedAtomicConstraint constraint, boolean inclusive) { return new AfterDateRelation( + constraint.getField(), constraint.getOtherField(), - constraint.field(), - constraint.inclusive()); + inclusive); } - private FieldSpecRelations constructEqualToDate(IsEqualToDynamicDateConstraint constraint) { - if (constraint.unit() != null) { + private FieldSpecRelations constructEqualToDate(DelayedAtomicConstraint constraint) { + if (constraint.getOffsetUnit() != null) { return new EqualToOffsetDateRelation( + constraint.getField(), constraint.getOtherField(), - constraint.field(), - constraint.unit(), - constraint.offset()); + constraint.getOffsetGenerator(), + constraint.getOffsetUnit()); } else { return new EqualToDateRelation( - constraint.getOtherField(), - constraint.field()); + constraint.getField(), + constraint.getOtherField()); } } } diff --git a/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/AtomicConstraintTypeMapper.java b/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/AtomicConstraintTypeMapper.java index 03d397e09..911cec6db 100644 --- a/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/AtomicConstraintTypeMapper.java +++ b/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/AtomicConstraintTypeMapper.java @@ -17,7 +17,7 @@ package com.scottlogic.deg.orchestrator.violate; import com.scottlogic.deg.common.profile.constraints.atomic.*; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; public class AtomicConstraintTypeMapper { public Class toConstraintClass(AtomicConstraintType type) { diff --git a/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateCommandLine.java b/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateCommandLine.java index f9e272d0e..032d93cb5 100644 --- a/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateCommandLine.java +++ b/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateCommandLine.java @@ -20,7 +20,7 @@ import com.google.inject.Injector; import com.google.inject.Module; import com.scottlogic.deg.orchestrator.generate.GenerateCommandLine; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import picocli.CommandLine; import java.io.IOException; diff --git a/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateConfigSource.java b/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateConfigSource.java index abf30b77d..d4edad591 100644 --- a/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateConfigSource.java +++ b/orchestrator/src/main/java/com/scottlogic/deg/orchestrator/violate/ViolateConfigSource.java @@ -17,7 +17,7 @@ package com.scottlogic.deg.orchestrator.violate; import com.scottlogic.deg.orchestrator.guice.AllConfigSource; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import java.util.List; diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/GeneralTestStep.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/GeneralTestStep.java index 1c60963df..7fbd47967 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/GeneralTestStep.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/GeneralTestStep.java @@ -21,7 +21,7 @@ import com.scottlogic.deg.generator.config.detail.DataGenerationType; import com.scottlogic.deg.orchestrator.cucumber.testframework.utils.*; import com.scottlogic.deg.profile.reader.InvalidProfileException; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import cucumber.api.java.Before; import cucumber.api.java.en.*; import org.hamcrest.Matcher; diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/TypeRegistryConfiguration.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/TypeRegistryConfiguration.java index cbbb8836d..20c24cca0 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/TypeRegistryConfiguration.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/steps/TypeRegistryConfiguration.java @@ -22,7 +22,7 @@ import com.scottlogic.deg.orchestrator.cucumber.testframework.utils.CucumberGenerationMode; import com.scottlogic.deg.orchestrator.cucumber.testframework.utils.GeneratorTestUtilities; import com.scottlogic.deg.profile.reader.InvalidProfileException; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import cucumber.api.TypeRegistry; import cucumber.api.TypeRegistryConfigurer; import io.cucumber.cucumberexpressions.ParameterType; diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberGenerationConfigSource.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberGenerationConfigSource.java index 2acb067e8..74584371c 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberGenerationConfigSource.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberGenerationConfigSource.java @@ -23,7 +23,7 @@ import com.scottlogic.deg.orchestrator.guice.AllConfigSource; import com.scottlogic.deg.orchestrator.violate.ViolateConfigSource; import com.scottlogic.deg.output.guice.OutputFormat; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import java.io.File; import java.nio.file.Path; diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberTestState.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberTestState.java index c507262f7..5c486f6ad 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberTestState.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberTestState.java @@ -21,8 +21,7 @@ import com.scottlogic.deg.common.profile.Field; import com.scottlogic.deg.generator.config.detail.CombinationStrategyType; import com.scottlogic.deg.generator.config.detail.DataGenerationType; -import com.scottlogic.deg.common.util.Defaults; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.profile.dto.ConstraintDTO; import java.io.IOException; diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/violation/ViolationFiltersProviderTest.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/violation/ViolationFiltersProviderTest.java index 7f144320c..4e1069867 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/violation/ViolationFiltersProviderTest.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/violation/ViolationFiltersProviderTest.java @@ -23,7 +23,7 @@ import com.scottlogic.deg.generator.violations.filters.ViolationFilter; import com.scottlogic.deg.orchestrator.violate.ViolateConfigSource; import com.scottlogic.deg.orchestrator.violate.ViolationFiltersProvider; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import org.junit.jupiter.api.Test; import java.util.Arrays; diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java index c6a476ed9..93cc312d6 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java @@ -16,22 +16,14 @@ package com.scottlogic.deg.profile.reader; -import com.scottlogic.deg.common.profile.constraints.atomic.*; -import com.scottlogic.deg.common.profile.constraints.delayed.IsAfterDynamicDateConstraint; -import com.scottlogic.deg.common.profile.constraints.delayed.IsBeforeDynamicDateConstraint; -import com.scottlogic.deg.common.util.Defaults; +import com.scottlogic.deg.common.profile.constraints.delayed.DelayedAtomicConstraint; import com.scottlogic.deg.profile.reader.constraintreaders.*; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; -import java.math.BigDecimal; -import java.time.OffsetDateTime; import java.util.HashMap; import java.util.Map; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import static com.scottlogic.deg.profile.dto.AtomicConstraintType.*; +import static com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType.*; public class AtomicConstraintTypeReaderMap { @@ -42,36 +34,36 @@ public Map getDelayedMapEntries() map.put(IS_BEFORE_FIELD_DATE_TIME, (dto, fields) -> - new IsBeforeDynamicDateConstraint( - fields.getByName((String)dto.value), - false, - fields.getByName(dto.field) + new DelayedAtomicConstraint( + fields.getByName(dto.field), + IS_BEFORE_CONSTANT_DATE_TIME, + fields.getByName((String)dto.value) ) ); map.put(IS_BEFORE_OR_EQUAL_TO_FIELD_DATE_TIME, (dto, fields) -> - new IsBeforeDynamicDateConstraint( - fields.getByName((String)dto.value), - true, - fields.getByName(dto.field) + new DelayedAtomicConstraint( + fields.getByName(dto.field), + IS_BEFORE_OR_EQUAL_TO_CONSTANT_DATE_TIME, + fields.getByName((String)dto.value) ) ); map.put(IS_AFTER_FIELD_DATE_TIME, (dto, fields) -> - new IsAfterDynamicDateConstraint( - fields.getByName((String)dto.value), - false, - fields.getByName(dto.field) + new DelayedAtomicConstraint( + fields.getByName(dto.field), + IS_AFTER_CONSTANT_DATE_TIME, + fields.getByName((String)dto.value) )); map.put(IS_AFTER_OR_EQUAL_TO_FIELD_DATE_TIME, (dto, fields) -> - new IsAfterDynamicDateConstraint( - fields.getByName((String)dto.value), - true, - fields.getByName(dto.field) + new DelayedAtomicConstraint( + fields.getByName(dto.field), + IS_AFTER_OR_EQUAL_TO_CONSTANT_DATE_TIME, + fields.getByName((String)dto.value) ) ); diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java index 18a8f2f79..d210b5f9e 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java @@ -22,7 +22,7 @@ import com.scottlogic.deg.common.profile.constraints.grammatical.AndConstraint; import com.scottlogic.deg.common.profile.constraints.grammatical.ConditionalConstraint; import com.scottlogic.deg.common.profile.constraints.grammatical.OrConstraint; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.profile.dto.ConstraintDTO; import com.scottlogic.deg.profile.reader.atomic.AtomicConstraintValueReader; import com.scottlogic.deg.profile.reader.atomic.AtomicConstraintFactory; diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintFactory.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintFactory.java index 286c88823..900411fe0 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintFactory.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintFactory.java @@ -7,7 +7,7 @@ import com.scottlogic.deg.common.profile.constraints.atomic.*; import com.scottlogic.deg.common.util.NumberUtils; import com.scottlogic.deg.generator.fieldspecs.whitelist.DistributedSet; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.profile.reader.RemoveFromTree; import java.time.OffsetDateTime; diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintValueReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintValueReader.java index 96267b7f6..491646270 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintValueReader.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/AtomicConstraintValueReader.java @@ -3,7 +3,6 @@ import com.google.inject.Inject; import com.scottlogic.deg.common.ValidationException; import com.scottlogic.deg.generator.fieldspecs.whitelist.FrequencyDistributedSet; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; import com.scottlogic.deg.profile.dto.ConstraintDTO; import com.scottlogic.deg.profile.reader.InvalidProfileException; diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/ConstraintValueValidator.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/ConstraintValueValidator.java index 545ecc171..71a184e28 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/ConstraintValueValidator.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/atomic/ConstraintValueValidator.java @@ -7,14 +7,14 @@ import com.scottlogic.deg.common.util.Defaults; import com.scottlogic.deg.common.util.NumberUtils; import com.scottlogic.deg.generator.fieldspecs.whitelist.DistributedSet; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.profile.reader.InvalidProfileException; import java.math.BigDecimal; import java.time.OffsetDateTime; import java.util.regex.Pattern; -import static com.scottlogic.deg.profile.dto.AtomicConstraintType.IS_NULL; +import static com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType.IS_NULL; public class ConstraintValueValidator { diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java index 3a4567a8d..9ad34c2de 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java @@ -18,9 +18,10 @@ import com.scottlogic.deg.common.date.TemporalAdjusterGenerator; import com.scottlogic.deg.common.profile.ProfileFields; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.common.profile.constraints.Constraint; import com.scottlogic.deg.common.profile.constraints.atomic.EqualToConstraint; -import com.scottlogic.deg.common.profile.constraints.delayed.IsEqualToDynamicDateConstraint; +import com.scottlogic.deg.common.profile.constraints.delayed.DelayedAtomicConstraint; import com.scottlogic.deg.profile.dto.ConstraintDTO; import com.scottlogic.deg.profile.reader.AtomicConstraintReader; @@ -34,9 +35,10 @@ public Constraint apply(ConstraintDTO dto, ProfileFields fields) { return createOffsetConstraint(dto, fields); } - return new IsEqualToDynamicDateConstraint( - fields.getByName((String)dto.value), - fields.getByName(dto.field) + return new DelayedAtomicConstraint( + fields.getByName(dto.field), + AtomicConstraintType.IS_EQUAL_TO_CONSTANT, + fields.getByName((String)dto.value) ); } @@ -48,11 +50,12 @@ private Constraint createOffsetConstraint(ConstraintDTO dto, ProfileFields field workingDay ); - return new IsEqualToDynamicDateConstraint( + return new DelayedAtomicConstraint( + fields.getByName(dto.field), + AtomicConstraintType.IS_EQUAL_TO_CONSTANT, fields.getByName((String)dto.value), unit, - dto.offset, - fields.getByName(dto.field) + dto.offset ); } } diff --git a/profile/src/test/java/com/scottlogic/deg/profile/dto/AtomicConstraintTypeTest.java b/profile/src/test/java/com/scottlogic/deg/profile/dto/AtomicConstraintTypeTest.java index 994132504..17d574504 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/dto/AtomicConstraintTypeTest.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/dto/AtomicConstraintTypeTest.java @@ -16,6 +16,7 @@ package com.scottlogic.deg.profile.dto; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import org.junit.Assert; import org.junit.jupiter.api.Test; diff --git a/profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java b/profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java index 85ba3d5dd..6f5f7cd1f 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java @@ -22,7 +22,7 @@ import com.scottlogic.deg.common.profile.constraints.Constraint; import com.scottlogic.deg.common.profile.constraints.grammatical.AndConstraint; import com.scottlogic.deg.common.util.Defaults; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.profile.dto.ConstraintDTO; import com.scottlogic.deg.profile.reader.atomic.AtomicConstraintValueReader; import com.scottlogic.deg.profile.reader.atomic.AtomicConstraintFactory; diff --git a/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java b/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java index 943de449d..aac41f79b 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReaderTest.java @@ -1,9 +1,9 @@ +/* package com.scottlogic.deg.profile.reader.constraintreaders; import com.scottlogic.deg.common.profile.Field; import com.scottlogic.deg.common.profile.ProfileFields; -import com.scottlogic.deg.common.profile.constraints.delayed.IsEqualToDynamicDateConstraint; -import com.scottlogic.deg.profile.dto.AtomicConstraintType; +import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; import com.scottlogic.deg.profile.dto.ConstraintDTO; import com.scottlogic.deg.profile.reader.AtomicConstraintReader; import org.junit.jupiter.api.BeforeEach; @@ -98,4 +98,4 @@ private static IsEqualToDynamicDateConstraint createConstraint(AtomicConstraintR ProfileFields fields) { return (IsEqualToDynamicDateConstraint) reader.apply(dto, fields); } -} \ No newline at end of file +}*/ From 6dedc4c05378e03d6cffd0bf483fe46c51a1d740 Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Tue, 10 Sep 2019 10:39:27 +0100 Subject: [PATCH 3/7] Generically construct Delayed constraint --- .../AtomicConstraintType.java | 5 -- .../operators/temporal/AfterField.feature | 4 +- .../operators/temporal/AfterOrAtField.feature | 4 +- .../operators/temporal/BeforeField.feature | 4 +- .../temporal/BeforeOrAtField.feature | 4 +- .../operators/temporal/EqualToField.feature | 20 ++--- .../utils/CucumberProfileReader.java | 5 +- .../deg/profile/dto/ConstraintDTO.java | 2 + .../deg/profile/guice/ProfileModule.java | 1 - .../reader/AtomicConstraintReader.java | 28 ------- .../reader/AtomicConstraintTypeReaderMap.java | 74 ------------------- .../profile/reader/MainConstraintReader.java | 47 ++++++++---- .../constraintreaders/EqualToFieldReader.java | 61 --------------- ... ConstraintValidationAndReadingTests.java} | 21 +----- .../reader/JsonProfileReaderTests.java | 2 +- 15 files changed, 55 insertions(+), 227 deletions(-) delete mode 100644 profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintReader.java delete mode 100644 profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java delete mode 100644 profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java rename profile/src/test/java/com/scottlogic/deg/profile/reader/{AtomicConstraintReaderMapTests.java => ConstraintValidationAndReadingTests.java} (95%) diff --git a/common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java b/common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java index 1d8840967..66711fbe3 100644 --- a/common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java +++ b/common/src/main/java/com/scottlogic/deg/common/profile/constraintdetail/AtomicConstraintType.java @@ -21,7 +21,6 @@ public enum AtomicConstraintType { IS_EQUAL_TO_CONSTANT("equalTo"), - IS_EQUAL_TO_FIELD("equalToField"), IS_IN_SET("inSet"), IS_NULL("null"), IS_UNIQUE("unique"), @@ -44,13 +43,9 @@ public enum AtomicConstraintType { // DateTime IS_AFTER_CONSTANT_DATE_TIME("after"), - IS_AFTER_FIELD_DATE_TIME("afterField"), IS_AFTER_OR_EQUAL_TO_CONSTANT_DATE_TIME("afterOrAt"), - IS_AFTER_OR_EQUAL_TO_FIELD_DATE_TIME("afterOrAtField"), IS_BEFORE_CONSTANT_DATE_TIME("before"), - IS_BEFORE_FIELD_DATE_TIME("beforeField"), IS_BEFORE_OR_EQUAL_TO_CONSTANT_DATE_TIME("beforeOrAt"), - IS_BEFORE_OR_EQUAL_TO_FIELD_DATE_TIME("beforeOrAtField"), IS_GRANULAR_TO("granularTo"); diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterField.feature b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterField.feature index 072959ee2..02e45cdd9 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterField.feature +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterField.feature @@ -14,8 +14,8 @@ Feature: User can specify that one date should be after another date """ { "field": "bar", - "is": "afterField", - "value": "foo" + "is": "after", + "otherField": "foo" } """ Then the following data should be generated: diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterOrAtField.feature b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterOrAtField.feature index a61e2af11..6771f3e6a 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterOrAtField.feature +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/AfterOrAtField.feature @@ -14,8 +14,8 @@ Feature: User can specify that one date should be after or equal to another date """ { "field": "bar", - "is": "afterOrAtField", - "value": "foo" + "is": "afterOrAt", + "otherField": "foo" } """ Then the following data should be generated: diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeField.feature b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeField.feature index a0ed9a934..41abfe633 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeField.feature +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeField.feature @@ -13,8 +13,8 @@ Feature: User can specify that one date should be before another date """ { "field": "foo", - "is": "beforeField", - "value": "bar" + "is": "before", + "otherField": "bar" } """ Then the following data should be generated: diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeOrAtField.feature b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeOrAtField.feature index 0411a638e..606e20a41 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeOrAtField.feature +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/BeforeOrAtField.feature @@ -13,8 +13,8 @@ Feature: User can specify that one date should be before another date """ { "field": "foo", - "is": "beforeOrAtField", - "value": "bar" + "is": "beforeOrAt", + "otherField": "bar" } """ Then the following data should be generated: diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/EqualToField.feature b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/EqualToField.feature index 42432662a..0092f214b 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/EqualToField.feature +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/features/operators/temporal/EqualToField.feature @@ -14,8 +14,8 @@ Feature: User can specify that one date should be equal to another date """ { "field": "foo", - "is": "equalToField", - "value": "bar" + "is": "equalTo", + "otherField": "bar" } """ Then the following data should be generated: @@ -28,8 +28,8 @@ Feature: User can specify that one date should be equal to another date """ { "field": "bar", - "is": "equalToField", - "value": "foo", + "is": "equalTo", + "otherField": "foo", "offset": 3, "offsetUnit": "days" } @@ -45,8 +45,8 @@ Feature: User can specify that one date should be equal to another date """ { "field": "foo", - "is": "equalToField", - "value": "bar", + "is": "equalTo", + "otherField": "bar", "offset": -3, "offsetUnit": "days" } @@ -62,8 +62,8 @@ Feature: User can specify that one date should be equal to another date """ { "field": "bar", - "is": "equalToField", - "value": "foo", + "is": "equalTo", + "otherField": "foo", "offset": 5, "offsetUnit": "working days" } @@ -79,8 +79,8 @@ Feature: User can specify that one date should be equal to another date """ { "field": "foo", - "is": "equalToField", - "value": "bar", + "is": "equalTo", + "otherField": "bar", "offset": -5, "offsetUnit": "working days" } diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java index a6d8af3f1..b196905f0 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java @@ -36,12 +36,9 @@ public class CucumberProfileReader implements ProfileReader { private final CucumberTestState state; - private final AtomicConstraintTypeReaderMap constraintReaderMap; - @Inject - public CucumberProfileReader(CucumberTestState state, AtomicConstraintTypeReaderMap constraintReaderMap) { + public CucumberProfileReader(CucumberTestState state) { this.state = state; - this.constraintReaderMap = constraintReaderMap; } @Override diff --git a/profile/src/main/java/com/scottlogic/deg/profile/dto/ConstraintDTO.java b/profile/src/main/java/com/scottlogic/deg/profile/dto/ConstraintDTO.java index 4e229e52d..6b9611e48 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/dto/ConstraintDTO.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/dto/ConstraintDTO.java @@ -36,6 +36,8 @@ public class ConstraintDTO { /** a constant value - eg, used in isEqualTo or isGreaterThan */ public Object value; + public String otherField; + public Integer offset; public String offsetUnit; diff --git a/profile/src/main/java/com/scottlogic/deg/profile/guice/ProfileModule.java b/profile/src/main/java/com/scottlogic/deg/profile/guice/ProfileModule.java index c78197bf7..6a8254bc8 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/guice/ProfileModule.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/guice/ProfileModule.java @@ -18,7 +18,6 @@ import com.google.inject.AbstractModule; import com.google.inject.name.Names; -import com.scottlogic.deg.profile.reader.AtomicConstraintTypeReaderMap; import com.scottlogic.deg.profile.reader.JsonProfileReader; import com.scottlogic.deg.profile.reader.ProfileReader; import com.scottlogic.deg.profile.dto.ProfileSchemaValidator; diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintReader.java deleted file mode 100644 index 1872ecb46..000000000 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintReader.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2019 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.deg.profile.reader; - -import com.scottlogic.deg.common.profile.ProfileFields; -import com.scottlogic.deg.common.profile.constraints.Constraint; -import com.scottlogic.deg.profile.dto.ConstraintDTO; - -@FunctionalInterface -public interface AtomicConstraintReader { - Constraint apply( - ConstraintDTO dto, - ProfileFields fields); -} \ No newline at end of file diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java deleted file mode 100644 index 93cc312d6..000000000 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/AtomicConstraintTypeReaderMap.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2019 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.deg.profile.reader; - -import com.scottlogic.deg.common.profile.constraints.delayed.DelayedAtomicConstraint; -import com.scottlogic.deg.profile.reader.constraintreaders.*; -import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; - -import java.util.HashMap; -import java.util.Map; - -import static com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType.*; - -public class AtomicConstraintTypeReaderMap { - - public Map getDelayedMapEntries() { - Map map = new HashMap<>(); - - map.put(IS_EQUAL_TO_FIELD, new EqualToFieldReader()); - - map.put(IS_BEFORE_FIELD_DATE_TIME, - (dto, fields) -> - new DelayedAtomicConstraint( - fields.getByName(dto.field), - IS_BEFORE_CONSTANT_DATE_TIME, - fields.getByName((String)dto.value) - ) - ); - - map.put(IS_BEFORE_OR_EQUAL_TO_FIELD_DATE_TIME, - (dto, fields) -> - new DelayedAtomicConstraint( - fields.getByName(dto.field), - IS_BEFORE_OR_EQUAL_TO_CONSTANT_DATE_TIME, - fields.getByName((String)dto.value) - ) - ); - - map.put(IS_AFTER_FIELD_DATE_TIME, - (dto, fields) -> - new DelayedAtomicConstraint( - fields.getByName(dto.field), - IS_AFTER_CONSTANT_DATE_TIME, - fields.getByName((String)dto.value) - )); - - map.put(IS_AFTER_OR_EQUAL_TO_FIELD_DATE_TIME, - (dto, fields) -> - new DelayedAtomicConstraint( - fields.getByName(dto.field), - IS_AFTER_OR_EQUAL_TO_CONSTANT_DATE_TIME, - fields.getByName((String)dto.value) - ) - ); - - return map; - } - - -} diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java index d210b5f9e..cffd8c7ea 100644 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java +++ b/profile/src/main/java/com/scottlogic/deg/profile/reader/MainConstraintReader.java @@ -17,8 +17,10 @@ package com.scottlogic.deg.profile.reader; import com.google.inject.Inject; +import com.scottlogic.deg.common.date.TemporalAdjusterGenerator; import com.scottlogic.deg.common.profile.constraints.Constraint; import com.scottlogic.deg.common.profile.ProfileFields; +import com.scottlogic.deg.common.profile.constraints.delayed.DelayedAtomicConstraint; import com.scottlogic.deg.common.profile.constraints.grammatical.AndConstraint; import com.scottlogic.deg.common.profile.constraints.grammatical.ConditionalConstraint; import com.scottlogic.deg.common.profile.constraints.grammatical.OrConstraint; @@ -28,19 +30,17 @@ import com.scottlogic.deg.profile.reader.atomic.AtomicConstraintFactory; import com.scottlogic.deg.profile.reader.atomic.ConstraintValueValidator; +import java.time.temporal.ChronoUnit; import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; public class MainConstraintReader { - private final AtomicConstraintTypeReaderMap constraintReaderMap; private final AtomicConstraintValueReader atomicConstraintValueReader; @Inject - public MainConstraintReader(AtomicConstraintTypeReaderMap constraintReaderMap, - AtomicConstraintValueReader atomicConstraintValueReader) { - this.constraintReaderMap = constraintReaderMap; + public MainConstraintReader(AtomicConstraintValueReader atomicConstraintValueReader) { this.atomicConstraintValueReader = atomicConstraintValueReader; } @@ -58,24 +58,18 @@ public Constraint apply( if (dto.is != ConstraintDTO.undefined) { - Object value = atomicConstraintValueReader.getValue(dto); + if (dto.otherField != null){ + return createDelayedAtomicConstraint(dto, fields); + } AtomicConstraintType atomicConstraintType = AtomicConstraintType.fromText((String) dto.is); - ConstraintValueValidator.validate(dto.field, atomicConstraintType, value); + Object value = atomicConstraintValueReader.getValue(dto); - AtomicConstraintReader subReader = constraintReaderMap.getDelayedMapEntries() - .get(atomicConstraintType); + ConstraintValueValidator.validate(dto.field, atomicConstraintType, value); - if (subReader == null) { - return AtomicConstraintFactory.create(atomicConstraintType, fields.getByName(dto.field), value); - } + return AtomicConstraintFactory.create(atomicConstraintType, fields.getByName(dto.field), value); - try { - return subReader.apply(dto, fields); - } catch (IllegalArgumentException e) { - throw new InvalidProfileException(e.getMessage()); - } } if (dto.not != null) { @@ -117,6 +111,27 @@ public Constraint apply( throw new InvalidProfileException("Couldn't interpret constraint"); } + private DelayedAtomicConstraint createDelayedAtomicConstraint(ConstraintDTO dto, ProfileFields fields) { + return new DelayedAtomicConstraint( + fields.getByName(dto.field), + AtomicConstraintType.fromText((String) dto.is), + fields.getByName(dto.otherField), + getOffsetUnit(dto), + dto.offset); + } + + private TemporalAdjusterGenerator getOffsetUnit(ConstraintDTO dto) { + if (dto.offsetUnit == null) { + return null; + } + + String offsetUnitUpperCase = dto.offsetUnit.toUpperCase(); + boolean workingDay = offsetUnitUpperCase.equals("WORKING DAYS"); + return new TemporalAdjusterGenerator( + ChronoUnit.valueOf(ChronoUnit.class, workingDay ? "DAYS" : offsetUnitUpperCase), + workingDay); + } + Set getSubConstraints(ProfileFields fields, Collection allOf) { return allOf.stream() .map(subConstraintDto -> apply(subConstraintDto, fields)) diff --git a/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java b/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java deleted file mode 100644 index 9ad34c2de..000000000 --- a/profile/src/main/java/com/scottlogic/deg/profile/reader/constraintreaders/EqualToFieldReader.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2019 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.deg.profile.reader.constraintreaders; - -import com.scottlogic.deg.common.date.TemporalAdjusterGenerator; -import com.scottlogic.deg.common.profile.ProfileFields; -import com.scottlogic.deg.common.profile.constraintdetail.AtomicConstraintType; -import com.scottlogic.deg.common.profile.constraints.Constraint; -import com.scottlogic.deg.common.profile.constraints.atomic.EqualToConstraint; -import com.scottlogic.deg.common.profile.constraints.delayed.DelayedAtomicConstraint; -import com.scottlogic.deg.profile.dto.ConstraintDTO; -import com.scottlogic.deg.profile.reader.AtomicConstraintReader; - -import java.time.temporal.ChronoUnit; - -public class EqualToFieldReader implements AtomicConstraintReader { - - @Override - public Constraint apply(ConstraintDTO dto, ProfileFields fields) { - if (dto.offset != null && dto.offsetUnit != null) { - return createOffsetConstraint(dto, fields); - } - - return new DelayedAtomicConstraint( - fields.getByName(dto.field), - AtomicConstraintType.IS_EQUAL_TO_CONSTANT, - fields.getByName((String)dto.value) - ); - } - - private Constraint createOffsetConstraint(ConstraintDTO dto, ProfileFields fields) { - String offsetUnitUpperCase = dto.offsetUnit.toUpperCase(); - boolean workingDay = offsetUnitUpperCase.equals("WORKING DAYS"); - TemporalAdjusterGenerator unit = new TemporalAdjusterGenerator( - ChronoUnit.valueOf(ChronoUnit.class, workingDay ? "DAYS" : offsetUnitUpperCase), - workingDay - ); - - return new DelayedAtomicConstraint( - fields.getByName(dto.field), - AtomicConstraintType.IS_EQUAL_TO_CONSTANT, - fields.getByName((String)dto.value), - unit, - dto.offset - ); - } -} diff --git a/profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java b/profile/src/test/java/com/scottlogic/deg/profile/reader/ConstraintValidationAndReadingTests.java similarity index 95% rename from profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java rename to profile/src/test/java/com/scottlogic/deg/profile/reader/ConstraintValidationAndReadingTests.java index 6f5f7cd1f..bdec87649 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/reader/AtomicConstraintReaderMapTests.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/reader/ConstraintValidationAndReadingTests.java @@ -44,16 +44,12 @@ import static org.hamcrest.core.IsEqual.equalTo; @TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class AtomicConstraintReaderMapTests { +public class ConstraintValidationAndReadingTests { - Map constraintReaderMap; ProfileFields profileFields; @BeforeAll public void before() { - constraintReaderMap = - new AtomicConstraintTypeReaderMap().getDelayedMapEntries(); - List fields = new ArrayList<>(); fields.add(new Field("test")); @@ -218,20 +214,13 @@ private static Stream stringLengthValidOperandProvider() { @ParameterizedTest(name = "{0} should return {1}") @MethodSource("testProvider") public void testAtomicConstraintReader(AtomicConstraintType type, ConstraintDTO dto, Class constraintType) { - AtomicConstraintReader reader = constraintReaderMap.get(type); try { Object value = new AtomicConstraintValueReader(null).getValue(dto); ConstraintValueValidator.validate(dto.field, type, value); - Constraint constraint; - if (reader != null) { - constraint = reader.apply(dto, profileFields); - } - else { - constraint = AtomicConstraintFactory.create(type, new Field(dto.field), value); - } + Constraint constraint = AtomicConstraintFactory.create(type, new Field(dto.field), value); Assert.assertThat("Expected " + constraintType.getName() + " but got " + constraint.getClass().getName(), constraint, @@ -246,8 +235,6 @@ public void testAtomicConstraintReader(AtomicConstraintType type, ConstraintDTO @ParameterizedTest(name = "{0} should be invalid") @MethodSource({"stringLengthInvalidOperandProvider", "ofTypeInvalidValueProvider"}) public void testAtomicConstraintReaderWithInvalidOperands(AtomicConstraintType type, ConstraintDTO dto) { - AtomicConstraintReader reader = constraintReaderMap.get(type); - Assertions.assertThrows(InvalidProfileException.class, () -> ConstraintValueValidator.validate(dto.field, type, dto.value)); } @@ -262,8 +249,6 @@ public void testBaseConstraintReaderMapWithUnmappedOperands() { @ParameterizedTest(name = "{0} should be invalid") @MethodSource("numericOutOfBoundsOperandProvider") public void testAtomicConstraintReaderWithOutOfBoundValues(AtomicConstraintType type, ConstraintDTO dto) { - AtomicConstraintReader reader = constraintReaderMap.get(type); - Assertions.assertThrows(InvalidProfileException.class, () -> ConstraintValueValidator.validate(dto.field, type, dto.value)); } @@ -272,8 +257,6 @@ public void testAtomicConstraintReaderWithOutOfBoundValues(AtomicConstraintType @ParameterizedTest(name = "{0} should be valid") @MethodSource("stringLengthValidOperandProvider") public void testAtomicConstraintReaderWithValidOperands(AtomicConstraintType type, ConstraintDTO dto) { - AtomicConstraintReader reader = constraintReaderMap.get(type); - Assertions.assertDoesNotThrow(() -> ConstraintValueValidator.validate(dto.field, type, dto.value)); } diff --git a/profile/src/test/java/com/scottlogic/deg/profile/reader/JsonProfileReaderTests.java b/profile/src/test/java/com/scottlogic/deg/profile/reader/JsonProfileReaderTests.java index c9a82e57d..61c0e3029 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/reader/JsonProfileReaderTests.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/reader/JsonProfileReaderTests.java @@ -45,7 +45,7 @@ public class JsonProfileReaderTests { private JsonProfileReader jsonProfileReader = new JsonProfileReader( null, new MainConstraintReader( - new AtomicConstraintTypeReaderMap(), new AtomicConstraintValueReader(null))); + new AtomicConstraintValueReader(null))); private void givenJson(String json) { From 778d8584ed3bb42dc86fa2e38a8f04e31c811d0f Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Thu, 12 Sep 2019 10:47:03 +0100 Subject: [PATCH 4/7] Create v0.4 schema --- .../profileschema/0.4/datahelix.schema.json | 573 ++++++++++++++++++ 1 file changed, 573 insertions(+) create mode 100644 profile/src/main/resources/profileschema/0.4/datahelix.schema.json diff --git a/profile/src/main/resources/profileschema/0.4/datahelix.schema.json b/profile/src/main/resources/profileschema/0.4/datahelix.schema.json new file mode 100644 index 000000000..ff0c1bb2b --- /dev/null +++ b/profile/src/main/resources/profileschema/0.4/datahelix.schema.json @@ -0,0 +1,573 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://scottlogic.com/datahelix.json", + "title": "The Scott Logic DataHelix Profile Schema", + "type": "object", + "additionalProperties": false, + "required": ["schemaVersion", "fields", "rules"], + "properties": { + "additionalProperties": false, + "schemaVersion": { + "$ref": "#/definitions/schemaVersion" + }, + "description": { + "title": "A description of what data the profile is modelling", + "type": "string" + }, + "fields": { + "title": "Defines the fields that data will be produced for. field names must begin with an alphabetic character.", + "type": "array", + "minItems": 1, + "uniqueItems": true, + "additionalItems": false, + "items": { + "$ref": "#/definitions/fieldName" + } + }, + "rules": { + "title": "The Rules defining the data to be output", + "type": "array", + "additionalItems": false, + "items": { + "title": "A set of Rule objects.", + "type": "object", + "additionalProperties": false, + "required": ["constraints"], + "properties": { + "rule": { + "title": "A collection of constraints. Test case generation revolves around rules, in that the generator will output a separate dataset for each rule, wherein each row violates the rule in a different way.", + "type": "string" + }, + "constraints": { + "type": "array", + "items": { + "$ref": "#/definitions/constraint" + } + } + } + } + } + }, + "definitions": { + "schemaVersion": { + "title": "The version of the DataHelix profile schema", + "const": "0.3" + }, + "dataType": { + "oneOf": [ + { + "$ref": "#/definitions/datetime" + }, + { + "$ref": "#/definitions/string" + }, + { + "$ref": "#/definitions/numeric" + } + ] + }, + "datetime": { + "type": "object", + "additionalProperties": false, + "required": ["date"], + "default": { + "date": "2000-01-01T09:00:00.000" + }, + "properties": { + "additionalProperties": false, + "date": { + "title": "an ISO 8610 compatible string denoting a date and time", + "type": "string", + "default": "2000-01-01T09:00:00.000", + "oneOf": [ + { + "pattern": "^(?!0000)[0-9]{4}-([0][0-9]|[1][0-2])-([0-2][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9][.][0-9]{3}Z?$" + }, + { + "enum": ["now"] + }] + } + } + }, + "numeric": { + "type": "number", + "minimum": -1e20, + "maximum": 1e20, + "default": 0 + }, + "integer": { + "$ref": "#/definitions/numeric", + "multipleOf": 1 + }, + "string": { + "type": "string", + "maxLength": 1000, + "default": "string" + }, + "fieldName": { + "title": "The name of a field to generate data for", + "type": "object", + "additionalProperties": false, + "required": ["name"], + "default": { + "name": "fieldName" + }, + "properties": { + "name": { + "type": "string" + } + } + }, + "constraint": { + "oneOf": [ + { + "$ref": "#/definitions/anyOfConstraint" + }, + { + "$ref": "#/definitions/allOfConstraint" + }, + { + "$ref": "#/definitions/dataConstraint" + }, + { + "$ref": "#/definitions/nullConstraint" + }, + { + "$ref": "#/definitions/uniqueConstraint" + }, + { + "$ref": "#/definitions/extendedDataConstraint" + }, + { + "$ref": "#/definitions/inSetConstraint" + }, + { + "$ref": "#/definitions/fromFileConstraint" + }, + { + "$ref": "#/definitions/notConstraint" + }, + { + "$ref": "#/definitions/ifThenConstraint" + }, + { + "$ref": "#/definitions/ifThenElseConstraint" + } + ] + }, + "dataConstraint": { + "type": "object", + "required": ["field", "is", "value"], + "additionalProperties": false, + "properties": { + "field": { + "type": "string" + }, + "is": { + "enum": [ + "ofType", + "equalTo", + "formattedAs", + "matchingRegex", + "containingRegex", + "ofLength", + "longerThan", + "shorterThan", + "greaterThan", + "lessThan", + "greaterThanOrEqualTo", + "lessThanOrEqualTo", + "granularTo", + "after", + "afterOrAt", + "before", + "beforeOrAt", + ] + }, + "value": { + "oneOf": [ + { + "$ref": "#/definitions/datetime" + }, + { + "$ref": "#/definitions/numeric" + }, + { + "$ref": "#/definitions/string" + } + ] + } + }, + "allOf": [ + { + "if": { + "properties": { + "is": { + "enum": ["after", "afterOrAt", "before", "beforeOrAt"] + } + } + }, + "then": { + "properties": { + "value": { + "$ref": "#/definitions/datetime" + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "equalTo" + } + } + }, + "then": { + "properties": { + "value": { + "$ref": "#/definitions/dataType" + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "ofType" + } + } + }, + "then": { + "properties": { + "value": { + "enum": ["decimal", "integer", "string", "datetime","ISIN","SEDOL","CUSIP","RIC","firstname","lastname","fullname"] + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "formattedAs" + } + } + }, + "then": { + "properties": { + "value": { + "pattern": "^%.+$", + "default": "%" + } + } + } + }, + { + "if": { + "properties": { + "is": { + "enum": ["matchingRegex", "containingRegex"] + } + } + }, + "then": { + "properties": { + "value": { + "type": "string", + "default": ".*" + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "shorterThan" + } + } + }, + "then": { + "properties": { + "value": { + "$ref": "#/definitions/integer", + "minimum": 1, + "maximum": 1001 + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "ofLength" + } + } + }, + "then": { + "properties": { + "value": { + "$ref": "#/definitions/integer", + "minimum": 0, + "maximum": 1000 + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "longerThan" + } + } + }, + "then": { + "properties": { + "value": { + "$ref": "#/definitions/integer", + "minimum": -1, + "maximum": 999 + } + } + } + }, + { + "if": { + "properties": { + "is": { + "const": "granularTo" + } + } + }, + "then": { + "properties": { + "value": { + "enum": [ + 1, + 1e-1, + 1e-2, + 1e-3, + 1e-4, + 1e-5, + 1e-6, + 1e-7, + 1e-8, + 1e-9, + 1e-10, + 1e-11, + 1e-12, + 1e-13, + 1e-14, + 1e-15, + 1e-16, + 1e-17, + 1e-18, + 1e-19, + 1e-20, + "millis", + "seconds", + "minutes", + "hours", + "days", + "months", + "years" + ] + } + } + } + }, + { + "if": { + "properties": { + "is": { + "enum": [ + "greaterThan", + "lessThan", + "greaterThanOrEqualTo", + "lessThanOrEqualTo" + ] + } + } + }, + "then": { + "properties": { + "value": { + "$ref": "#/definitions/numeric" + } + } + } + } + ] + }, + "extendedDataConstraint": { + "type": "object", + "required": ["field", "is", "otherField"], + "additionalProperties": true, + "properties": { + "field": { + "type": "string" + }, + "is": { + "enum": [ + "after", + "afterOrAt", + "before", + "beforeOrAt", + "equalTo" + ] + }, + "otherField": { + "$ref": "#/definitions/string" + }, + "offset": { + "$ref": "#/definitions/integer" + }, + "offsetUnit": { + "type": "string" + } + } + }, + "notConstraint": { + "type": "object", + "additionalProperties": false, + "required": ["not"], + "properties": { + "not": { + "$ref": "#/definitions/constraint" + } + } + }, + "anyOfConstraint": { + "type": "object", + "additionalProperties": false, + "required": ["anyOf"], + "properties": { + "anyOf": { + "type": "array", + "minItems": 2, + "items": { + "$ref": "#/definitions/constraint" + } + } + } + }, + "allOfConstraint": { + "type": "object", + "additionalProperties": false, + "required": ["allOf"], + "properties": { + "allOf": { + "type": "array", + "minItems": 2, + "items": { + "$ref": "#/definitions/constraint" + } + } + } + }, + "ifThenConstraint": { + "type": "object", + "required": ["if", "then"], + "additionalProperties": false, + "properties": { + "if": { + "$ref": "#/definitions/constraint" + }, + "then": { + "$ref": "#/definitions/constraint" + } + } + }, + "ifThenElseConstraint": { + "type": "object", + "required": ["if", "then", "else"], + "additionalProperties": false, + "properties": { + "if": { + "$ref": "#/definitions/constraint" + }, + "then": { + "$ref": "#/definitions/constraint" + }, + "else": { + "$ref": "#/definitions/constraint" + } + } + }, + "nullConstraint": { + "type": "object", + "required": ["field", "is"], + "additionalProperties": false, + "properties": { + "field": { + "type": "string" + }, + "is": { + "const": "null" + } + } + }, + "uniqueConstraint": { + "type": "object", + "required": ["field", "is"], + "additionalProperties": false, + "properties": { + "field": { + "type": "string" + }, + "is": { + "const": "unique" + } + } + }, + "fromFileConstraint": { + "type": "object", + "required": ["field", "is", "file"], + "additionalProperties": false, + "properties": { + "field": { + "type": "string" + }, + "is": { + "const": "inSet" + }, + "file": { + "type": "string" + } + } + }, + "inSetConstraint": { + "type": "object", + "required": ["field", "is", "values"], + "additionalProperties": false, + "properties": { + "field": { + "type": "string" + }, + "is": { + "const": "inSet" + }, + "values": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/datetime" + }, + { + "$ref": "#/definitions/numeric" + }, + { + "$ref": "#/definitions/string" + } + ] + } + } + } + } + } +} From 3b9af158f59ecd13d04fc50bcf77ed124fe602c1 Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Thu, 12 Sep 2019 10:49:32 +0100 Subject: [PATCH 5/7] feat(#1235): create dependant constraints using "otherField" --- .../deg/generator/fieldspecs/FieldRelationsFactory.java | 4 ++-- .../cucumber/testframework/utils/CucumberProfileReader.java | 2 +- .../deg/profile/ProfileSchemaImmutabilityTests.java | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java b/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java index 389594e2e..b282ded27 100644 --- a/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java +++ b/generator/src/main/java/com/scottlogic/deg/generator/fieldspecs/FieldRelationsFactory.java @@ -17,15 +17,15 @@ package com.scottlogic.deg.generator.fieldspecs; +import com.scottlogic.deg.common.ValidationException; import com.scottlogic.deg.common.profile.constraints.delayed.*; import com.scottlogic.deg.generator.fieldspecs.relations.*; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; public class FieldRelationsFactory { public FieldSpecRelations construct(DelayedAtomicConstraint constraint) { if (constraint instanceof DynamicNotConstraint) { - throw new NotImplementedException(); + throw new ValidationException("related field constraints cannot yet be negated"); } switch (constraint.getUnderlyingConstraint()) { diff --git a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java index b196905f0..863d258bf 100644 --- a/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java +++ b/orchestrator/src/test/java/com/scottlogic/deg/orchestrator/cucumber/testframework/utils/CucumberProfileReader.java @@ -48,7 +48,7 @@ public Profile read() { private Profile getProfile() { try { - MainConstraintReader constraintReader = new MainConstraintReader(constraintReaderMap, new AtomicConstraintValueReader(new FromFileReader(""))); + MainConstraintReader constraintReader = new MainConstraintReader(new AtomicConstraintValueReader(new FromFileReader(""))); ProfileFields profileFields = new ProfileFields(state.profileFields); AtomicBoolean exceptionInMapping = new AtomicBoolean(); diff --git a/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java b/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java index cd11c6589..cc25f504d 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java @@ -66,8 +66,10 @@ private static Set versionToHash() { "1208511af02fcf69285e6d16d1a0caaa3cae3aef95912d1d940d8dfe4eda6031")); versionToHash.add(new VersionHash( "0.3", - "545db9f55228cda6eeff076c4cb1905f6c1a3b061a388dcdeadfbfb6cdd36676" - )); + "545db9f55228cda6eeff076c4cb1905f6c1a3b061a388dcdeadfbfb6cdd36676")); + versionToHash.add(new VersionHash( + "0.4", + "8ca6a1da96b447d1a5fe7065ca527a5d26c12a07828642333fb1d493960af119")); return versionToHash; } From a398be30c23d19568e35ffe5ad74c2860a7558fc Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Thu, 12 Sep 2019 15:48:07 +0100 Subject: [PATCH 6/7] update schema --- .../src/main/resources/profileschema/0.4/datahelix.schema.json | 2 +- .../scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/profile/src/main/resources/profileschema/0.4/datahelix.schema.json b/profile/src/main/resources/profileschema/0.4/datahelix.schema.json index ff0c1bb2b..d56e7f74c 100644 --- a/profile/src/main/resources/profileschema/0.4/datahelix.schema.json +++ b/profile/src/main/resources/profileschema/0.4/datahelix.schema.json @@ -51,7 +51,7 @@ "definitions": { "schemaVersion": { "title": "The version of the DataHelix profile schema", - "const": "0.3" + "const": "0.4" }, "dataType": { "oneOf": [ diff --git a/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java b/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java index cc25f504d..14980370c 100644 --- a/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java +++ b/profile/src/test/java/com/scottlogic/deg/profile/ProfileSchemaImmutabilityTests.java @@ -69,7 +69,7 @@ private static Set versionToHash() { "545db9f55228cda6eeff076c4cb1905f6c1a3b061a388dcdeadfbfb6cdd36676")); versionToHash.add(new VersionHash( "0.4", - "8ca6a1da96b447d1a5fe7065ca527a5d26c12a07828642333fb1d493960af119")); + "9d4cdf397ae8d6c9e841a7577c859caca56fd906168eff77ba66d4ddf5e06ba7")); return versionToHash; } From 27f11f7de71909fefe6dd3062bcd35428ebcdbcd Mon Sep 17 00:00:00 2001 From: Paul Daulby Date: Thu, 12 Sep 2019 16:22:10 +0100 Subject: [PATCH 7/7] add docs for dependant field --- docs/UserGuide.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 76e24d0d1..b1c99719d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -38,6 +38,9 @@ 3. [before](#predicate-before) 4. [beforeOrAt](#predicate-beforeorat) 5. [granularTo](#predicate-granularto-datetime) + 6. [Dependent field constraints](#otherfield-constraints) + 1. [otherField](#predicate-otherfield) + 2. [offset](#predicate-offset) 5. [Grammatical constraints](#Grammatical-Constraints) 1. [not](#not) @@ -502,6 +505,28 @@ Is satisfied if `field` is a datetime occurring before or simultaneously with `v Is satisfied if `field` has at least the [granularity](#DateTime-granularity) specified in `value`. +
+## Dependant field constraints + +
+### `otherField` +allows a date field to be dependant on the output of another date field + +```javascript +{ "field": "laterDateField", "is": "after", "otherField": "previousDateField" } +``` + +supported operators are currently +"after", "afterOrAt", "before", "beforeOrAt", "equalTo" + +
+### `offset` +Allows a dependant date to always be a certain offset away from another date + +```javascript +{ "field": "threeDaysAfterField", "is": "equalTo", "otherField": "previousDateField", "offset": 3, "offsetUnit": "days" } +``` + # Grammatical constraints