1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 
3 /**
4  * @copyright 2013 Couchbase, Inc.
5  *
6  * @author Filipe Manana  <filipe@couchbase.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9  * use this file except in compliance with the License. You may obtain a copy of
10  * the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17  * License for the specific language governing permissions and limitations under
18  * the License.
19  **/
20 
21 #include "src/views/mapreduce/mapreduce.h"
22 #include <string.h>
23 
24 
25 #define DOC_BODY "{" \
26     "  \"values\": [10, -7, 20, 1]," \
27     "  \"bin\": \"aGVsbG8gd29ybGQh\"," \
28     "  \"date\":\"+033658-09-27T01:46:40.000Z\"" \
29     "}"
30 
31 #if __STDC_VERSION__ >=199901L
32 #define ASSIGN(x) x =
33 #else
34 #define ASSIGN(x)
35 #endif
36 
37 static const mapreduce_json_t doc = {
38     ASSIGN(.json) DOC_BODY,
39     ASSIGN(.length) sizeof(DOC_BODY) - 1
40 };
41 static const mapreduce_json_t meta = {
42     ASSIGN(.json) "{\"id\":\"doc1\"}",
43     ASSIGN(.length) sizeof("{\"id\":\"doc1\"}") - 1
44 };
45 
test_sum_function(void)46 static void test_sum_function(void)
47 {
48     void *context = NULL;
49     char *error_msg = NULL;
50     mapreduce_error_t ret;
51     const char *functions[] = {
52         "function(doc, meta) { emit(meta.id, sum(doc.values)); }"
53     };
54     mapreduce_map_result_list_t *result = NULL;
55 
56     ret = mapreduce_start_map_context(functions, 1, &context, &error_msg);
57     cb_assert(ret == MAPREDUCE_SUCCESS);
58     cb_assert(error_msg == NULL);
59     cb_assert(context != NULL);
60 
61     ret = mapreduce_map(context, &doc, &meta, &result);
62     cb_assert(ret == MAPREDUCE_SUCCESS);
63     cb_assert(result != NULL);
64     cb_assert(result->length == 1);
65     cb_assert(result->list != NULL);
66 
67     cb_assert(result->list[0].error == MAPREDUCE_SUCCESS);
68     cb_assert(result->list[0].result.kvs.length == 1);
69     cb_assert(result->list[0].result.kvs.kvs[0].key.length == (sizeof("\"doc1\"") - 1));
70     cb_assert(memcmp(result->list[0].result.kvs.kvs[0].key.json,
71                   "\"doc1\"",
72                   (sizeof("\"doc1\"") - 1)) == 0);
73     cb_assert(result->list[0].result.kvs.kvs[0].value.length == (sizeof("24") - 1));
74     cb_assert(memcmp(result->list[0].result.kvs.kvs[0].value.json,
75                   "24",
76                   (sizeof("24") - 1)) == 0);
77 
78     mapreduce_free_map_result_list(result);
79     mapreduce_free_context(context);
80 }
81 
test_b64decode_function(void)82 static void test_b64decode_function(void)
83 {
84     void *context = NULL;
85     char *error_msg = NULL;
86     mapreduce_error_t ret;
87     const char *functions[] = {
88         "function(doc, meta) {"
89         "  emit(meta.id, String.fromCharCode.apply(this, decodeBase64(doc.bin)));"
90         "}"
91     };
92     mapreduce_map_result_list_t *result = NULL;
93 
94     ret = mapreduce_start_map_context(functions, 1, &context, &error_msg);
95     cb_assert(ret == MAPREDUCE_SUCCESS);
96     cb_assert(error_msg == NULL);
97     cb_assert(context != NULL);
98 
99     ret = mapreduce_map(context, &doc, &meta, &result);
100     cb_assert(ret == MAPREDUCE_SUCCESS);
101     cb_assert(result != NULL);
102     cb_assert(result->length == 1);
103     cb_assert(result->list != NULL);
104 
105     cb_assert(result->list[0].error == MAPREDUCE_SUCCESS);
106     cb_assert(result->list[0].result.kvs.length == 1);
107     cb_assert(result->list[0].result.kvs.kvs[0].key.length == (sizeof("\"doc1\"") - 1));
108     cb_assert(memcmp(result->list[0].result.kvs.kvs[0].key.json,
109                   "\"doc1\"",
110                   (sizeof("\"doc1\"") - 1)) == 0);
111     cb_assert(result->list[0].result.kvs.kvs[0].value.length == (sizeof("\"hello world!\"") - 1));
112     cb_assert(memcmp(result->list[0].result.kvs.kvs[0].value.json,
113                   "\"hello world!\"",
114                   (sizeof("\"hello world!\"") - 1)) == 0);
115 
116     mapreduce_free_map_result_list(result);
117     mapreduce_free_context(context);
118 }
119 
test_date_to_array_function(void)120 static void test_date_to_array_function(void)
121 {
122     void *context = NULL;
123     char *error_msg = NULL;
124     mapreduce_error_t ret;
125     const char *functions[] = {
126         "function(doc, meta) { emit(meta.id, dateToArray(doc.date)); }"
127     };
128     mapreduce_map_result_list_t *result = NULL;
129 
130     ret = mapreduce_start_map_context(functions, 1, &context, &error_msg);
131     cb_assert(ret == MAPREDUCE_SUCCESS);
132     cb_assert(error_msg == NULL);
133     cb_assert(context != NULL);
134 
135     ret = mapreduce_map(context, &doc, &meta, &result);
136     cb_assert(ret == MAPREDUCE_SUCCESS);
137     cb_assert(result != NULL);
138     cb_assert(result->length == 1);
139     cb_assert(result->list != NULL);
140 
141     cb_assert(result->list[0].error == MAPREDUCE_SUCCESS);
142     cb_assert(result->list[0].result.kvs.length == 1);
143     cb_assert(result->list[0].result.kvs.kvs[0].key.length == (sizeof("\"doc1\"") - 1));
144     cb_assert(memcmp(result->list[0].result.kvs.kvs[0].key.json,
145                   "\"doc1\"",
146                   (sizeof("\"doc1\"") - 1)) == 0);
147     cb_assert(result->list[0].result.kvs.kvs[0].value.length == (sizeof("[33658,9,27,1,46,40]") - 1));
148     cb_assert(memcmp(result->list[0].result.kvs.kvs[0].value.json,
149                   "[33658,9,27,1,46,40]",
150                   (sizeof("[33658,9,27,1,46,40]") - 1)) == 0);
151 
152     mapreduce_free_map_result_list(result);
153     mapreduce_free_context(context);
154 }
155 
main(void)156 int main(void)
157 {
158     fprintf(stderr, "Running mapreduce builtin tests\n");
159     mapreduce_init();
160 
161     test_sum_function();
162     test_b64decode_function();
163     test_date_to_array_function();
164 
165     mapreduce_deinit();
166     return 0;
167 }
168