blob: bd5939e4c396218305db1e79d58fdc3bde8311df [file]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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
//
// https://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.IO;
using org.apache.plc4net.tools.codegen;
using Xunit;
namespace org.apache.plc4net.test.codegen
{
/// <summary>
/// Verifies that the pure-.NET mspec parser can parse the Modbus protocol
/// description, which is the simplest of the 24 protocol descriptions and
/// therefore the first target for the generator pipeline.
/// </summary>
public class MspecParserTests
{
private static string? GetModbusMspecPath()
{
// The mspec file lives in the repo root under protocols/modbus/...
// FindRepoRoot walks up from the test output directory; null means
// the tests are not running inside a checkout.
var repoRoot = RepoPaths.FindRepoRoot();
if (repoRoot == null) return null;
return Path.Combine(repoRoot,
"protocols", "modbus", "src", "main", "resources",
"protocols", "modbus", "modbus.mspec");
}
[Fact]
public void Modbus_mspec_parses_without_errors()
{
var path = GetModbusMspecPath();
if (path == null)
{
// Fail loud rather than passing vacuously outside the repo layout.
Assert.Fail("repo root not found; real-protocol coverage would be vacuous");
}
// Deliberately no File.Exists guard here: inside a checkout the
// file must exist, and a missing one is a real error worth failing
// on, not a reason to pass vacuously.
var tree = MspecReader.ReadFile(path);
Assert.NotNull(tree);
}
[Fact]
public void A_minimal_mspec_parses()
{
var mspec = @"
[type Byte
[simple uint 8 value]
]
";
var tree = MspecReader.Read(mspec);
Assert.NotNull(tree);
}
[Fact]
public void Malformed_mspec_throws()
{
var ex = Assert.Throws<MspecParseException>(
() => MspecReader.Read("[type Broken <<<"));
Assert.Contains("Failed to parse", ex.Message);
}
[Fact]
public void A_lexer_error_is_reported_by_strict_parsing()
{
var ex = Assert.Throws<MspecParseException>(
() => MspecReader.Read("[type Packet [simple uint 8 value] @]"));
Assert.Contains("token recognition error", ex.Message);
}
}
}