File: try_parse_integer_test.cpp

package info (click to toggle)
cataclysm-dda 0.H-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 710,808 kB
  • sloc: cpp: 524,019; python: 11,580; sh: 1,228; makefile: 1,169; xml: 507; javascript: 150; sql: 56; exp: 41; perl: 37
file content (142 lines) | stat: -rw-r--r-- 4,856 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "cata_catch.h"
#include "cata_scope_helpers.h"
#include "try_parse_integer.h"

template<typename TestType>
void try_parse_int_simple_parsing()
{
    CAPTURE( demangle( typeid( TestType ).name() ) );
    std::locale const &oldloc = std::locale();
    on_out_of_scope reset_loc( [&oldloc]() {
        std::locale::global( oldloc );
    } );
    try {
        std::locale::global( std::locale( "en_US.UTF-8" ) );
    } catch( std::runtime_error & ) {
        // On platforms where we can't set the locale, the test should still
        // pass
    }
    CAPTURE( setlocale( LC_ALL, nullptr ) );
    CAPTURE( std::locale().name() );

    bool use_locale = GENERATE( false, true );
    CAPTURE( use_locale );

    SECTION( "successes" ) {
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "1234", use_locale );
            CAPTURE( result.str() );
            CHECK( result.success() );
            CHECK( result.value() == 1234 );
        }
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "-1234", use_locale );
            CAPTURE( result.str() );
            CHECK( result.success() );
            CHECK( result.value() == -1234 );
        }
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "+1234", use_locale );
            CAPTURE( result.str() );
            CHECK( result.success() );
            CHECK( result.value() == +1234 );
        }
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "  1234", use_locale );
            CAPTURE( result.str() );
            CHECK( result.success() );
            CHECK( result.value() == 1234 );
        }
    }

    SECTION( "errors" ) {
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "", use_locale );
            CHECK( !result.success() );
            CHECK( result.str() == "Could not convert '' to an integer" );
        }
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "a", use_locale );
            CHECK( !result.success() );
            CHECK( result.str() == "Could not convert 'a' to an integer" );
        }
        {
            // Verify that we detect overflow
            ret_val<TestType> result =
                try_parse_integer<TestType>( "999999999999999999999", use_locale );
            CHECK( !result.success() );
            CHECK( result.str() == "Could not convert '999999999999999999999' to an integer" );
        }
    }
}

TEST_CASE( "try_parse_int_simple_parsing", "[try_parse_integer]" )
{
    try_parse_int_simple_parsing<int>();
    try_parse_int_simple_parsing<long>();
    try_parse_int_simple_parsing<long long>();
}

template<typename TestType>
void try_parse_int_locale_parsing()
{
    CAPTURE( demangle( typeid( TestType ).name() ) );
    std::locale const &oldloc = std::locale();
    on_out_of_scope reset_loc( [&oldloc]() {
        std::locale::global( oldloc );
    } );
    SECTION( "de_DE" ) {
        try {
            std::locale::global( std::locale( "de_DE.UTF-8" ) );
        } catch( std::runtime_error &e ) {
            WARN( "couldn't set locale for try_parse_integer test: " << e.what() );
            return;
        }
        CAPTURE( setlocale( LC_ALL, nullptr ) );
        CAPTURE( std::locale().name() );
        // Disabling on Apple; seems like their C library doesn't do localized integer
        // parsing.
#ifndef __APPLE__
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "1.234", true );
            CHECK( result.success() );
            CHECK( result.value() == 1234 );
        }
#endif
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "1.234", false );
            CHECK( !result.success() );
            CHECK( result.str() == "Stray characters after integer in '1.234'" );
        }
    }

    SECTION( "en_US" ) {
        try {
            std::locale::global( std::locale( "en_US.UTF-8" ) );
        } catch( std::runtime_error &e ) {
            WARN( "couldn't set locale for try_parse_integer test: " << e.what() );
            return;
        }
        CAPTURE( setlocale( LC_ALL, nullptr ) );
        CAPTURE( std::locale().name() );
#ifndef __APPLE__
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "1,234", true );
            CHECK( result.success() );
            CHECK( result.value() == 1234 );
        }
#endif
        {
            ret_val<TestType> result = try_parse_integer<TestType>( "1,234", false );
            CHECK( !result.success() );
            CHECK( result.str() == "Stray characters after integer in '1,234'" );
        }
    }
}

TEST_CASE( "try_parse_int_locale_parsing", "[try_parse_integer]" )
{
    try_parse_int_locale_parsing<int>();
    try_parse_int_locale_parsing<long>();
    try_parse_int_locale_parsing<long long>();
}