242 lines
9.0 KiB
C#
242 lines
9.0 KiB
C#
/*
|
|
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
|
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
using NUnit.Framework;
|
|
|
|
namespace QuantConnect.Tests.Common
|
|
{
|
|
[TestFixture]
|
|
public class StringExtensionsTests
|
|
{
|
|
[Test]
|
|
[TestCase(typeof(string), "123", typeof(long), 123L)]
|
|
[TestCase(typeof(string), "123", typeof(int), 123)]
|
|
[TestCase(typeof(string), "123", typeof(decimal), 123)]
|
|
[TestCase(typeof(long), "123", typeof(decimal), 123)]
|
|
[TestCase(typeof(string), null, typeof(decimal), 0)]
|
|
public void ConvertInvariant(Type sourceType, string sourceString, Type conversionType, object expected)
|
|
{
|
|
// we can't put a decimal in the attribute, so this ensure the runtime types are correct
|
|
expected = Convert.ChangeType(expected, conversionType, CultureInfo.InvariantCulture);
|
|
Assert.IsInstanceOf(conversionType, expected);
|
|
|
|
var source = Convert.ChangeType(sourceString, sourceType, CultureInfo.InvariantCulture);
|
|
if (sourceString == null)
|
|
{
|
|
Assert.IsNull(source);
|
|
}
|
|
else
|
|
{
|
|
Assert.IsInstanceOf(sourceType, source);
|
|
}
|
|
|
|
var converted = ((IConvertible)source).ConvertInvariant(conversionType);
|
|
Assert.AreEqual(expected, converted);
|
|
Assert.IsInstanceOf(conversionType, converted);
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertInvariant_ThrowsFormatException_WhenConvertingEmptyString()
|
|
{
|
|
const string input = "";
|
|
Assert.Throws<FormatException>(
|
|
() => input.ConvertInvariant<decimal>()
|
|
);
|
|
}
|
|
|
|
[Test]
|
|
public void ConvertInvariantString()
|
|
{
|
|
var source = 123L;
|
|
const string expected = "123";
|
|
var actual = source.ConvertInvariant<string>();
|
|
Assert.AreEqual(expected, actual);
|
|
}
|
|
|
|
[Test]
|
|
public void Convertible_ToStringInvariant_Equals_ToStringInvariantCulture()
|
|
{
|
|
IConvertible convertible = 1;
|
|
var formatted = convertible.ToStringInvariant();
|
|
Assert.AreEqual(convertible.ToString(CultureInfo.InvariantCulture), formatted);
|
|
}
|
|
|
|
[Test]
|
|
public void Formattable_ToStringInvariant_DoesNotRequire_FormatParameter()
|
|
{
|
|
var format = (string) null;
|
|
IFormattable formattable = 1;
|
|
var formatted = formattable.ToStringInvariant(format);
|
|
Assert.AreEqual(formattable.ToString(format, CultureInfo.InvariantCulture), formatted);
|
|
}
|
|
|
|
[Test]
|
|
[TestCase(TypeCode.DateTime, "07/28/2019", "yyyy-MM-dd")]
|
|
public void Formattable_ToStringInvariant_UsesProvided_FormatParameter(
|
|
TypeCode typeCode,
|
|
string value,
|
|
string format
|
|
)
|
|
{
|
|
var formattable = (IFormattable) Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
|
|
var formatted = formattable.ToStringInvariant(format);
|
|
var expected = formattable.ToString(format, CultureInfo.InvariantCulture);
|
|
Assert.AreEqual(expected, formatted, $"Failed on type code: {typeCode}");
|
|
}
|
|
|
|
[Test]
|
|
public void Formattable_ToStringInvariant_RespectsFieldWidth_InFormatParameter()
|
|
{
|
|
// BEHAVIOR CHANGE --
|
|
var value = 5.678m;
|
|
var format = "-20:P2";
|
|
var sameBehavior = $"{value,-20:P2}";
|
|
var expected = string.Format(CultureInfo.InvariantCulture, "{0,-20:P2}", value);
|
|
|
|
// the usage of the InvariantCulture add a space between the number of the percent sign
|
|
//Assert.AreEqual("567.80% ", sameBehavior); // this passes in windows but failed in travis
|
|
Assert.AreEqual("567.80 % ", expected);
|
|
|
|
var actual = value.ToStringInvariant(format);
|
|
Assert.AreEqual(expected, actual);
|
|
}
|
|
|
|
[Test]
|
|
public void StartsWithInvariant_IsTheSameAs_StartsWith_WithInvariantCulture_DefaultingToCaseSensitive()
|
|
{
|
|
var str = "aBcD";
|
|
var beginning = "aB";
|
|
Assert.IsTrue(str.StartsWithInvariant(beginning));
|
|
|
|
beginning = "AB";
|
|
Assert.IsFalse(str.StartsWithInvariant(beginning));
|
|
Assert.IsTrue(str.StartsWithInvariant(beginning, ignoreCase: true));
|
|
}
|
|
|
|
[Test]
|
|
public void EndsWithInvariant_IsTheSameAs_EndsWith_WithInvariantCulture_DefaultingToCaseSensitive()
|
|
{
|
|
var str = "aBcD";
|
|
var ending = "cD";
|
|
Assert.IsTrue(str.EndsWithInvariant(ending));
|
|
|
|
ending = "CD";
|
|
Assert.IsFalse(str.EndsWithInvariant(ending));
|
|
Assert.IsTrue(str.EndsWithInvariant(ending, ignoreCase: true));
|
|
}
|
|
|
|
[Test]
|
|
public void ToIso8601Invariant_IsTheSameAs_ToString_O_WithInvariantCulture()
|
|
{
|
|
var date = DateTime.UtcNow;
|
|
var expected = date.ToString("O", CultureInfo.InvariantCulture);
|
|
var actual = date.ToIso8601Invariant();
|
|
Assert.AreEqual(expected, actual);
|
|
}
|
|
|
|
[Test]
|
|
[TestCase(true)]
|
|
[TestCase(false)]
|
|
public void IndexOfInvariant_IsTheSameAs_IndexOf_WithStringComparisonInvariantCulture(bool ignoreCase)
|
|
{
|
|
var comparison = ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture;
|
|
var str = "abcdefg";
|
|
var substring1 = "de";
|
|
var expected1 = str.IndexOf(substring1, comparison);
|
|
var actual1 = str.IndexOfInvariant(substring1, ignoreCase);
|
|
Assert.AreEqual(expected1, actual1);
|
|
|
|
var substring2 = "dE";
|
|
var expected2 = str.IndexOf(substring2, comparison);
|
|
var actual2 = str.IndexOfInvariant(substring2, ignoreCase);
|
|
Assert.AreEqual(expected2, actual2);
|
|
}
|
|
|
|
[Test]
|
|
[TestCase("")]
|
|
[TestCase(null)]
|
|
public void IfNotNullOrEmpty_ReturnsSpecifiedDefaultValue_WhenNullOrEmpty(string str)
|
|
{
|
|
int defaultValue = 42;
|
|
var actual = str.IfNotNullOrEmpty(defaultValue, int.Parse);
|
|
Assert.AreEqual(defaultValue, actual);
|
|
}
|
|
|
|
[Test]
|
|
[TestCase("")]
|
|
[TestCase(null)]
|
|
public void IfNotNullOrEmpty_ReturnsDefaultValue_WhenNullOrEmpty(string str)
|
|
{
|
|
var actual = str.IfNotNullOrEmpty(int.Parse);
|
|
Assert.AreEqual(default(int), actual);
|
|
}
|
|
|
|
[Test]
|
|
public void IfNotNullOrEmpty_ReturnsResultOfFunc_WhenNotEmpty()
|
|
{
|
|
var actual = "42".IfNotNullOrEmpty(int.Parse);
|
|
Assert.AreEqual(42, actual);
|
|
}
|
|
|
|
[Test]
|
|
public void IfNotNullOrEmpty_ReturnsResultOfFunc_WhenNotEmptyAndDefaultValueSpecified()
|
|
{
|
|
var defaultValue = -42;
|
|
var actual = "42".IfNotNullOrEmpty(defaultValue, int.Parse);
|
|
Assert.AreEqual(42, actual);
|
|
}
|
|
|
|
[Test]
|
|
[TestCase(null, 0, 9)]
|
|
[TestCase("Test Data", 0, 9)]
|
|
[TestCase("Test Data", 0, 5)]
|
|
[TestCase("Test Data", 5, 4)]
|
|
[TestCase("Test Data", 8, 0)]
|
|
public void SafeSubstring_ReturnsProperSubstring(string sourceString, int startIndex, int length)
|
|
{
|
|
Assert.AreEqual(sourceString?.Substring(startIndex, length), sourceString.SafeSubstring(startIndex, length));
|
|
}
|
|
|
|
[Test]
|
|
[TestCase(null, 0, 9, null)]
|
|
[TestCase("Test Data", 0, 15, "Test Data")]
|
|
[TestCase("Test Data", 5, 15, "Data")]
|
|
[TestCase("Test Data", 9, 15, "")]
|
|
public void SafeSubstring_ReturnsSubstring_WhenSubstringThrowException(string sourceString, int startIndex, int length, string expected)
|
|
{
|
|
if (sourceString != null)
|
|
{
|
|
Assert.Throws<ArgumentOutOfRangeException>(() =>
|
|
{
|
|
sourceString.Substring(startIndex, length);
|
|
});
|
|
}
|
|
Assert.AreEqual(expected, sourceString.SafeSubstring(startIndex, length));
|
|
}
|
|
|
|
[TestCase("test input")]
|
|
[TestCase("[ asdd[ \" 12344 :::}")]
|
|
public void EncodeDecode64String(string input)
|
|
{
|
|
var encoded = input.EncodeBase64();
|
|
var decoded = encoded.DecodeBase64();
|
|
|
|
Assert.AreEqual(input, decoded);
|
|
}
|
|
}
|
|
}
|