Home | History | Annotate | Download | only in objectivec
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2014 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
     32 #include <google/protobuf/testing/googletest.h>
     33 #include <gtest/gtest.h>
     34 
     35 namespace google {
     36 namespace protobuf {
     37 namespace compiler {
     38 namespace objectivec {
     39 namespace {
     40 
     41 TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
     42   string input_for_decode("abcdefghIJ");
     43   string desired_output_for_decode;
     44   string expected;
     45   string result;
     46 
     47   // Different data, can't transform.
     48 
     49   desired_output_for_decode = "zbcdefghIJ";
     50   expected = string("\0zbcdefghIJ\0", 12);
     51   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     52                                                      desired_output_for_decode);
     53   EXPECT_EQ(expected, result);
     54 
     55   desired_output_for_decode = "abcdezghIJ";
     56   expected = string("\0abcdezghIJ\0", 12);
     57   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     58                                                      desired_output_for_decode);
     59   EXPECT_EQ(expected, result);
     60 
     61   // Shortened data, can't transform.
     62 
     63   desired_output_for_decode = "abcdefghI";
     64   expected = string("\0abcdefghI\0", 11);
     65   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     66                                                      desired_output_for_decode);
     67   EXPECT_EQ(expected, result);
     68 
     69   // Extra data, can't transform.
     70 
     71   desired_output_for_decode = "abcdefghIJz";
     72   expected = string("\0abcdefghIJz\0", 13);
     73   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     74                                                      desired_output_for_decode);
     75   EXPECT_EQ(expected, result);
     76 }
     77 
     78 TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
     79   string input_for_decode("abcdefghIJ");
     80   string desired_output_for_decode;
     81   string expected;
     82   string result;
     83 
     84   desired_output_for_decode = "abcdefghIJ";
     85   expected = string("\x0A\x0", 2);
     86   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     87                                                      desired_output_for_decode);
     88   EXPECT_EQ(expected, result);
     89 
     90   desired_output_for_decode = "_AbcdefghIJ";
     91   expected = string("\xCA\x0", 2);
     92   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     93                                                      desired_output_for_decode);
     94   EXPECT_EQ(expected, result);
     95 
     96   desired_output_for_decode = "ABCD__EfghI_j";
     97   expected = string("\x64\x80\xC5\xA1\x0", 5);
     98   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
     99                                                      desired_output_for_decode);
    100   EXPECT_EQ(expected, result);
    101 
    102   // Long name so multiple decode ops are needed.
    103 
    104   input_for_decode =
    105       "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000";
    106   desired_output_for_decode =
    107       "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000";
    108   expected = string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
    109   result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
    110                                                      desired_output_for_decode);
    111   EXPECT_EQ(expected, result);
    112 }
    113 
    114 // Death tests do not work on Windows as of yet.
    115 #ifdef PROTOBUF_HAS_DEATH_TEST
    116 TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) {
    117   // Empty inputs.
    118 
    119   EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", ""),
    120               ::testing::KilledBySignal(SIGABRT),
    121               "error: got empty string for making TextFormat data, input:");
    122   EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("a", ""),
    123               ::testing::KilledBySignal(SIGABRT),
    124               "error: got empty string for making TextFormat data, input:");
    125   EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", "a"),
    126               ::testing::KilledBySignal(SIGABRT),
    127               "error: got empty string for making TextFormat data, input:");
    128 
    129   // Null char in the string.
    130 
    131   string str_with_null_char("ab\0c", 4);
    132   EXPECT_EXIT(
    133       TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"),
    134       ::testing::KilledBySignal(SIGABRT),
    135       "error: got a null char in a string for making TextFormat data, input:");
    136   EXPECT_EXIT(
    137       TextFormatDecodeData::DecodeDataForString("def", str_with_null_char),
    138       ::testing::KilledBySignal(SIGABRT),
    139       "error: got a null char in a string for making TextFormat data, input:");
    140 }
    141 #endif  // PROTOBUF_HAS_DEATH_TEST
    142 
    143 TEST(ObjCHelper, TextFormatDecodeData_RawStrings) {
    144   TextFormatDecodeData decode_data;
    145 
    146   // Different data, can't transform.
    147   decode_data.AddString(1, "abcdefghIJ", "zbcdefghIJ");
    148   decode_data.AddString(3, "abcdefghIJ", "abcdezghIJ");
    149   // Shortened data, can't transform.
    150   decode_data.AddString(2, "abcdefghIJ", "abcdefghI");
    151   // Extra data, can't transform.
    152   decode_data.AddString(4, "abcdefghIJ", "abcdefghIJz");
    153 
    154   EXPECT_EQ(4, decode_data.num_entries());
    155 
    156   uint8 expected_data[] = {
    157       0x4,
    158       0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0,
    159       0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0,
    160       0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0,
    161       0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0,
    162   };
    163   string expected((const char*)expected_data, sizeof(expected_data));
    164 
    165   EXPECT_EQ(expected, decode_data.Data());
    166 }
    167 
    168 TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) {
    169   TextFormatDecodeData decode_data;
    170 
    171   decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
    172   decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
    173   decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
    174   decode_data.AddString(4, "abcdefghIJ", "ABCD__EfghI_j");
    175   decode_data.AddString(1000,
    176                         "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000",
    177                         "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000");
    178 
    179   EXPECT_EQ(5, decode_data.num_entries());
    180 
    181   uint8 expected_data[] = {
    182       0x5,
    183       // All as is (00 op)
    184       0x1,  0x0A, 0x0,
    185       // Underscore, upper + 9 (10 op)
    186       0x3,  0xCA, 0x0,
    187       //  Upper + 3 (10 op), underscore, upper + 5 (10 op)
    188       0x2,  0x44, 0xC6, 0x0,
    189       // All Upper for 4 (11 op), underscore, underscore, upper + 5 (10 op),
    190       // underscore, lower + 0 (01 op)
    191       0x4,  0x64, 0x80, 0xC5, 0xA1, 0x0,
    192       // 2 byte key: as is + 3 (00 op), underscore, lower + 4 (01 op),
    193       //   underscore, lower + 3 (01 op), underscore, lower + 1 (01 op),
    194       //   underscore, lower + 30 (01 op), as is + 30 (00 op), as is + 13 (00
    195       //   op),
    196       //   underscore, as is + 3 (00 op)
    197       0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0,
    198   };
    199   string expected((const char*)expected_data, sizeof(expected_data));
    200 
    201   EXPECT_EQ(expected, decode_data.Data());
    202 }
    203 
    204 
    205 // Death tests do not work on Windows as of yet.
    206 #ifdef PROTOBUF_HAS_DEATH_TEST
    207 TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
    208   TextFormatDecodeData decode_data;
    209 
    210   // Empty inputs.
    211 
    212   EXPECT_EXIT(decode_data.AddString(1, "", ""),
    213               ::testing::KilledBySignal(SIGABRT),
    214               "error: got empty string for making TextFormat data, input:");
    215   EXPECT_EXIT(decode_data.AddString(1, "a", ""),
    216               ::testing::KilledBySignal(SIGABRT),
    217               "error: got empty string for making TextFormat data, input:");
    218   EXPECT_EXIT(decode_data.AddString(1, "", "a"),
    219               ::testing::KilledBySignal(SIGABRT),
    220               "error: got empty string for making TextFormat data, input:");
    221 
    222   // Null char in the string.
    223 
    224   string str_with_null_char("ab\0c", 4);
    225   EXPECT_EXIT(
    226       decode_data.AddString(1, str_with_null_char, "def"),
    227       ::testing::KilledBySignal(SIGABRT),
    228       "error: got a null char in a string for making TextFormat data, input:");
    229   EXPECT_EXIT(
    230       decode_data.AddString(1, "def", str_with_null_char),
    231       ::testing::KilledBySignal(SIGABRT),
    232       "error: got a null char in a string for making TextFormat data, input:");
    233 
    234   // Duplicate keys
    235 
    236   decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
    237   decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
    238   decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
    239   EXPECT_EXIT(decode_data.AddString(2, "xyz", "x_yz"),
    240               ::testing::KilledBySignal(SIGABRT),
    241               "error: duplicate key \\(2\\) making TextFormat data, input:");
    242 }
    243 #endif  // PROTOBUF_HAS_DEATH_TEST
    244 
    245 // TODO(thomasvl): Should probably add some unittests for all the special cases
    246 // of name mangling (class name, field name, enum names).  Rather than doing
    247 // this with an ObjC test in the objectivec directory, we should be able to
    248 // use src/google/protobuf/compiler/importer* (like other tests) to support a
    249 // virtual file system to feed in protos, once we have the Descriptor tree, the
    250 // tests could use the helper methods for generating names and validate the
    251 // right things are happening.
    252 
    253 }  // namespace
    254 }  // namespace objectivec
    255 }  // namespace compiler
    256 }  // namespace protobuf
    257 }  // namespace google
    258