Files
allwpilib/wpiutil/src/test/native/cpp/struct/SchemaParserTest.cpp

219 lines
6.2 KiB
C++
Raw Normal View History

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
2025-11-07 19:56:21 -05:00
#include "wpi/util/struct/SchemaParser.hpp" // NOLINT(build/include_order)
#include <gtest/gtest.h>
2025-11-07 20:00:05 -05:00
using namespace wpi::util::structparser;
TEST(StructParserTest, Empty) {
Parser p{""};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_TRUE(schema.declarations.empty());
}
TEST(StructParserTest, EmptySemicolon) {
Parser p{";"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_TRUE(schema.declarations.empty());
}
TEST(StructParserTest, Simple) {
Parser p{"int32 a"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
EXPECT_EQ(decl.arraySize, 1u);
}
TEST(StructParserTest, SimpleTrailingSemi) {
Parser p{"int32 a;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
}
TEST(StructParserTest, Array) {
Parser p{"int32 a[2]"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
EXPECT_EQ(decl.arraySize, 2u);
}
TEST(StructParserTest, ArrayTrailingSemi) {
Parser p{"int32 a[2];"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
}
TEST(StructParserTest, Bitfield) {
Parser p{"int32 a:2"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
EXPECT_EQ(decl.bitWidth, 2u);
}
TEST(StructParserTest, BitfieldTrailingSemi) {
Parser p{"int32 a:2;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
}
TEST(StructParserTest, EnumKeyword) {
Parser p{"enum {x=1} int32 a;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
ASSERT_EQ(decl.enumValues.size(), 1u);
EXPECT_EQ(decl.enumValues[0].first, "x");
EXPECT_EQ(decl.enumValues[0].second, 1);
}
TEST(StructParserTest, EnumNoKeyword) {
Parser p{"{x=1} int32 a;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
ASSERT_EQ(decl.enumValues.size(), 1u);
EXPECT_EQ(decl.enumValues[0].first, "x");
EXPECT_EQ(decl.enumValues[0].second, 1);
}
TEST(StructParserTest, EnumNoValues) {
Parser p{"{} int32 a;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
ASSERT_TRUE(decl.enumValues.empty());
}
TEST(StructParserTest, EnumMultipleValues) {
Parser p{"{x=1,y=-2} int32 a;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
ASSERT_EQ(decl.enumValues.size(), 2u);
EXPECT_EQ(decl.enumValues[0].first, "x");
EXPECT_EQ(decl.enumValues[0].second, 1);
EXPECT_EQ(decl.enumValues[1].first, "y");
EXPECT_EQ(decl.enumValues[1].second, -2);
}
TEST(StructParserTest, EnumTrailingComma) {
Parser p{"{x=1,y=2,} int32 a;"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 1u);
auto& decl = schema.declarations[0];
EXPECT_EQ(decl.typeString, "int32");
EXPECT_EQ(decl.name, "a");
ASSERT_EQ(decl.enumValues.size(), 2u);
EXPECT_EQ(decl.enumValues[0].first, "x");
EXPECT_EQ(decl.enumValues[0].second, 1);
EXPECT_EQ(decl.enumValues[1].first, "y");
EXPECT_EQ(decl.enumValues[1].second, 2);
}
TEST(StructParserTest, MultipleNoTrailingSemi) {
Parser p{"int32 a; int16 b"};
ParsedSchema schema;
ASSERT_TRUE(p.Parse(&schema));
ASSERT_EQ(schema.declarations.size(), 2u);
EXPECT_EQ(schema.declarations[0].typeString, "int32");
EXPECT_EQ(schema.declarations[0].name, "a");
EXPECT_EQ(schema.declarations[1].typeString, "int16");
EXPECT_EQ(schema.declarations[1].name, "b");
}
TEST(StructParserTest, ErrBitfieldArray) {
Parser p{"int32 a[1]:2"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "10: expected ';', got ':'");
}
TEST(StructParserTest, ErrNoArrayValue) {
Parser p{"int32 a[]"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "8: expected integer, got ']'");
}
TEST(StructParserTest, ErrNoBitfieldValue) {
Parser p{"int32 a:"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "8: expected integer, got ''");
}
TEST(StructParserTest, ErrNoNameArray) {
Parser p{"int32 [2]"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "6: expected identifier, got '['");
}
TEST(StructParserTest, ErrNoNameBitField) {
Parser p{"int32 :2"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "6: expected identifier, got ':'");
}
TEST(StructParserTest, NegativeBitField) {
Parser p{"int32 a:-1"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "8: bitfield width '-1' is not a positive integer");
}
TEST(StructParserTest, NegativeArraySize) {
Parser p{"int32 a[-1]"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "8: array size '-1' is not a positive integer");
}
TEST(StructParserTest, ZeroBitField) {
Parser p{"int32 a:0"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "8: bitfield width '0' is not a positive integer");
}
TEST(StructParserTest, ZeroArraySize) {
Parser p{"int32 a[0]"};
ParsedSchema schema;
ASSERT_FALSE(p.Parse(&schema));
ASSERT_EQ(p.GetError(), "8: array size '0' is not a positive integer");
}