Skip to content

Commit

Permalink
Automatic merge of X1.3.1-194-g1e6e4b5f4 and 9 pull requests
Browse files Browse the repository at this point in the history
- Pull request #40 at e81861b: Monogame upgrade
- Pull request #79 at 7d9f14b: Update version calculation for new unstable versions
- Pull request #216 at 927a49c: Upgrade and replace web server with EmbedIO
- Pull request #226 at 2ba1d2c: EmbedIO web server graphical track monitor
- Pull request #227 at 6ec1539: EmbedIO web server graphical train driving monitor
- Pull request #228 at 72c0146: adds links to OR on Elvas Tower
- Pull request #232 at 377e893: JSON consist format: https://blueprints.launchpad.net/or/+spec/consist-editor
- Pull request #233 at 4084c75: Remove startup exception in the launcher by refactoring a try-catch
- Pull request #234 at e3c545c: Rehabilitate unit testing suite, migrate to xUnit 2
  • Loading branch information
openrails-bot committed Jul 22, 2020
11 parents ee8de79 + 1e6e4b5 + e81861b + 7d9f14b + 927a49c + 2ba1d2c + 6ec1539 + 72c0146 + 377e893 + 4084c75 + e3c545c commit 63d9c32
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 52 deletions.
Binary file removed Source/3rdPartyLibs/xunit.dll
Binary file not shown.
27 changes: 15 additions & 12 deletions Source/Orts.Parsers.Msts/STFReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ namespace Orts.Parsers.Msts
// (constant or block) will not be processed.
//
// NB!!! If a comment/skip/#*/_* is the last {item} in a block, rather than being totally consumed a dummy
// "#\u00b6" is returned, so if EndOFBlock() returns false, you always get an {item} (which can then just be
// ignored).
// {STFReader.EndBlockCommentSentinel}, is returned, so if EndOFBlock() returns false, you always get an
// {item} (which can then just be ignored).
//
// Here are two examples which use different techniques to read the same STF file:
// Example 1:
Expand Down Expand Up @@ -163,6 +163,11 @@ namespace Orts.Parsers.Msts
/// </exception>
public class STFReader : IDisposable
{
/// <summary>
/// Returned in lieu of an item for a comment that is the last item in a block.
/// </summary>
public const string EndBlockCommentSentinel = "#\u00b6";

/// <summary>Open a file, reader the header line, and prepare for STF parsing
/// </summary>
/// <param name="filename">Filename of the STF file to be opened and parsed.</param>
Expand Down Expand Up @@ -235,7 +240,7 @@ protected virtual void Dispose(bool disposing)

/// <summary>Property that returns true when the EOF has been reached
/// </summary>
public bool Eof { get { return PeekChar() == -1; } }
public bool Eof { get { return PeekPastWhitespace() == -1; } }
/// <summary>Filename property for the file being parsed - for reporting purposes
/// </summary>
public string FileName { get; private set; }
Expand Down Expand Up @@ -272,7 +277,7 @@ public string Tree
/// <summary>Returns the next whitespace delimited {item} from the STF file skipping comments, etc.
/// </summary>
/// <remarks>
/// <alert class="important">If a comment/skip/#*/_* ignore block is the last {item} in a block, rather than being totally consumed a dummy '#' is returned, so if EndOFBlock() returns false, you always get an {item} (which can then just be ignored).</alert>
/// <alert class="important">If a comment/skip/#*/_* ignore block is the last {item} in a block, rather than being totally consumed a dummy <see cref="EndBlockCommentSentinel"/> is returned, so if EndOFBlock() returns false, you always get an {item} (which can then just be ignored).</alert>
/// </remarks>
/// <returns>The next {item} from the STF file, any surrounding quotations will be not be returned.</returns>
public string ReadItem()
Expand All @@ -283,7 +288,7 @@ public string ReadItem()
/// <summary>This is an internal function in STFReader, it returns the next whitespace delimited {item} from the STF file.
/// </summary>
/// <remarks>
/// <alert class="important">If a comment/skip/#*/_* ignore block is the last {item} in a block, rather than being totally consumed a dummy '#' is returned, so if EndOFBlock() returns false, you always get an {item} (which can then just be ignored).</alert>
/// <alert class="important">If a comment/skip/#*/_* ignore block is the last {item} in a block, rather than being totally consumed a dummy <see cref="EndBlockCommentSentinel"/> is returned, so if EndOFBlock() returns false, you always get an {item} (which can then just be ignored).</alert>
/// </remarks>
/// <param name="string_mode">When true normal comment processing is disabled.</param>
/// <returns>The next {item} from the STF file, any surrounding quotations will be not be returned.</returns>
Expand Down Expand Up @@ -529,6 +534,8 @@ public uint ReadHex(uint? defaultValue)
return defaultValue.Value;
}

if (item.Length == 0)
return 0x0;
uint val;
if (uint.TryParse(item, parseHex, parseNFI, out val)) return val;
STFException.TraceWarning(this, "Cannot parse the constant hex string " + item);
Expand Down Expand Up @@ -1148,7 +1155,7 @@ public string ReadStringBlock(string defaultValue)
return (defaultValue != null) ? defaultValue : "";
}
SkipRestOfBlock(); // <CJComment> This call seems poor practice as it discards any tokens _including mistakes_ up to the matching ")". </CJComment>
if (result == "#\u00b6")
if (result == EndBlockCommentSentinel)
{
STFException.TraceWarning(this, "Found a comment when an {constant item} was expected.");
return (defaultValue != null) ? defaultValue : result;
Expand Down Expand Up @@ -1679,9 +1686,7 @@ private string ReadItem(bool skip_mode, bool string_mode)
//this correctly when using 'tree'
int c2 = PeekPastWhitespace();
if (c2 == ')')
{
return "#\u00b6";
}
return EndBlockCommentSentinel;
string item = ReadItem(skip_mode, string_mode);
return item; // Now move on to the next token after the commented area
}
Expand Down Expand Up @@ -1797,9 +1802,7 @@ private string ReadItem(bool skip_mode, bool string_mode)
//this correctly when using 'tree'
int c2 = PeekPastWhitespace();
if (c2 == ')')
{
return "#\u00b6";
}
return EndBlockCommentSentinel;
string item = ReadItem(skip_mode, string_mode);
return item; // Now move on to the next token after the commented area
}
Expand Down
4 changes: 2 additions & 2 deletions Source/Tests/AssertWarnings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static void Expected()
/// </summary>
/// <param name="pattern">Pattern to match the warning against; if there is no match, the test fails.</param>
/// <param name="code">Code which is expected to generate a matching warning.</param>
public static void Matching(string pattern, Assert.ThrowsDelegate code)
public static void Matching(string pattern, Action code)
{
Initialize();
Listener.InternalMatching(pattern, code);
Expand All @@ -92,7 +92,7 @@ void Set(bool expected)
LastWarning = null;
}

void InternalMatching(string pattern, Assert.ThrowsDelegate callback)
void InternalMatching(string pattern, Action callback)
{
Set(true);
LastWarning = null;
Expand Down
2 changes: 1 addition & 1 deletion Source/Tests/Orts.Common/Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public static void FormattedStrings()
Assert.Equal(inhgResult, FormatStrings.FormatPressure(KPa.ToKgfpCm2(KPa.FromInHg(1.2f)), PressureUnit.KgfpCm2, PressureUnit.InHg, true));
Assert.Equal(inhgResult, FormatStrings.FormatPressure(KPa.ToPSI(KPa.FromInHg(1.2f)), PressureUnit.PSI, PressureUnit.InHg, true));

var kgfResult = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:F1} kgf/cm^2", 1.2f);
var kgfResult = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:F1} kgf/cm²", 1.2f);
Assert.Equal(kgfResult, FormatStrings.FormatPressure(KPa.FromKgfpCm2(1.2f), PressureUnit.KPa, PressureUnit.KgfpCm2, true));
Assert.Equal(kgfResult, FormatStrings.FormatPressure(KPa.ToBar(KPa.FromKgfpCm2(1.2f)), PressureUnit.Bar, PressureUnit.KgfpCm2, true));
Assert.Equal(kgfResult, FormatStrings.FormatPressure(KPa.ToInHg(KPa.FromKgfpCm2(1.2f)), PressureUnit.InHg, PressureUnit.KgfpCm2, true));
Expand Down
65 changes: 31 additions & 34 deletions Source/Tests/Orts.Parsers.Msts/StfReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static void EmptyFile()
Assert.True(reader.EndOfBlock(), "STFReader.EndOfBlock()");
Assert.Equal("EmptyFile.stf", reader.FileName);
Assert.Equal(1, reader.LineNumber);
Assert.Equal(null, reader.SimisSignature);
Assert.Null(reader.SimisSignature);
// Note, the Debug.Assert() in reader.Tree is already captured by AssertWarnings.Expected.
// For the rest, we do not care which exception is being thrown.
var exception = Record.Exception(() => reader.Tree);
Expand All @@ -87,7 +87,7 @@ public static void EmptyFile()
reader.ParseBlock(new STFReader.TokenProcessor[0]);
reader.ParseFile(new STFReader.TokenProcessor[0]);
Assert.Equal(-1, reader.PeekPastWhitespace());
Assert.Equal(false, reader.ReadBoolBlock(false));
Assert.False(reader.ReadBoolBlock(false));
Assert.Equal(0, reader.ReadDouble(null));
Assert.Equal(0, reader.ReadDoubleBlock(null));
Assert.Equal(0, reader.ReadFloat(STFReader.UNITS.None, null));
Expand All @@ -98,7 +98,7 @@ public static void EmptyFile()
Assert.Equal(0, reader.ReadIntBlock(null));
Assert.Equal("", reader.ReadItem());
Assert.Equal("", reader.ReadString());
Assert.Equal(null, reader.ReadStringBlock(null));
Assert.Null(reader.ReadStringBlock(null));
Assert.Equal(0U, reader.ReadUInt(null));
Assert.Equal(0U, reader.ReadUIntBlock(null));
Assert.Equal(Vector3.Zero, reader.ReadVector3Block(STFReader.UNITS.None, Vector3.Zero));
Expand Down Expand Up @@ -131,7 +131,7 @@ public static void EmptyBlock()
Assert.False(reader.EndOfBlock(), "STFReader.EndOfBlock()");
Assert.Equal("EmptyBlock.stf", reader.FileName);
Assert.Equal(1, reader.LineNumber);
Assert.Equal(null, reader.SimisSignature);
Assert.Null(reader.SimisSignature);
Assert.Throws<STFException>(() => reader.MustMatch("Something Else"));
// We can't rewind the STFReader and it has advanced forward now. :(
}
Expand Down Expand Up @@ -224,8 +224,8 @@ public static void BlockNumericFormats()
{
using (var reader = new STFReader(new MemoryStream(Encoding.Unicode.GetBytes("(true ignored) (false ignored) (1.123456789 ignored) (1e9 ignored) (1.1e9 ignored) (2.123456 ignored) (2e9 ignored) (2.1e9 ignored) (00ABCDEF ignored) (123456 ignored) (-123456 ignored) (234567 ignored)")), "", Encoding.Unicode, false))
{
Assert.Equal(true, reader.ReadBoolBlock(false));
Assert.Equal(false, reader.ReadBoolBlock(true));
Assert.True(reader.ReadBoolBlock(false));
Assert.False(reader.ReadBoolBlock(true));
Assert.Equal(1.123456789, reader.ReadDoubleBlock(null));
Assert.Equal(1e9, reader.ReadDoubleBlock(null));
Assert.Equal(1.1e9, reader.ReadDoubleBlock(null));
Expand Down Expand Up @@ -697,7 +697,8 @@ static void ParenthicalCommentSingle(string inputString)
reader.SkipRestOfBlock();
Assert.Equal("wagon(lights()", reader.Tree.ToLower());

reader.ReadItem();
if (reader.ReadItem() == STFReader.EndBlockCommentSentinel)
reader.ReadItem();
reader.ReadItem();
Assert.Equal("wagon(sound", reader.Tree.ToLower());
Assert.Equal("test.sms", reader.ReadStringBlock(""));
Expand All @@ -723,7 +724,7 @@ public class Should
public static void BeConstructableFromStfReader()
{
var reader = Tests.Orts.Parsers.Msts.StfReader.Create.Reader("sometoken");
Assert.DoesNotThrow(() => new STFException(reader, "some message"));
new STFException(reader, "some message");
}

#if NEW_READER
Expand Down Expand Up @@ -817,7 +818,7 @@ public static void OnStreamConstructorHasNullSimisSignature()
AssertWarnings.NotExpected();
string firstToken = "firsttoken";
var reader = Create.Reader(firstToken);
Assert.Equal(null, reader.SimisSignature);
Assert.Null(reader.SimisSignature);
}

#if NEW_READER
Expand Down Expand Up @@ -1059,12 +1060,14 @@ public static void AtEOFKeepReturningEmptyString()
public static void StoreSourceLineNumberOfLastReadToken()
{
//AssertWarnings.Activate();
List<TokenTester> tokenTesters = new List<TokenTester>();
//tokenTesters.Add(new TokenTester("a b", new int[] { 1, 1 }));
tokenTesters.Add(new TokenTester("a\nb", new int[] { 1, 2 }));
//tokenTesters.Add(new TokenTester("a\nb\nc", new int[] { 1, 2, 3 }));
//tokenTesters.Add(new TokenTester("a b\n\nc", new int[] { 1, 1, 3 }));
//tokenTesters.Add(new TokenTester("a(b(\nc)\nc)", new int[] { 1, 1, 1, 1, 2, 2, 3, 3 }));
var tokenTesters = new TokenTester[]
{
new TokenTester("a b", new int[] { 1, 1 }),
new TokenTester("a \nb", new int[] { 1, 2 }),
new TokenTester("a \nb \nc", new int[] { 1, 2, 3 }),
new TokenTester("a b \n\nc", new int[] { 1, 1, 3 }),
new TokenTester("a(b(\nc)\nc)", new int[] { 1, 1, 1, 1, 2, 2, 3, 3 })
};

foreach (var tokenTester in tokenTesters)
{
Expand Down Expand Up @@ -1455,16 +1458,12 @@ public static void SkipBlockOnCommentOtherCase()
}

[Fact]
public static void WarnOnMissingBlockAfterComment()
public static void DontWarnOnMissingBlockAfterComment()
{
// todo: old stf reader would simply return 'b'. Throwing an exception is perhaps harsh
AssertWarnings.NotExpected();
string someFollowingToken = "b";
AssertStfException.Throws(() =>
{
var reader = Create.Reader("comment a " + someFollowingToken);
Assert.Equal(someFollowingToken, reader.ReadItem());
}, "expected.*open");
STFReader reader = Create.Reader("comment a " + someFollowingToken);
Assert.Equal(someFollowingToken, reader.ReadItem());
}

[Fact]
Expand All @@ -1486,16 +1485,12 @@ public static void SkipBlockOnSkipOtherCase()
}

[Fact]
public static void WarnOnMissingBlockAfterSkip()
public static void DontWarnOnMissingBlockAfterSkip()
{
// todo: old stf reader would simply return 'b'. Throwing an exception is perhaps harsh
AssertWarnings.NotExpected();
string someFollowingToken = "b";
AssertStfException.Throws(() =>
{
var reader = Create.Reader("skip a " + someFollowingToken);
Assert.Equal(someFollowingToken, reader.ReadItem());
}, "expected.*open");
STFReader reader = Create.Reader("skip a " + someFollowingToken);
Assert.Equal(someFollowingToken, reader.ReadItem());
}

[Fact]
Expand Down Expand Up @@ -1927,17 +1922,16 @@ public static void ReturnValue()
}

[Fact]
public static void SkipValueStartingWithUnderscore()
public static void DontSkipValueStartingWithUnderscore()
{
AssertWarnings.NotExpected();
string underscoreToken = "_underscore";
string toBeSkippedToken = "tobeskippedtoken";
string followingToken = "followingtoken";
string inputString = underscoreToken + " " + toBeSkippedToken + " " + followingToken;
var reader = Create.Reader(inputString);
// todo spec change?: old STF reader would return _underscore and tobeskippedtoken"
//Assert.Equal(underscoreToken, reader.ReadString());
//Assert.Equal(toBeSkippedToken, reader.ReadString());
Assert.Equal(underscoreToken, reader.ReadString());
Assert.Equal(toBeSkippedToken, reader.ReadString());
Assert.Equal(followingToken, reader.ReadString());

}
Expand Down Expand Up @@ -2060,6 +2054,7 @@ public static void OnBlockEndReturnDefaultOrWarn()
(SOMEDEFAULT, SOMEDEFAULT, (reader, x) => reader.ReadIntBlock(x));
}

[Fact]
public static void ReturnValueInBlock()
{
StfTokenReaderCommon.ReturnValueInBlock<int>(SOMEDEFAULTS, reader => reader.ReadIntBlock(null));
Expand Down Expand Up @@ -2423,6 +2418,7 @@ public static void OnBlockEndReturnDefaultOrWarn()
(SOMEDEFAULT, SOMEDEFAULT, (reader, x) => reader.ReadDoubleBlock(x));
}

[Fact]
public static void ReturnValueInBlock()
{
StfTokenReaderCommon.ReturnValueInBlock<double>(SOMEDEFAULTS, reader => reader.ReadDoubleBlock(null));
Expand Down Expand Up @@ -2505,6 +2501,7 @@ public static void OnBlockEndReturnDefaultOrWarn()
(SOMEDEFAULT, SOMEDEFAULT, (reader, x) => reader.ReadFloatBlock(STFReader.UNITS.None, x));
}

[Fact]
public static void ReturnValueInBlock()
{
StfTokenReaderCommon.ReturnValueInBlock<float>
Expand Down Expand Up @@ -2850,7 +2847,7 @@ static class AssertStfException
/// </summary>
/// <param name="testCode">Code that will be executed</param>
/// <param name="pattern">The pattern that the exception message should match</param>
public static void Throws(Assert.ThrowsDelegate testCode, string pattern)
public static void Throws(Action testCode, string pattern)
{
var exception = Record.Exception(testCode);
Assert.NotNull(exception);
Expand Down
12 changes: 9 additions & 3 deletions Source/Tests/Orts.Parsers.OR/TimetableReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,24 @@ public static void DetectSeparator()
using (var file = new TestFile(";"))
{
var tr = new TimetableReader(file.FileName);
Assert.Equal(1, tr.Strings.Count);
Assert.Single(tr.Strings);
Assert.Equal(2, tr.Strings[0].Length);
}
using (var file = new TestFile(","))
{
var tr = new TimetableReader(file.FileName);
Assert.Equal(1, tr.Strings.Count);
Assert.Single(tr.Strings);
Assert.Equal(2, tr.Strings[0].Length);
}
using (var file = new TestFile("\t"))
{
Assert.Throws(typeof(InvalidDataException), () => {
var tr = new TimetableReader(file.FileName);
Assert.Single(tr.Strings);
Assert.Equal(2, tr.Strings[0].Length);
}
using (var file = new TestFile(":"))
{
Assert.Throws<InvalidDataException>(() => {
var tr = new TimetableReader(file.FileName);
});
}
Expand Down

0 comments on commit 63d9c32

Please sign in to comment.