File: ondemand_twitter_tests.cpp

package info (click to toggle)
simdjson 4.3.1-4
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 31,396 kB
  • sloc: cpp: 195,760; ansic: 20,954; sh: 1,126; python: 885; makefile: 47; ruby: 25; javascript: 13
file content (197 lines) | stat: -rw-r--r-- 6,560 bytes parent folder | download | duplicates (7)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <set>
#include "simdjson.h"
#include "test_ondemand.h"

using namespace simdjson;

namespace twitter_tests {
  using namespace std;

  bool twitter_count() {
    TEST_START();
    padded_string json;
    ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
    ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
      uint64_t count;
      ASSERT_SUCCESS( doc_result["search_metadata"]["count"].get(count) );
      ASSERT_EQUAL( count, 100 );
      return true;
    }));
    TEST_SUCCEED();
  }
#if SIMDJSON_EXCEPTIONS
  bool twitter_example() {
    TEST_START();
    padded_string json;
    ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
    ondemand::parser parser;
    auto doc = parser.iterate(json);
    for (ondemand::object tweet : doc["statuses"]) {
      uint64_t         id            = tweet["id"];
      std::string_view text          = tweet["text"];
      std::string_view screen_name   = tweet["user"]["screen_name"];
      uint64_t         retweets      = tweet["retweet_count"];
      uint64_t         favorites     = tweet["favorite_count"];
      (void) id;
      (void) text;
      (void) retweets;
      (void) favorites;
      (void) screen_name;
    }
    TEST_SUCCEED();
  }
#endif // SIMDJSON_EXCEPTIONS

  bool twitter_default_profile() {
    TEST_START();
    padded_string json;
    ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
    ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
      // Print users with a default profile.
      set<string_view> default_users;
      for (auto tweet : doc_result["statuses"]) {
        auto user = tweet["user"].get_object();

        // We have to get the screen name before default_profile because it appears first
        std::string_view screen_name;
        ASSERT_SUCCESS( user["screen_name"].get(screen_name) );

        bool default_profile{};
        ASSERT_SUCCESS( user["default_profile"].get(default_profile) );
        if (default_profile) {
          default_users.insert(screen_name);
        }
      }
      ASSERT_EQUAL( default_users.size(), 86 );
      return true;
    }));
    TEST_SUCCEED();
  }

  bool twitter_image_sizes() {
    TEST_START();
    padded_string json;
    ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
    ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
      // Print image names and sizes
      set<pair<uint64_t, uint64_t>> image_sizes;
      for (auto tweet : doc_result["statuses"]) {
        auto media = tweet["entities"]["media"];
        if (!media.error()) {
          for (auto image : media) {
            uint64_t id_val;
            std::string_view id_string;
            ASSERT_SUCCESS( image["id"].get(id_val) );
            ASSERT_SUCCESS( image["id_str"].get(id_string) );
            std::cout << "id = " << id_val << std::endl;
            std::cout << "id_string = " << id_string << std::endl;

            for (auto size : image["sizes"].get_object()) {
              std::string_view size_key;
              ASSERT_SUCCESS( size.unescaped_key().get(size_key) );
              std::cout << "Type of image size = " << size_key << std::endl;

              uint64_t width, height;
              ASSERT_SUCCESS( size.value()["w"].get(width) );
              ASSERT_SUCCESS( size.value()["h"].get(height) );
              image_sizes.insert(make_pair(width, height));
            }
          }
        }
      }
      ASSERT_EQUAL( image_sizes.size(), 15 );
      return true;
    }));
    TEST_SUCCEED();
  }

#if SIMDJSON_EXCEPTIONS

  bool twitter_count_exception() {
    TEST_START();
    padded_string json;
    ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
    ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
      uint64_t count = doc_result["search_metadata"]["count"];
      ASSERT_EQUAL( count, 100 );
      return true;
    }));
    TEST_SUCCEED();
  }

  bool twitter_default_profile_exception() {
    TEST_START();
    padded_string json = padded_string::load(TWITTER_JSON);
    ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
      // Print users with a default profile.
      set<string_view> default_users;
      for (auto tweet : doc_result["statuses"]) {
        ondemand::object user = tweet["user"];

        // We have to get the screen name before default_profile because it appears first
        std::string_view screen_name = user["screen_name"];
        if (user["default_profile"]) {
          default_users.insert(screen_name);
        }
      }
      ASSERT_EQUAL( default_users.size(), 86 );
      return true;
    }));
    TEST_SUCCEED();
  }

  /*
   * Fun fact: id and id_str can differ:
   * 505866668485386240 and 505866668485386241.
   * Presumably, it is because doubles are used
   * at some point in the process and the number
   * 505866668485386241 cannot be represented as a double.
   * (not our fault)
   */
  bool twitter_image_sizes_exception() {
    TEST_START();
    padded_string json = padded_string::load(TWITTER_JSON);
    ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
      // Print image names and sizes
      set<pair<uint64_t, uint64_t>> image_sizes;
      for (auto tweet : doc_result["statuses"]) {
        auto media = tweet["entities"]["media"];
        if (!media.error()) {
          for (auto image : media) {
            std::cout << "id = " << uint64_t(image["id"]) << std::endl;
            std::cout << "id_string = " << std::string_view(image["id_str"]) << std::endl;
            for (auto size : image["sizes"].get_object()) {
              std::cout << "Type of image size = " << std::string_view(size.unescaped_key()) << std::endl;
              // NOTE: the uint64_t is required so that each value is actually parsed before the pair is created
              image_sizes.insert(make_pair<uint64_t,uint64_t>(size.value()["w"], size.value()["h"]));
            }
          }
        }
      }
      ASSERT_EQUAL( image_sizes.size(), 15 );
      return true;
    }));
    TEST_SUCCEED();
  }

#endif // SIMDJSON_EXCEPTIONS

  bool run() {
    return
           twitter_count() &&
           twitter_default_profile() &&
           twitter_image_sizes() &&
#if SIMDJSON_EXCEPTIONS
           twitter_count_exception() &&
           twitter_example() &&
           twitter_default_profile_exception() &&
           twitter_image_sizes_exception() &&
#endif // SIMDJSON_EXCEPTIONS
           true;
  }

} // namespace twitter_tests

int main(int argc, char *argv[]) {
  return test_main(argc, argv, twitter_tests::run);
}