Skip to content

Commit

Permalink
Merge branch 'feature/Complex_alteration_bug_(#573)' into develop
Browse files Browse the repository at this point in the history
# Conflicts:
#	NBi.Testing.Core/Scalar/Resolver/FormatScalarResolverTest.cs
  • Loading branch information
Cédric L. Charlier committed Feb 4, 2020
2 parents 6baa70a + 5e597a3 commit d3915b4
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 32 deletions.
1 change: 1 addition & 0 deletions NBi.Core/NBi.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@
<Compile Include="ResultSet\Lookup\Violation\LookupViolationInformation.cs" />
<Compile Include="ResultSet\Lookup\Violation\LookupMatchesViolationData.cs" />
<Compile Include="ResultSet\Lookup\Violation\RowViolationState.cs" />
<Compile Include="Scalar\Casting\UntypedCaster.cs" />
<Compile Include="Scalar\Comparer\CellComparer.cs" />
<Compile Include="Scalar\Comparer\ComparerFactory.cs" />
<Compile Include="Report\DatabaseReportingParser.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public ResultSet Execute(ResultSet candidate)
var stopWatch = new Stopwatch();
stopWatch.Start();
var referenceKeyRetriever = BuildColumnsRetriever(Args.Mapping, x => x.ReferenceColumn);
var referenceValueRetriever = BuildColumnsRetriever(new ColumnMapping(Args.Replacement, ColumnType.Text), x => x.ReferenceColumn);
var referenceValueRetriever = BuildColumnsRetriever(new ColumnMapping(Args.Replacement, ColumnType.Untyped), x => x.ReferenceColumn);
var index = BuildReferenceIndex(reference.Table, referenceKeyRetriever, referenceValueRetriever);
Trace.WriteLineIf(Extensibility.NBiTraceSwitch.TraceInfo, $"Built the index for reference table containing {index.Count()} rows [{stopWatch.Elapsed:d'.'hh':'mm':'ss'.'fff'ms'}]");

Expand Down
1 change: 1 addition & 0 deletions NBi.Core/ResultSet/ColumnType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace NBi.Core.ResultSet
{
public enum ColumnType
{
Untyped = -1,
[XmlEnum(Name = "text")]
Text = 0,
[XmlEnum(Name = "numeric")]
Expand Down
2 changes: 1 addition & 1 deletion NBi.Core/ResultSet/ICell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace NBi.Core.ResultSet
{
public interface ICell
{
string Value { get; set; }
object Value { get; set; }
string ColumnName { get; set; }
}
}
4 changes: 2 additions & 2 deletions NBi.Core/ResultSet/Resolver/ObjectsToRowsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public IEnumerable<IRow> Execute(IEnumerable<object> objects)
if (obj is IEnumerable<object> items)
foreach (var item in items)
{
var cell = new Cell() { Value = item?.ToString() };
var cell = new Cell() { Value = item };
row.Cells.Add(cell);
}
rows.Add(row);
Expand All @@ -35,7 +35,7 @@ private class Row : IRow

private class Cell : ICell
{
public string Value { get; set; }
public object Value { get; set; }
public string ColumnName { get; set; }
}
}
Expand Down
1 change: 1 addition & 0 deletions NBi.Core/Scalar/Casting/CasterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public ICaster Instantiate(ColumnType type)
{
switch (type)
{
case ColumnType.Untyped: return new UntypedCaster();
case ColumnType.Text: return new TextCaster();
case ColumnType.Numeric: return new NumericCaster();
case ColumnType.Boolean: return new BooleanCaster();
Expand Down
10 changes: 10 additions & 0 deletions NBi.Core/Scalar/Casting/TextCaster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ public string Execute(object value)
{
if (value is string)
return (string)value;

if (value is DateTime)
return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");

if (value is bool)
return (bool)value ? "True" : "False";

var numericCaster = new NumericCaster();
if (numericCaster.IsStrictlyValid(value))
return Convert.ToDecimal(value).ToString(new CultureFactory().Invariant.NumberFormat);

return value.ToString();
}
Expand Down
19 changes: 19 additions & 0 deletions NBi.Core/Scalar/Casting/UntypedCaster.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NBi.Core.Scalar.Casting
{
class UntypedCaster : ICaster<object>
{
public object Execute(object value)
=> value;

object ICaster.Execute(object value) => Execute(value);

public bool IsValid(object value) => true;
public bool IsStrictlyValid(object obj) => true;
}
}
16 changes: 8 additions & 8 deletions NBi.Testing.Core/Calculation/Ranking/BottomRankingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void Apply_Rows_Success(object[] values, ColumnType columnType, int index
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(1));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index.ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Min()));
}

Expand All @@ -55,9 +55,9 @@ public void Apply_TopTwo_Success(object[] values, ColumnType columnType, int[] i
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(2));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0].ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0]));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Min()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1].ToString()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1]));
Assert.That(filteredRs.Rows[1].ItemArray[1], Is.EqualTo(values.Except(Enumerable.Repeat(values.Min(), 1)).Min()));
}

Expand All @@ -76,11 +76,11 @@ public void Apply_Larger_Success(object[] values, ColumnType columnType, int[] i
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(values.Count()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0].ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0]));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Min()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1].ToString()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1]));
Assert.That(filteredRs.Rows[1].ItemArray[1], Is.EqualTo(values.Except(Enumerable.Repeat(values.Min(), 1)).Min()));
Assert.That(filteredRs.Rows[values.Count() - 1].ItemArray[0], Is.EqualTo(index[2].ToString()));
Assert.That(filteredRs.Rows[values.Count() - 1].ItemArray[0], Is.EqualTo(index[2]));
Assert.That(filteredRs.Rows[values.Count() - 1].ItemArray[1], Is.EqualTo(values.Max()));
}

Expand All @@ -101,7 +101,7 @@ public void Apply_Alias_Success(object[] values, ColumnType columnType, int inde
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(1));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index.ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Min()));
}

Expand All @@ -123,7 +123,7 @@ public void Apply_Exp_Success(object[] values, ColumnType columnType, int index)
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(1));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index.ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo("125"));
}

Expand Down
17 changes: 9 additions & 8 deletions NBi.Testing.Core/Calculation/Ranking/TopRankingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class TopRankingTest
[TestCase(new object[] { "100", "120", "110", "130", "105" }, ColumnType.Numeric, 4)]
[TestCase(new object[] { "a", "b", "e", "c", "d" }, ColumnType.Text, 3)]
[TestCase(new object[] { "2010-02-02 07:12:16.52", "2010-02-02 07:12:16.55", "2010-02-02 08:12:16.50" }, ColumnType.DateTime, 3)]

public void Apply_Rows_Success(object[] values, ColumnType columnType, int index)
{
var i = 0;
Expand All @@ -34,7 +35,7 @@ public void Apply_Rows_Success(object[] values, ColumnType columnType, int index
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(1));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index.ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Max()));
}

Expand All @@ -55,9 +56,9 @@ public void Apply_TopTwo_Success(object[] values, ColumnType columnType, int[] i
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(2));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0].ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0]));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Max()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1].ToString()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1]));
Assert.That(filteredRs.Rows[1].ItemArray[1], Is.EqualTo(values.Except(Enumerable.Repeat(values.Max(), 1)).Max()));
}

Expand All @@ -76,11 +77,11 @@ public void Apply_Larger_Success(object[] values, ColumnType columnType, int[] i
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(values.Count()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0].ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index[0]));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Max()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1].ToString()));
Assert.That(filteredRs.Rows[1].ItemArray[0], Is.EqualTo(index[1]));
Assert.That(filteredRs.Rows[1].ItemArray[1], Is.EqualTo(values.Except(Enumerable.Repeat(values.Max(), 1)).Max()));
Assert.That(filteredRs.Rows[values.Count() - 1].ItemArray[0], Is.EqualTo(index[2].ToString()));
Assert.That(filteredRs.Rows[values.Count() - 1].ItemArray[0], Is.EqualTo(index[2]));
Assert.That(filteredRs.Rows[values.Count() - 1].ItemArray[1], Is.EqualTo(values.Min()));
}

Expand All @@ -102,7 +103,7 @@ public void Apply_Alias_Success(object[] values, ColumnType columnType, int inde
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(1));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index.ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo(values.Max()));
}

Expand All @@ -124,7 +125,7 @@ public void Apply_Exp_Success(object[] values, ColumnType columnType, int index)
var filteredRs = ranking.Apply(rs);

Assert.That(filteredRs.Rows.Count, Is.EqualTo(1));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index.ToString()));
Assert.That(filteredRs.Rows[0].ItemArray[0], Is.EqualTo(index));
Assert.That(filteredRs.Rows[0].ItemArray[1], Is.EqualTo("139"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,43 @@ public void Execute_AllLookupFound_CorrectReplacement()
Assert.That(result.Rows.Cast<DataRow>().Select(x => x[1] as string).Where(x => x != "alpha" && x != "beta"), Is.Empty);
}

[Test]
public void Execute_AllLookupFoundSwitchingFromTextToNumeric_CorrectReplacement()
{
var candidate = new ObjectsResultSetResolver(
new ObjectsResultSetResolverArgs(
new[] {
new object[] { 1, "A", 100 },
new object[] { 2, "B", 101 },
new object[] { 3, "A", 125 },
new object[] { 4, "B", 155 }
}
)).Execute();

var reference = new ResultSetService(
new ObjectsResultSetResolver(
new ObjectsResultSetResolverArgs(
new[] {
new object[] { "A", 10.2 },
new object[] { "B", 21.1 },
}
)).Execute, null);

var engine = new LookupReplaceEngine(
new LookupReplaceArgs(
reference,
new ColumnMapping(new ColumnOrdinalIdentifier(1), new ColumnOrdinalIdentifier(0), ColumnType.Text),
new ColumnOrdinalIdentifier(1)
));

var result = engine.Execute(candidate);
Assert.That(result.Columns.Count, Is.EqualTo(3));
Assert.That(result.Rows.Count, Is.EqualTo(4));
Assert.That(result.Rows.Cast<DataRow>().Select(x => x[1]).Distinct(), Does.Contain(10.2));
Assert.That(result.Rows.Cast<DataRow>().Select(x => x[1]).Distinct(), Does.Contain(21.1));
Assert.That(result.Rows.Cast<DataRow>().Select(x => Convert.ToDecimal(x[1])).Where(x => x != 10.2m && x != 21.1m), Is.Empty);
}

[Test]
public void ExecuteWithFailureStretegy_OneLookupMissing_ExceptionThrown()
{
Expand Down
16 changes: 9 additions & 7 deletions NBi.Testing.Core/ResultSet/ResultSetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,20 @@ public void Load_ThreeIRowsWithTwoICells_ThreeRowsAndTwoColumns()
var objects = new List<IRow> {
Mock.Of<IRow> (
x => x.Cells == new List<ICell> {
Mock.Of<ICell>( y=> y.Value == "CY 2001"),
Mock.Of<ICell>( y=> y.Value == "1000") }
Mock.Of<ICell>(y => (string)(y.Value) == "CY 2001"),
Mock.Of<ICell>(y => (decimal)(y.Value) == 1000) }
)
,
Mock.Of<IRow>(
x => x.Cells == new List<ICell> {
Mock.Of<ICell>(y=> y.Value == "CY 2002"),
Mock.Of<ICell>(y => y.Value == "10.4") }
Mock.Of<ICell>(y => (string)(y.Value) == "CY 2002"),
Mock.Of<ICell>(y => (decimal)(y.Value) == 10.4m) }
)
,
Mock.Of<IRow>(
x => x.Cells == new List<ICell> {
Mock.Of<ICell> ( y=> y.Value == "CY 2003"),
Mock.Of<ICell>(y => y.Value == "200") }
Mock.Of<ICell>(y => (string)(y.Value) == "CY 2003"),
Mock.Of<ICell>(y => (decimal)(y.Value) == 200) }
)
};

Expand All @@ -86,7 +86,9 @@ public void Load_ThreeIRowsWithTwoICells_ThreeRowsAndTwoColumns()
Assert.That(rs.Rows.Count, Is.EqualTo(3));

Assert.That(rs.Rows[0].ItemArray[0], Is.EqualTo("CY 2001"));
Assert.That(rs.Rows[0].ItemArray[1], Is.EqualTo("1000"));
Assert.That(rs.Rows[0].ItemArray[1], Is.EqualTo(1000));
Assert.That(rs.Rows[1].ItemArray[0], Is.EqualTo("CY 2002"));
Assert.That(rs.Rows[1].ItemArray[1], Is.EqualTo(10.4));
}

[Test]
Expand Down
1 change: 1 addition & 0 deletions NBi.Testing.Core/Variable/InstanceFactoryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace NBi.Testing.Core.Variable
public class InstanceFactoryTest
{
[Test]
[Culture("en-us")]
public void Instantiate_DerivedFromMain_Success()
{
var resolver = new Mock<ISequenceResolver>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2133,6 +2133,49 @@
</equal-to>
</assert>
</test>
<test name="alteration with replacement of a text value by a numeric value" uid="0291">
<system-under-test>
<result-set>
<row>
<cell>39.500</cell>
<cell>8.200</cell>
</row>
</result-set>
</system-under-test>
<assert>
<equal-to behavior="single-row" values-default-type="numeric">
<result-set>
<row>
<cell>2018-10-01</cell>
<cell>8.200</cell>
</row>
<alteration>
<lookup-replace>
<missing behavior="default-value">0</missing>
<join>
<mapping candidate="#0" reference="#0" />
</join>
<result-set>
<row>
<cell>2018-10-01</cell>
<cell>39.500</cell>
</row>
<alteration>
<summarize>
<sum column="#1" type="numeric" />
<group-by>
<column identifier="#0" />
</group-by>
</summarize>
</alteration>
</result-set>
<replacement identifier="#1" />
</lookup-replace>
</alteration>
</result-set>
</equal-to>
</assert>
</test>
<test name="Transform, lookup-replace, summarize, unstack, extend, project" uid="0300">
<system-under-test>
<result-set>
Expand Down
10 changes: 5 additions & 5 deletions NBi.Xml/Items/ResultSet/CellXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ namespace NBi.Xml.Items.ResultSet
public class CellXml : ICell
{
[XmlText]
public string Value { get; set; }
public string StringValue { get; set; }

[XmlIgnore]
public object Value { get => StringValue; set { StringValue = value.ToString(); } }

[XmlAttribute("column-name")]
public string ColumnName { get; set; }

public override string ToString()
{
return Value;
}
public override string ToString() => StringValue.ToString();
}
}

0 comments on commit d3915b4

Please sign in to comment.