From ac30e44af2fc0494b1fb6aa4abd86f42e56d5a6f Mon Sep 17 00:00:00 2001 From: Daniel Petrov Date: Tue, 18 Oct 2022 18:39:45 +0200 Subject: [PATCH 1/5] Add replace_last and remove_last filters --- Fluid.Tests/StringFiltersTests.cs | 29 +++++++++++++++++++++++++++- Fluid/Filters/StringFilters.cs | 32 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/Fluid.Tests/StringFiltersTests.cs b/Fluid.Tests/StringFiltersTests.cs index 6f91a9c1..2728168d 100644 --- a/Fluid.Tests/StringFiltersTests.cs +++ b/Fluid.Tests/StringFiltersTests.cs @@ -161,6 +161,21 @@ public void RemovesReturnsInputWhenArgumentIsEmpty() var context = new TemplateContext(); var result = StringFilters.Remove(input, arguments, context); + + Assert.Equal("abcabc", result.Result.ToStringValue()); + } + + [Fact] + public void RemoveLast() + { + var input = new StringValue("abcabc"); + + var arguments = new FilterArguments().Add(new StringValue("b")); + var context = new TemplateContext(); + + var result = StringFilters.RemoveLast(input, arguments, context); + + Assert.Equal("abcac", result.Result.ToStringValue()); } [Fact] @@ -189,8 +204,20 @@ public void Replace() Assert.Equal("aBcaBc", result.Result.ToStringValue()); } - [Theory] + [Fact] + public void ReplaceLast() + { + var input = new StringValue("abcabc"); + var arguments = new FilterArguments().Add(new StringValue("b")).Add(new StringValue("B")); + var context = new TemplateContext(); + + var result = StringFilters.ReplaceLast(input, arguments, context); + + Assert.Equal("abcaBc", result.Result.ToStringValue()); + } + + [Theory] [InlineData("hello", new object[] { 0 }, "h")] [InlineData("hello", new object[] { 1 }, "e")] [InlineData("hello", new object[] { 1, 3 }, "ell")] diff --git a/Fluid/Filters/StringFilters.cs b/Fluid/Filters/StringFilters.cs index 5f22d7c3..bd5d5967 100644 --- a/Fluid/Filters/StringFilters.cs +++ b/Fluid/Filters/StringFilters.cs @@ -22,8 +22,10 @@ public static FilterCollection WithStringFilters(this FilterCollection filters) filters.AddFilter("prepend", Prepend); filters.AddFilter("remove_first", RemoveFirst); filters.AddFilter("remove", Remove); + filters.AddFilter("remove_last", RemoveLast); filters.AddFilter("replace_first", ReplaceFirst); filters.AddFilter("replace", Replace); + filters.AddFilter("replace_last", ReplaceLast); filters.AddFilter("slice", Slice); filters.AddFilter("split", Split); filters.AddFilter("strip", Strip); @@ -108,6 +110,21 @@ public static ValueTask Remove(FluidValue input, FilterArguments arg return new StringValue(input.ToStringValue().Replace(argument, "")); } + public static ValueTask RemoveLast(FluidValue input, FilterArguments arguments, TemplateContext context) + { + var remove = arguments.At(0).ToStringValue(); + var value = input.ToStringValue(); + + var index = value.LastIndexOf(remove); + + if (index != -1) + { + return new StringValue(value.Remove(index, remove.Length)); + } + + return input; + } + public static ValueTask ReplaceFirst(FluidValue input, FilterArguments arguments, TemplateContext context) { string remove = arguments.At(0).ToStringValue(); @@ -128,6 +145,21 @@ public static ValueTask Replace(FluidValue input, FilterArguments ar return new StringValue(input.ToStringValue().Replace(arguments.At(0).ToStringValue(), arguments.At(1).ToStringValue())); } + public static ValueTask ReplaceLast(FluidValue input, FilterArguments arguments, TemplateContext context) + { + var remove = arguments.At(0).ToStringValue(); + var value = input.ToStringValue(); + + var index = value.LastIndexOf(remove); + + if (index != -1) + { + return new StringValue(value.Substring(0, index) + arguments.At(1).ToStringValue() + value.Substring(index + remove.Length)); + } + + return input; + } + public static ValueTask Slice(FluidValue input, FilterArguments arguments, TemplateContext context) { var firstArgument = arguments.At(0); From 6818e2ef29caa1a14ae2303a3f2c231024f0e5be Mon Sep 17 00:00:00 2001 From: Daniel Petrov Date: Tue, 18 Oct 2022 23:23:40 +0200 Subject: [PATCH 2/5] Add replace test cases --- Fluid.Tests/StringFiltersTests.cs | 51 ++++++++++++++++++------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/Fluid.Tests/StringFiltersTests.cs b/Fluid.Tests/StringFiltersTests.cs index 2728168d..554f9ee9 100644 --- a/Fluid.Tests/StringFiltersTests.cs +++ b/Fluid.Tests/StringFiltersTests.cs @@ -178,43 +178,52 @@ public void RemoveLast() Assert.Equal("abcac", result.Result.ToStringValue()); } - [Fact] - public void ReplaceFirst() + [Theory] + [InlineData("a a a a", new object[] { "a", "b" }, "b a a a")] + [InlineData("1 1 1 1", new object[] { 1, 2 }, "2 1 1 1")] + [InlineData("1 1 1 1", new object[] { 2, 3 }, "1 1 1 1")] + [InlineData("1 1 1 1", new object[] { "1", 2 }, "2 1 1 1")] + public void ReplaceFirst(string input, object[] arguments, string expected) { - var input = new StringValue("abcabc"); - - var arguments = new FilterArguments().Add(new StringValue("b")).Add(new StringValue("B")); + var filterInput = new StringValue(input); + var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); var context = new TemplateContext(); - var result = StringFilters.ReplaceFirst(input, arguments, context); + var result = StringFilters.ReplaceFirst(filterInput, filterArguments, context); - Assert.Equal("aBcabc", result.Result.ToStringValue()); + Assert.Equal(expected, result.Result.ToStringValue()); } - [Fact] - public void Replace() + [Theory] + [InlineData("a a a a", new object[] { "a", "b" }, "b b b b")] + [InlineData("1 1 1 1", new object[] { 1, 2 }, "2 2 2 2")] + [InlineData("1 1 1 1", new object[] { 2, 3 }, "1 1 1 1")] + [InlineData("1 1 1 1", new object[] { "1", 2 }, "2 2 2 2")] + public void Replace(string input, object[] arguments, string expected) { - var input = new StringValue("abcabc"); - - var arguments = new FilterArguments().Add(new StringValue("b")).Add(new StringValue("B")); + var filterInput = new StringValue(input); + var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); var context = new TemplateContext(); - var result = StringFilters.Replace(input, arguments, context); + var result = StringFilters.Replace(filterInput, filterArguments, context); - Assert.Equal("aBcaBc", result.Result.ToStringValue()); + Assert.Equal(expected, result.Result.ToStringValue()); } - [Fact] - public void ReplaceLast() + [Theory] + [InlineData("a a a a", new object[] { "a", "b" }, "a a a b")] + [InlineData("1 1 1 1", new object[] { 1, 2 }, "1 1 1 2")] + [InlineData("1 1 1 1", new object[] { 2, 3 }, "1 1 1 1")] + [InlineData("1 1 1 1", new object[] { "1", 2 }, "1 1 1 2")] + public void ReplaceLast(string input, object[] arguments, string expected) { - var input = new StringValue("abcabc"); - - var arguments = new FilterArguments().Add(new StringValue("b")).Add(new StringValue("B")); + var filterInput = new StringValue(input); + var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); var context = new TemplateContext(); - var result = StringFilters.ReplaceLast(input, arguments, context); + var result = StringFilters.ReplaceLast(filterInput, filterArguments, context); - Assert.Equal("abcaBc", result.Result.ToStringValue()); + Assert.Equal(expected, result.Result.ToStringValue()); } [Theory] From 9dcb0f59b8f996a6c6a8bb4fac81f148a3e81be8 Mon Sep 17 00:00:00 2001 From: Daniel Petrov Date: Tue, 18 Oct 2022 23:43:52 +0200 Subject: [PATCH 3/5] Add remove test cases --- .../Extensions/ConversionExtensions.cs | 13 +++++ Fluid.Tests/StringFiltersTests.cs | 52 ++++++++++--------- 2 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 Fluid.Tests/Extensions/ConversionExtensions.cs diff --git a/Fluid.Tests/Extensions/ConversionExtensions.cs b/Fluid.Tests/Extensions/ConversionExtensions.cs new file mode 100644 index 00000000..d96002fb --- /dev/null +++ b/Fluid.Tests/Extensions/ConversionExtensions.cs @@ -0,0 +1,13 @@ +using Fluid.Values; +using System.Linq; + +namespace Fluid.Tests.Extensions +{ + internal static class ConversionExtensions + { + public static FilterArguments ToFilterArguments(this object[] arguments) + { + return new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); + } + } +} diff --git a/Fluid.Tests/StringFiltersTests.cs b/Fluid.Tests/StringFiltersTests.cs index 554f9ee9..807002b3 100644 --- a/Fluid.Tests/StringFiltersTests.cs +++ b/Fluid.Tests/StringFiltersTests.cs @@ -2,6 +2,7 @@ using Fluid.Values; using Fluid.Filters; using Xunit; +using Fluid.Tests.Extensions; namespace Fluid.Tests { @@ -126,30 +127,32 @@ public void Prepend() Assert.Equal("Hello World", result.Result.ToStringValue()); } - [Fact] - public void RemoveFirst() + [Theory] + [InlineData("a b a a", new object[] { "a " }, "b a a")] + [InlineData("1 1 1 1", new object[] { 1 }, " 1 1 1")] + public void RemoveFirst(string input, object[] arguments, string expected) { - var input = new StringValue("abcabc"); - - var arguments = new FilterArguments().Add(new StringValue("b")); + var filterInput = new StringValue(input); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); - var result = StringFilters.RemoveFirst(input, arguments, context); + var result = StringFilters.RemoveFirst(filterInput, filterArguments, context); - Assert.Equal("acabc", result.Result.ToStringValue()); + Assert.Equal(expected, result.Result.ToStringValue()); } - [Fact] - public void Remove() + [Theory] + [InlineData("a a a a", new object[] { "a" }, " ")] + [InlineData("1 1 1 1", new object[] { 1 }, " ")] + public void Remove(string input, object[] arguments, string expected) { - var input = new StringValue("abcabc"); - - var arguments = new FilterArguments().Add(new StringValue("b")); + var filterInput = new StringValue(input); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); - var result = StringFilters.Remove(input, arguments, context); + var result = StringFilters.Remove(filterInput, filterArguments, context); - Assert.Equal("acac", result.Result.ToStringValue()); + Assert.Equal(expected, result.Result.ToStringValue()); } [Fact] @@ -165,17 +168,18 @@ public void RemovesReturnsInputWhenArgumentIsEmpty() Assert.Equal("abcabc", result.Result.ToStringValue()); } - [Fact] - public void RemoveLast() + [Theory] + [InlineData("a a b a", new object[] { " a" }, "a a b")] + [InlineData("1 1 1 1", new object[] { 1 }, "1 1 1 ")] + public void RemoveLast(string input, object[] arguments, string expected) { - var input = new StringValue("abcabc"); - - var arguments = new FilterArguments().Add(new StringValue("b")); + var filterInput = new StringValue(input); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); - var result = StringFilters.RemoveLast(input, arguments, context); + var result = StringFilters.RemoveLast(filterInput, filterArguments, context); - Assert.Equal("abcac", result.Result.ToStringValue()); + Assert.Equal(expected, result.Result.ToStringValue()); } [Theory] @@ -186,7 +190,7 @@ public void RemoveLast() public void ReplaceFirst(string input, object[] arguments, string expected) { var filterInput = new StringValue(input); - var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); var result = StringFilters.ReplaceFirst(filterInput, filterArguments, context); @@ -202,7 +206,7 @@ public void ReplaceFirst(string input, object[] arguments, string expected) public void Replace(string input, object[] arguments, string expected) { var filterInput = new StringValue(input); - var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); var result = StringFilters.Replace(filterInput, filterArguments, context); @@ -218,7 +222,7 @@ public void Replace(string input, object[] arguments, string expected) public void ReplaceLast(string input, object[] arguments, string expected) { var filterInput = new StringValue(input); - var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); var result = StringFilters.ReplaceLast(filterInput, filterArguments, context); From 04fac614a5fdb3d1c8a689b8cdf7d005c00def2a Mon Sep 17 00:00:00 2001 From: Daniel Petrov Date: Tue, 18 Oct 2022 23:54:14 +0200 Subject: [PATCH 4/5] DRY --- Fluid.Tests/ColorFiltersTests.cs | 20 +++++++++---------- .../Integration/StandardFilterTests.cs | 8 ++++---- Fluid.Tests/StringFiltersTests.cs | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Fluid.Tests/ColorFiltersTests.cs b/Fluid.Tests/ColorFiltersTests.cs index 896f6c8a..2ee800e9 100644 --- a/Fluid.Tests/ColorFiltersTests.cs +++ b/Fluid.Tests/ColorFiltersTests.cs @@ -1,7 +1,7 @@ using Fluid.Filters; +using Fluid.Tests.Extensions; using Fluid.Values; using System.Globalization; -using System.Linq; using Xunit; namespace Fluid.Tests @@ -188,7 +188,7 @@ public void ColorExtract(string color, object[] arguments, string expected) var context = new TemplateContext(); // Act - var result = ColorFilters.ColorExtract(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.ColorExtract(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToStringValue()); @@ -246,7 +246,7 @@ public void ColorModify(string color, object[] arguments, string expected) var context = new TemplateContext(); // Act - var result = ColorFilters.ColorModify(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.ColorModify(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToStringValue()); @@ -304,7 +304,7 @@ public void ColorSaturate(string color, object[] arguments, string expected) var context = new TemplateContext(); // Act - var result = ColorFilters.ColorSaturate(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.ColorSaturate(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToStringValue()); @@ -321,7 +321,7 @@ public void ColorDesaturate(string color, object[] arguments, string expected) var context = new TemplateContext(); // Act - var result = ColorFilters.ColorDesaturate(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.ColorDesaturate(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToStringValue()); @@ -338,7 +338,7 @@ public void ColorLighten(string color, object[] arguments, string expected) var context = new TemplateContext(); // Act - var result = ColorFilters.ColorLighten(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.ColorLighten(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToStringValue()); @@ -355,7 +355,7 @@ public void ColorDarken(string color, object[] arguments, string expected) var context = new TemplateContext(); // Act - var result = ColorFilters.ColorDarken(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.ColorDarken(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToStringValue()); @@ -372,7 +372,7 @@ public void ColorDifference(string color, object[] arguments, decimal expected) var context = new TemplateContext(); // Act - var result = ColorFilters.GetColorDifference(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.GetColorDifference(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToNumberValue()); @@ -389,7 +389,7 @@ public void BrightnessDifference(string color, object[] arguments, decimal expec var context = new TemplateContext(); // Act - var result = ColorFilters.GetColorBrightnessDifference(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.GetColorBrightnessDifference(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToNumberValue()); @@ -406,7 +406,7 @@ public void ColorContrast(string color, object[] arguments, decimal expected) var context = new TemplateContext(); // Act - var result = ColorFilters.GetColorContrast(input, new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), context); + var result = ColorFilters.GetColorContrast(input, arguments.ToFilterArguments(), context); // Assert Assert.Equal(expected, result.Result.ToNumberValue()); diff --git a/Fluid.Tests/Integration/StandardFilterTests.cs b/Fluid.Tests/Integration/StandardFilterTests.cs index fe7fde9d..39c8c1fe 100644 --- a/Fluid.Tests/Integration/StandardFilterTests.cs +++ b/Fluid.Tests/Integration/StandardFilterTests.cs @@ -1,7 +1,7 @@ using Fluid.Filters; +using Fluid.Tests.Extensions; using Fluid.Values; using System; -using System.Linq; using System.Threading.Tasks; using Xunit; @@ -50,7 +50,7 @@ public void TestUpcase(string expected, object input) [InlineData("oob", "foobar", "1", "3")] public void TestSlice(string expected, object input, params object[] arguments) { - Assert.Equal(expected, StringFilters.Slice(FluidValue.Create(input, TemplateOptions.Default), new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), new TemplateContext()).Result.ToObjectValue()); + Assert.Equal(expected, StringFilters.Slice(FluidValue.Create(input, TemplateOptions.Default), arguments.ToFilterArguments(), new TemplateContext()).Result.ToObjectValue()); } [Theory] @@ -58,7 +58,7 @@ public void TestSlice(string expected, object input, params object[] arguments) [InlineData("foobar", 0, "")] public void TestSliceArgument(object input, params object[] arguments) { - Assert.Throws(() => StringFilters.Slice(FluidValue.Create(input, TemplateOptions.Default), new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), new TemplateContext()).Result.ToObjectValue()); + Assert.Throws(() => StringFilters.Slice(FluidValue.Create(input, TemplateOptions.Default), arguments.ToFilterArguments(), new TemplateContext()).Result.ToObjectValue()); } [Theory] @@ -76,7 +76,7 @@ public void TestSliceOnArrays(string expected, params object[] arguments) { var foobar = new object [] { 'f', 'o', 'o', 'b', 'a', 'r' }; - var result = StringFilters.Slice(FluidValue.Create(foobar, TemplateOptions.Default), new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()), new TemplateContext()); + var result = StringFilters.Slice(FluidValue.Create(foobar, TemplateOptions.Default), arguments.ToFilterArguments(), new TemplateContext()); Assert.IsType(result.Result); string resultString = ""; diff --git a/Fluid.Tests/StringFiltersTests.cs b/Fluid.Tests/StringFiltersTests.cs index 807002b3..8001577c 100644 --- a/Fluid.Tests/StringFiltersTests.cs +++ b/Fluid.Tests/StringFiltersTests.cs @@ -240,7 +240,7 @@ public void ReplaceLast(string input, object[] arguments, string expected) public void Slice(object input, object[] arguments, string expected) { var filterInput = FluidValue.Create(input, TemplateOptions.Default); - var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); var result = StringFilters.Slice(filterInput, filterArguments, context); @@ -262,7 +262,7 @@ public void Slice(object input, object[] arguments, string expected) public void SliceOutsideBounds(object input, object[] arguments, string expected) { var filterInput = FluidValue.Create(input, TemplateOptions.Default); - var filterArguments = new FilterArguments(arguments.Select(x => FluidValue.Create(x, TemplateOptions.Default)).ToArray()); + var filterArguments = arguments.ToFilterArguments(); var context = new TemplateContext(); var result = StringFilters.Slice(filterInput, filterArguments, context); From 95e9d101267b744d66310706cf228bc0fde6ec1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Tue, 18 Oct 2022 15:01:51 -0700 Subject: [PATCH 5/5] Update StringFiltersTests.cs --- Fluid.Tests/StringFiltersTests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Fluid.Tests/StringFiltersTests.cs b/Fluid.Tests/StringFiltersTests.cs index 8001577c..d64a6814 100644 --- a/Fluid.Tests/StringFiltersTests.cs +++ b/Fluid.Tests/StringFiltersTests.cs @@ -187,6 +187,7 @@ public void RemoveLast(string input, object[] arguments, string expected) [InlineData("1 1 1 1", new object[] { 1, 2 }, "2 1 1 1")] [InlineData("1 1 1 1", new object[] { 2, 3 }, "1 1 1 1")] [InlineData("1 1 1 1", new object[] { "1", 2 }, "2 1 1 1")] + [InlineData("aa bb cc aa bb cc", new object[] { "cc", "dd" }, "aa bb dd aa bb cc")] public void ReplaceFirst(string input, object[] arguments, string expected) { var filterInput = new StringValue(input); @@ -203,6 +204,7 @@ public void ReplaceFirst(string input, object[] arguments, string expected) [InlineData("1 1 1 1", new object[] { 1, 2 }, "2 2 2 2")] [InlineData("1 1 1 1", new object[] { 2, 3 }, "1 1 1 1")] [InlineData("1 1 1 1", new object[] { "1", 2 }, "2 2 2 2")] + [InlineData("aa bb cc aa bb cc", new object[] { "cc", "dd" }, "aa bb dd aa bb dd")] public void Replace(string input, object[] arguments, string expected) { var filterInput = new StringValue(input); @@ -219,6 +221,7 @@ public void Replace(string input, object[] arguments, string expected) [InlineData("1 1 1 1", new object[] { 1, 2 }, "1 1 1 2")] [InlineData("1 1 1 1", new object[] { 2, 3 }, "1 1 1 1")] [InlineData("1 1 1 1", new object[] { "1", 2 }, "1 1 1 2")] + [InlineData("aa bb cc aa bb cc", new object[] { "cc", "dd" }, "aa bb cc aa bb dd")] public void ReplaceLast(string input, object[] arguments, string expected) { var filterInput = new StringValue(input);