@ -29,6 +29,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
# include <google/protobuf/io/zero_copy_stream_impl_lite.h>
# include <google/protobuf/testing/googletest.h>
# include <gtest/gtest.h>
@ -242,6 +243,107 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
}
# endif // PROTOBUF_HAS_DEATH_TEST
class TestLineCollector : public LineConsumer {
public :
TestLineCollector ( std : : vector < std : : string > * inout_lines ,
const std : : string * reject_line = nullptr )
: lines_ ( inout_lines ) , reject_ ( reject_line ) { }
bool ConsumeLine ( const StringPiece & line , std : : string * out_error ) override {
if ( reject_ ) {
if ( * reject_ = = line ) {
* out_error = std : : string ( " Rejected ' " ) + * reject_ + " ' " ;
return false ;
}
}
if ( lines_ ) {
lines_ - > emplace_back ( line ) ;
}
return true ;
}
private :
std : : vector < std : : string > * lines_ ;
const std : : string * reject_ ;
} ;
const int kBlockSizes [ ] = { - 1 , 1 , 2 , 5 , 64 } ;
const int kBlockSizeCount = GOOGLE_ARRAYSIZE ( kBlockSizes ) ;
TEST ( ObjCHelper , ParseSimple_BasicsSuccess ) {
const std : : vector < std : : pair < std : : string , std : : vector < std : : string > > > tests = {
{ " " , { } } ,
{ " a " , { " a " } } ,
{ " a c " , { " a c " } } ,
{ " a c " , { " a c " } } ,
{ " \t a c " , { " a c " } } ,
{ " abc \n " , { " abc " } } ,
{ " abc \n d f " , { " abc " , " d f " } } ,
{ " \n abc \n def \n \n " , { " abc " , " def " } } ,
} ;
for ( const auto & test : tests ) {
for ( int i = 0 ; i < kBlockSizeCount ; i + + ) {
io : : ArrayInputStream input ( test . first . data ( ) , test . first . size ( ) , kBlockSizes [ i ] ) ;
std : : string err_str ;
std : : vector < std : : string > lines ;
TestLineCollector collector ( & lines ) ;
EXPECT_TRUE ( ParseSimpleStream ( input , " dummy " , & collector , & err_str ) ) ;
EXPECT_EQ ( lines , test . second ) ;
EXPECT_TRUE ( err_str . empty ( ) ) ;
}
}
}
TEST ( ObjCHelper , ParseSimple_DropsComments ) {
const std : : vector < std : : pair < std : : string , std : : vector < std : : string > > > tests = {
{ " # nothing " , { } } ,
{ " # " , { } } ,
{ " ## " , { } } ,
{ " \n # nothing \n " , { } } ,
{ " a # same line " , { " a " } } ,
{ " a # same line \n " , { " a " } } ,
{ " a \n # line \n c " , { " a " , " c " } } ,
{ " # n o t # h i n g # " , { } } ,
{ " ## n o # t h i n g # " , { } } ,
{ " a# n o t # h i n g # " , { " a " } } ,
{ " a \n ## n o # t h i n g # " , { " a " } } ,
} ;
for ( const auto & test : tests ) {
for ( int i = 0 ; i < kBlockSizeCount ; i + + ) {
io : : ArrayInputStream input ( test . first . data ( ) , test . first . size ( ) , kBlockSizes [ i ] ) ;
std : : string err_str ;
std : : vector < std : : string > lines ;
TestLineCollector collector ( & lines ) ;
EXPECT_TRUE ( ParseSimpleStream ( input , " dummy " , & collector , & err_str ) ) ;
EXPECT_EQ ( lines , test . second ) ;
EXPECT_TRUE ( err_str . empty ( ) ) ;
}
}
}
TEST ( ObjCHelper , ParseSimple_RejectLines ) {
const std : : vector < std : : tuple < std : : string , std : : string , int > > tests = {
{ " a \n b \n c " , " a " , 1 } ,
{ " a \n b \n c " , " b " , 2 } ,
{ " a \n b \n c " , " c " , 3 } ,
{ " a \n b \n c \n " , " c " , 3 } ,
} ;
for ( const auto & test : tests ) {
for ( int i = 0 ; i < kBlockSizeCount ; i + + ) {
io : : ArrayInputStream input ( std : : get < 0 > ( test ) . data ( ) , std : : get < 0 > ( test ) . size ( ) ,
kBlockSizes [ i ] ) ;
std : : string err_str ;
TestLineCollector collector ( nullptr , & std : : get < 1 > ( test ) ) ;
EXPECT_FALSE ( ParseSimpleStream ( input , " dummy " , & collector , & err_str ) ) ;
std : : string expected_err = StrCat ( " error: dummy Line " , std : : get < 2 > ( test ) , " , Rejected ' " , std : : get < 1 > ( test ) , " ' " ) ;
EXPECT_EQ ( err_str , expected_err ) ;
}
}
}
// TODO(thomasvl): Should probably add some unittests for all the special cases
// of name mangling (class name, field name, enum names). Rather than doing
// this with an ObjC test in the objectivec directory, we should be able to