master_lexer_token_unittest.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <exceptions/exceptions.h>
  15. #include <dns/master_lexer.h>
  16. #include <gtest/gtest.h>
  17. #include <string>
  18. using namespace isc::dns;
  19. namespace {
  20. const char TEST_STRING[] = "string token";
  21. // This excludes the ending \0 character
  22. const size_t TEST_STRING_LEN = sizeof(TEST_STRING) - 1;
  23. class MasterLexerTokenTest : public ::testing::Test {
  24. protected:
  25. MasterLexerTokenTest() :
  26. token_eof(MasterLexer::Token::END_OF_FILE),
  27. token_str(TEST_STRING, TEST_STRING_LEN),
  28. token_num(42),
  29. token_err(MasterLexer::Token::UNEXPECTED_END)
  30. {}
  31. const MasterLexer::Token token_eof; // an example of non-value type token
  32. const MasterLexer::Token token_str;
  33. const MasterLexer::Token token_num;
  34. const MasterLexer::Token token_err;
  35. };
  36. TEST_F(MasterLexerTokenTest, strings) {
  37. // basic construction and getter checks
  38. EXPECT_EQ(MasterLexer::Token::STRING, token_str.getType());
  39. EXPECT_EQ(std::string("string token"), token_str.getString());
  40. const MasterLexer::Token::StringRegion str_region =
  41. token_str.getStringRegion();
  42. EXPECT_EQ(TEST_STRING, str_region.beg);
  43. EXPECT_EQ(TEST_STRING_LEN, str_region.len);
  44. // Even if the stored string contains a nul character (in this case,
  45. // it happens to be at the end of the string, but could be in the middle),
  46. // getString() should return a string object containing the nul.
  47. std::string expected_str("string token");
  48. expected_str.push_back('\0');
  49. EXPECT_EQ(expected_str,
  50. MasterLexer::Token(TEST_STRING, TEST_STRING_LEN + 1).getString());
  51. // Construct type of qstring
  52. EXPECT_EQ(MasterLexer::Token::QSTRING,
  53. MasterLexer::Token(TEST_STRING, sizeof(TEST_STRING), true).
  54. getType());
  55. // if we explicitly set 'quoted' to false, it should be normal string
  56. EXPECT_EQ(MasterLexer::Token::STRING,
  57. MasterLexer::Token(TEST_STRING, sizeof(TEST_STRING), false).
  58. getType());
  59. // getString/StringRegion() aren't allowed for non string(-variant) types
  60. EXPECT_THROW(token_eof.getString(), isc::InvalidOperation);
  61. EXPECT_THROW(token_num.getString(), isc::InvalidOperation);
  62. EXPECT_THROW(token_eof.getStringRegion(), isc::InvalidOperation);
  63. EXPECT_THROW(token_num.getStringRegion(), isc::InvalidOperation);
  64. }
  65. TEST_F(MasterLexerTokenTest, numbers) {
  66. EXPECT_EQ(42, token_num.getNumber());
  67. EXPECT_EQ(MasterLexer::Token::NUMBER, token_num.getType());
  68. // It's copyable and assignable.
  69. MasterLexer::Token token(token_num);
  70. EXPECT_EQ(42, token.getNumber());
  71. EXPECT_EQ(MasterLexer::Token::NUMBER, token.getType());
  72. token = token_num;
  73. EXPECT_EQ(42, token.getNumber());
  74. EXPECT_EQ(MasterLexer::Token::NUMBER, token.getType());
  75. // it's okay to replace it with a different type of token
  76. token = token_eof;
  77. EXPECT_EQ(MasterLexer::Token::END_OF_FILE, token.getType());
  78. // Possible max value
  79. token = MasterLexer::Token(0xffffffff);
  80. EXPECT_EQ(4294967295u, token.getNumber());
  81. // getNumber() isn't allowed for non number types
  82. EXPECT_THROW(token_eof.getNumber(), isc::InvalidOperation);
  83. EXPECT_THROW(token_str.getNumber(), isc::InvalidOperation);
  84. }
  85. TEST_F(MasterLexerTokenTest, novalues) {
  86. // Just checking we can construct them and getType() returns correct value.
  87. EXPECT_EQ(MasterLexer::Token::END_OF_FILE, token_eof.getType());
  88. EXPECT_EQ(MasterLexer::Token::END_OF_LINE,
  89. MasterLexer::Token(MasterLexer::Token::END_OF_LINE).getType());
  90. EXPECT_EQ(MasterLexer::Token::INITIAL_WS,
  91. MasterLexer::Token(MasterLexer::Token::INITIAL_WS).getType());
  92. // Special types of tokens cannot have value-based types
  93. EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::STRING),
  94. isc::InvalidParameter);
  95. EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::QSTRING),
  96. isc::InvalidParameter);
  97. EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::NUMBER),
  98. isc::InvalidParameter);
  99. EXPECT_THROW(MasterLexer::Token t(MasterLexer::Token::ERROR),
  100. isc::InvalidParameter);
  101. }
  102. TEST_F(MasterLexerTokenTest, errors) {
  103. EXPECT_EQ(MasterLexer::Token::ERROR, token_err.getType());
  104. EXPECT_EQ(MasterLexer::Token::UNEXPECTED_END, token_err.getErrorCode());
  105. EXPECT_EQ("unexpected end of input", token_err.getErrorText());
  106. EXPECT_EQ("lexer not started",
  107. MasterLexer::Token(MasterLexer::Token::NOT_STARTED).
  108. getErrorText());
  109. EXPECT_EQ("unbalanced parentheses",
  110. MasterLexer::Token(MasterLexer::Token::UNBALANCED_PAREN).
  111. getErrorText());
  112. EXPECT_EQ("unbalanced quotes",
  113. MasterLexer::Token(MasterLexer::Token::UNBALANCED_QUOTES).
  114. getErrorText());
  115. // getErrorCode/Text() isn't allowed for non number types
  116. EXPECT_THROW(token_num.getErrorCode(), isc::InvalidOperation);
  117. EXPECT_THROW(token_num.getErrorText(), isc::InvalidOperation);
  118. // Only the pre-defined error code is accepted. Hardcoding '4' (max code
  119. // + 1) is intentional; it'd be actually better if we notice it when we
  120. // update the enum list (which shouldn't happen too often).
  121. EXPECT_THROW(MasterLexer::Token(MasterLexer::Token::ErrorCode(4)),
  122. isc::InvalidParameter);
  123. // Check the coexistence of "from number" and "from error-code"
  124. // constructors won't cause confusion.
  125. EXPECT_EQ(MasterLexer::Token::NUMBER,
  126. MasterLexer::Token(static_cast<uint32_t>(
  127. MasterLexer::Token::NOT_STARTED)).
  128. getType());
  129. }
  130. }