Skip to content

Commit

Permalink
Merge pull request #186 from buhlergroup/feature/regex-match
Browse files Browse the repository at this point in the history
Value Matches Condition
  • Loading branch information
MrF3lix authored Aug 23, 2023
2 parents 42e6f2a + 0dcfd9a commit 0d48b32
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 50 deletions.
42 changes: 1 addition & 41 deletions .github/workflows/CI-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,16 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.11
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Cache SonarCloud packages
uses: actions/cache@v1
with:
path: ~/sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache SonarCloud scanner
id: cache-sonar-scanner
uses: actions/cache@v1
with:
path: ./.sonar/scanner
key: ${{ runner.os }}-sonar-scanner
restore-keys: ${{ runner.os }}-sonar-scanner
- name: Install SonarCloud scanner
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
shell: pwsh
run: |
New-Item -Path ./.sonar/scanner -ItemType Directory
dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner
- name: Start Scanner
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
shell: pwsh
run: |
./.sonar/scanner/dotnet-sonarscanner begin /k:"buhlergroup_data-mapper-dotnet" /o:"buhlergroup" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /v:0.2.* /d:sonar.cs.opencover.reportsPaths="**/CoverageResults/coverage.opencover.xml" /d:sonar.coverage.exclusions="**/ServiceCollectionExtensions.cs"
fetch-depth: 0
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutput="../CoverageResults/" /p:MergeWith="../CoverageResults/coverage.json" /p:CoverletOutputFormat="\"opencover,json\""

- name: End Scanner
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
shell: pwsh
run: |
./.sonar/scanner/dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [v0.4.0]

- Add `VALUE_MATCHES` condition
- Use `SelectToken` to find matching source field

## [v0.3.0]

- Add fields `in-format` and `out-format` for date formatting
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Check the [Development Docs](./docs/Development.md) to get an overview of how th

### Mapping

Check the [Mappiong Docs](./docs/Mapping.md) to see how the mapping file works and what it can do for you.
Check the [Mapping Docs](./docs/Mapping.md) to see how the mapping file works and what it can do for you.

## Contribute

Expand Down
26 changes: 20 additions & 6 deletions docs/Mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,23 @@ The following types are supported as of now:

A condition contains the following information:

| Field | Values | Description |
| -------- | --------------------------------------------- | --------------------------------------------------- |
| `type` | `VALUE_EQUALS`<br>`VALUE_EXISTS`<br>`DEFAULT` | Type of the condition to check. |
| `field` | | Field to check the condition on from source system. |
| `equals` | Regex | Only required when the type `VALUE_EQUALS` is set. |
| `value` | | The value to set in the field of the target system. |
| Field | Values | Description |
| -------- | ---------------------------------------------------------------- | --------------------------------------------------------------------- |
| `type` | `VALUE_EQUALS`<br>`VALUE_MATCHES`<br>`VALUE_EXISTS`<br>`DEFAULT` | Type of the condition to check. |
| `field` | | Field to check the condition on from source system. |
| `equals` | | Only required when the type `VALUE_EQUALS` or `VALUE_MATCHES` is set. |
| `value` | `<value>`<br>`DO_NOT_OVERRIDE` | The value to set in the field of the target system. |

### Type

The following condition types exist:

- `VALUE_EQUALS` - Condition is applied if the value of the filed matches the value specified in the `equals` field (Case insensitive).
- `VALUE_MATCHES` - Condition is applied if the value of the filed matches the regex specified in the `equals` field.
- `VALUE_EXISTS` - Condition is applied if a value exists in the field.
- `DEFAULT` - Condition is always applied

### Value

- `<value>` - Writes the value in the field if the condition applies
- `DO_NOT_OVERRIDE` - Prevents the value from being updated if the condition applies
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public static class ConditionHandlerFactory
{
ConditionType.VALUE_EXISTS => new ValueExistsCondition(),
ConditionType.VALUE_EQUALS => new ValueEqualsCondition(),
ConditionType.VALUE_MATCHES => new ValueMatchesCondition(),
ConditionType.VALUE_DOES_NOT_EQUAL => new ValueDoesNotEqualCondition(),
_ => new DefaultCondition(),
};
Expand Down
34 changes: 34 additions & 0 deletions source/src/data-mapper/Condition/ValueMatchesCondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Buhlergroup.DataMapper.Condition
{
using System;
using System.Text.RegularExpressions;
using Buhlergroup.DataMapper.Model;
using Newtonsoft.Json.Linq;

public class ValueMatchesCondition : ICondition
{
public string Apply(FieldConditionModel condition, JObject model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}

if (condition == null)
{
throw new ArgumentNullException(nameof(condition));
}

var fieldValue = (string)model[condition.Field];

if (fieldValue == null)
{
return null;
}

var matches = Regex.IsMatch(fieldValue, condition.EqualsValue);

return Regex.IsMatch(fieldValue, condition.EqualsValue) ? condition.Value : null;
}
}
}
2 changes: 1 addition & 1 deletion source/src/data-mapper/Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public object GetFieldValue(JObject model, FieldMappingModel map)
return null;
}

var value = model.Value<object>(map.SourceFields.First());
var value = model.SelectToken(map.SourceFields.First());
if (!_validationHelper.ValidateField(map, value))
{
return null;
Expand Down
3 changes: 2 additions & 1 deletion source/src/data-mapper/Model/ConditionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum ConditionType
DEFAULT = 0,
VALUE_EXISTS = 1,
VALUE_EQUALS = 2,
VALUE_DOES_NOT_EQUAL = 3
VALUE_DOES_NOT_EQUAL = 3,
VALUE_MATCHES = 4
}
}
116 changes: 116 additions & 0 deletions source/tests/data-mapper-test/Condition/ValueMatchesConditionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
namespace Buhlergroup.DataMapper.Condition.Test
{
using System;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Model;
using Newtonsoft.Json.Linq;

[TestClass]
public class ValueMatchesConditionTest
{
[TestMethod]
public void Apply_ThrowOnNullCondition()
{
var jsonObject = new JObject
{
{ "bpmnr", "123" }
};

var handler = new ValueMatchesCondition();

Action act = () => handler.Apply(null, jsonObject);
act.Should().Throw<ArgumentNullException>();
}

[TestMethod]
public void Apply_ThrowOnNullObject()
{
var condition = new FieldConditionModel
{
Type = ConditionType.VALUE_MATCHES,
Field = "ms13actual",
Value = "ms13",
EqualsValue = "123"
};

var handler = new ValueMatchesCondition();

Action act = () => handler.Apply(condition, null);
act.Should().Throw<ArgumentNullException>();
}

[TestMethod]
public void Apply_Correctly()
{
var jsonObject = new JObject
{
{ "bpmnr", "123" }
};
var condition = new FieldConditionModel
{
Type = ConditionType.VALUE_MATCHES,
Field = "bpmnr",
Value = "1234",
EqualsValue = "[1-9]{3}"
};

var result = new ValueMatchesCondition().Apply(condition, jsonObject);
result.Should().Be("1234");
}

[TestMethod]
public void Apply_DoesNotEqual()
{
var jsonObject = new JObject
{
{ "bpmnr", "1234" }
};
var condition = new FieldConditionModel
{
Type = ConditionType.VALUE_MATCHES,
Field = "bpmnr",
Value = "1234",
EqualsValue = "[A-Z]"
};

var result = new ValueMatchesCondition().Apply(condition, jsonObject);
result.Should().BeNull();
}

[TestMethod]
public void Apply_EmptyField()
{
var jsonObject = new JObject
{
{ "bpmnr", "" }
};
var condition = new FieldConditionModel
{
Type = ConditionType.VALUE_MATCHES,
Field = "bpmnr",
Value = "1234",
EqualsValue = "[1-9]"
};

var result = new ValueMatchesCondition().Apply(condition, jsonObject);
result.Should().BeNull();
}

[TestMethod]
public void Apply_NonExistingField()
{
var jsonObject = new JObject();
var condition = new FieldConditionModel
{
Type = ConditionType.VALUE_MATCHES,
Field = "bpmnr",
Value = "1234",
EqualsValue = "123"
};

var result = new ValueMatchesCondition().Apply(condition, jsonObject);
result.Should().BeNull();
}
}
}
Loading

0 comments on commit 0d48b32

Please sign in to comment.