Merge lp:~marcustomlinson/v8-cpp/test-coverage into lp:v8-cpp
- test-coverage
- Merge into trunk
Proposed by
Marcus Tomlinson
Status: | Merged |
---|---|
Merged at revision: | 13 |
Proposed branch: | lp:~marcustomlinson/v8-cpp/test-coverage |
Merge into: | lp:v8-cpp |
Diff against target: |
1067 lines (+772/-31) 26 files modified
CMakeLists.txt (+34/-3) cmake/EnableCoverageReport.cmake (+166/-0) cmake/FindLcov.cmake (+29/-0) cmake/Findgcovr.cmake (+31/-0) cmake/ParseArguments.cmake (+52/-0) src/class.h (+2/-8) src/internal/require.h (+11/-12) src/run.h (+10/-1) tests/CMakeLists.txt (+2/-0) tests/errors/CMakeLists.txt (+49/-0) tests/errors/fail-module.cpp (+1/-0) tests/errors/module.cpp (+27/-0) tests/errors/scripts/fail.js (+1/-0) tests/errors/test.cpp (+183/-0) tests/errors/test.h (+25/-0) tests/methods/CMakeLists.txt (+2/-2) tests/methods/module.cpp (+2/-0) tests/methods/test.cpp (+9/-0) tests/methods/test.h (+14/-3) tests/objects/CMakeLists.txt (+2/-2) tests/run/CMakeLists.txt (+37/-0) tests/run/module.cpp (+26/-0) tests/run/scripts/test.js (+3/-0) tests/run/scripts/test2.js (+7/-0) tests/run/test.cpp (+27/-0) tests/run/test.h (+20/-0) |
To merge this branch: | bzr merge lp:~marcustomlinson/v8-cpp/test-coverage |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marcus Tomlinson | Pending | ||
Review via email: mp+264025@code.launchpad.net |
Commit message
Added coverage report and more tests to achieve better coverage.
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2015-07-02 11:46:38 +0000 |
3 | +++ CMakeLists.txt 2015-07-07 10:47:30 +0000 |
4 | @@ -1,6 +1,6 @@ |
5 | cmake_minimum_required(VERSION 2.8) |
6 | |
7 | -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
8 | +# Configure project environment |
9 | |
10 | project(v8-cpp CXX) |
11 | |
12 | @@ -13,6 +13,24 @@ |
13 | -fPIC |
14 | ) |
15 | |
16 | +# Configure CMake environment |
17 | + |
18 | +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
19 | + |
20 | +string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) # Build types should always be lowercase but sometimes they are not. |
21 | + |
22 | +if(cmake_build_type_lower MATCHES coverage) |
23 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -g") |
24 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -g") |
25 | + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --coverage -g") |
26 | + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage -g") |
27 | + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage -g") |
28 | +endif() |
29 | + |
30 | +include(EnableCoverageReport) |
31 | + |
32 | +# Add includes |
33 | + |
34 | include_directories( |
35 | ${CMAKE_CURRENT_SOURCE_DIR}/src |
36 | ${CMAKE_CURRENT_SOURCE_DIR}/deps/v8/include |
37 | @@ -21,9 +39,22 @@ |
38 | ${CMAKE_CURRENT_SOURCE_DIR}/deps/v8/out/native/obj.target/tools/gyp |
39 | ) |
40 | |
41 | +# Add sources |
42 | + |
43 | +enable_testing() |
44 | + |
45 | add_subdirectory(example) |
46 | add_subdirectory(src) |
47 | +add_subdirectory(tests) |
48 | add_subdirectory(v8runner) |
49 | |
50 | -enable_testing() |
51 | -add_subdirectory(tests) |
52 | +# Enable coverage report |
53 | + |
54 | +if (cmake_build_type_lower MATCHES coverage) |
55 | + ENABLE_COVERAGE_REPORT(TARGETS v8-cpp |
56 | + FILTER /usr/include |
57 | + ${CMAKE_CURRENT_SOURCE_DIR}/deps/* |
58 | + ${CMAKE_CURRENT_SOURCE_DIR}/example/* |
59 | + ${CMAKE_CURRENT_SOURCE_DIR}/tests/* |
60 | + ${CMAKE_BINARY_DIR}/*) |
61 | +endif() |
62 | |
63 | === added file 'cmake/EnableCoverageReport.cmake' |
64 | --- cmake/EnableCoverageReport.cmake 1970-01-01 00:00:00 +0000 |
65 | +++ cmake/EnableCoverageReport.cmake 2015-07-07 10:47:30 +0000 |
66 | @@ -0,0 +1,166 @@ |
67 | +# - Creates a special coverage build type and target on GCC. |
68 | +# |
69 | +# Defines a function ENABLE_COVERAGE_REPORT which generates the coverage target |
70 | +# for selected targets. Optional arguments to this function are used to filter |
71 | +# unwanted results using globbing expressions. Moreover targets with tests for |
72 | +# the source code can be specified to trigger regenerating the report if the |
73 | +# test has changed |
74 | +# |
75 | +# ENABLE_COVERAGE_REPORT(TARGETS target... [FILTER filter...] [TESTS test targets...]) |
76 | +# |
77 | +# To generate a coverage report first build the project with |
78 | +# CMAKE_BUILD_TYPE=coverage, then call make test and afterwards make coverage. |
79 | +# |
80 | +# The coverage report is based on gcov. Depending on the availability of lcov |
81 | +# a HTML report will be generated and/or an XML report of gcovr is found. |
82 | +# The generated coverage target executes all found solutions. Special targets |
83 | +# exist to create e.g. only the xml report: coverage-xml. |
84 | +# |
85 | +# Copyright (C) 2010 by Johannes Wienke <jwienke at techfak dot uni-bielefeld dot de> |
86 | +# |
87 | +# This program is free software; you can redistribute it |
88 | +# and/or modify it under the terms of the GNU General |
89 | +# Public License as published by the Free Software Foundation; |
90 | +# either version 2, or (at your option) |
91 | +# any later version. |
92 | +# |
93 | +# This program is distributed in the hope that it will be useful, |
94 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
95 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
96 | +# GNU General Public License for more details. |
97 | +# |
98 | + |
99 | +INCLUDE(ParseArguments) |
100 | + |
101 | +FIND_PACKAGE(Lcov) |
102 | +FIND_PACKAGE(gcovr) |
103 | + |
104 | +FUNCTION(ENABLE_COVERAGE_REPORT) |
105 | + |
106 | + # argument parsing |
107 | + PARSE_ARGUMENTS(ARG "FILTER;TARGETS;TESTS" "" ${ARGN}) |
108 | + |
109 | + SET(COVERAGE_RAW_FILE "${CMAKE_BINARY_DIR}/coverage.raw.info") |
110 | + SET(COVERAGE_FILTERED_FILE "${CMAKE_BINARY_DIR}/coverage.info") |
111 | + SET(COVERAGE_REPORT_DIR "${CMAKE_BINARY_DIR}/coveragereport") |
112 | + SET(COVERAGE_XML_FILE "${CMAKE_BINARY_DIR}/coverage.xml") |
113 | + SET(COVERAGE_XML_COMMAND_FILE "${CMAKE_BINARY_DIR}/coverage-xml.cmake") |
114 | + |
115 | + # decide if there is any tool to create coverage data |
116 | + SET(TOOL_FOUND FALSE) |
117 | + IF(LCOV_FOUND OR GCOVR_FOUND) |
118 | + SET(TOOL_FOUND TRUE) |
119 | + ENDIF() |
120 | + IF(NOT TOOL_FOUND) |
121 | + MESSAGE(STATUS "Cannot enable coverage targets because neither lcov nor gcovr are found.") |
122 | + ENDIF() |
123 | + |
124 | + STRING(TOLOWER "${CMAKE_BUILD_TYPE}" COVERAGE_BUILD_TYPE) |
125 | + IF(CMAKE_COMPILER_IS_GNUCXX AND TOOL_FOUND AND "${COVERAGE_BUILD_TYPE}" MATCHES "coverage") |
126 | + |
127 | + MESSAGE(STATUS "Coverage support enabled for targets: ${ARG_TARGETS}") |
128 | + |
129 | + # create coverage build type |
130 | + SET(CMAKE_CXX_FLAGS_COVERAGE ${CMAKE_CXX_FLAGS_DEBUG} PARENT_SCOPE) |
131 | + SET(CMAKE_C_FLAGS_COVERAGE ${CMAKE_C_FLAGS_DEBUG} PARENT_SCOPE) |
132 | + SET(CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES} coverage PARENT_SCOPE) |
133 | + |
134 | + # instrument targets |
135 | + SET_TARGET_PROPERTIES(${ARG_TARGETS} PROPERTIES COMPILE_FLAGS --coverage |
136 | + LINK_FLAGS --coverage) |
137 | + |
138 | + # html report |
139 | + IF (LCOV_FOUND) |
140 | + |
141 | + MESSAGE(STATUS "Enabling HTML coverage report") |
142 | + |
143 | + # set up coverage target |
144 | + |
145 | + ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_RAW_FILE} |
146 | + COMMAND ${LCOV_EXECUTABLE} -c -d ${CMAKE_BINARY_DIR} -o ${COVERAGE_RAW_FILE} |
147 | + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} |
148 | + COMMENT "Collecting coverage data" |
149 | + DEPENDS ${ARG_TARGETS} ${ARG_TESTS} |
150 | + VERBATIM) |
151 | + |
152 | + # filter unwanted stuff |
153 | + LIST(LENGTH ARG_FILTER FILTER_LENGTH) |
154 | + IF(${FILTER_LENGTH} GREATER 0) |
155 | + SET(FILTER COMMAND ${LCOV_EXECUTABLE}) |
156 | + FOREACH(F ${ARG_FILTER}) |
157 | + SET(FILTER ${FILTER} -r ${COVERAGE_FILTERED_FILE} ${F}) |
158 | + ENDFOREACH() |
159 | + SET(FILTER ${FILTER} -o ${COVERAGE_FILTERED_FILE}) |
160 | + ELSE() |
161 | + SET(FILTER "") |
162 | + ENDIF() |
163 | + |
164 | + ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_FILTERED_FILE} |
165 | + COMMAND ${LCOV_EXECUTABLE} -e ${COVERAGE_RAW_FILE} "${CMAKE_SOURCE_DIR}*" -o ${COVERAGE_FILTERED_FILE} |
166 | + ${FILTER} |
167 | + DEPENDS ${COVERAGE_RAW_FILE} |
168 | + COMMENT "Filtering recorded coverage data for project-relevant entries" |
169 | + VERBATIM) |
170 | + ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_REPORT_DIR} |
171 | + COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_REPORT_DIR} |
172 | + COMMAND ${GENHTML_EXECUTABLE} --legend --show-details -t "${PROJECT_NAME} test coverage" -o ${COVERAGE_REPORT_DIR} ${COVERAGE_FILTERED_FILE} |
173 | + DEPENDS ${COVERAGE_FILTERED_FILE} |
174 | + COMMENT "Generating HTML coverage report in ${COVERAGE_REPORT_DIR}" |
175 | + VERBATIM) |
176 | + |
177 | + ADD_CUSTOM_TARGET(coverage-html |
178 | + DEPENDS ${COVERAGE_REPORT_DIR}) |
179 | + |
180 | + ENDIF() |
181 | + |
182 | + # xml coverage report |
183 | + IF(GCOVR_FOUND) |
184 | + |
185 | + MESSAGE(STATUS "Enabling XML coverage report") |
186 | + |
187 | + # filter unwanted stuff |
188 | + SET(GCOV_FILTER "") |
189 | + LIST(LENGTH ARG_FILTER FILTER_LENGTH) |
190 | + IF(${FILTER_LENGTH} GREATER 0) |
191 | + FOREACH(F ${ARG_FILTER}) |
192 | + SET(GCOV_FILTER "${GCOV_FILTER} -e \"${F}\"") |
193 | + ENDFOREACH() |
194 | + ENDIF() |
195 | + |
196 | + # gcovr cannot write directly to a file so the execution needs to |
197 | + # be wrapped in a cmake file that generates the file output |
198 | + FILE(WRITE ${COVERAGE_XML_COMMAND_FILE} |
199 | + "SET(ENV{LANG} en)\n") |
200 | + FILE(APPEND ${COVERAGE_XML_COMMAND_FILE} |
201 | + "EXECUTE_PROCESS(COMMAND \"${GCOVR_EXECUTABLE}\" -x -r \"${CMAKE_SOURCE_DIR}\" ${GCOV_FILTER} OUTPUT_FILE \"${COVERAGE_XML_FILE}\" WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")\n") |
202 | + |
203 | + ADD_CUSTOM_COMMAND(OUTPUT ${COVERAGE_XML_FILE} |
204 | + COMMAND ${CMAKE_COMMAND} ARGS -P ${COVERAGE_XML_COMMAND_FILE} |
205 | + COMMENT "Generating coverage XML report" |
206 | + VERBATIM) |
207 | + |
208 | + ADD_CUSTOM_TARGET(coverage-xml |
209 | + DEPENDS ${COVERAGE_XML_FILE}) |
210 | + |
211 | + ENDIF() |
212 | + |
213 | + # provide a global coverage target executing both steps if available |
214 | + SET(GLOBAL_DEPENDS "") |
215 | + IF(LCOV_FOUND) |
216 | + LIST(APPEND GLOBAL_DEPENDS ${COVERAGE_REPORT_DIR}) |
217 | + ENDIF() |
218 | + IF(GCOVR_FOUND) |
219 | + LIST(APPEND GLOBAL_DEPENDS ${COVERAGE_XML_FILE}) |
220 | + ENDIF() |
221 | + IF(LCOV_FOUND OR GCOVR_FOUND) |
222 | + ADD_CUSTOM_TARGET(coverage |
223 | + DEPENDS ${GLOBAL_DEPENDS}) |
224 | + ENDIF() |
225 | + |
226 | + ENDIF() |
227 | + |
228 | + # This gets rid of any stale .gcda files. Run this if a running a binary causes lots of messages about |
229 | + # about a "merge mismatch for summaries". |
230 | + ADD_CUSTOM_TARGET(clean-coverage COMMAND find ${CMAKE_BINARY_DIR} -name '*.gcda' | xargs rm -f) |
231 | + |
232 | +ENDFUNCTION() |
233 | |
234 | === added file 'cmake/FindLcov.cmake' |
235 | --- cmake/FindLcov.cmake 1970-01-01 00:00:00 +0000 |
236 | +++ cmake/FindLcov.cmake 2015-07-07 10:47:30 +0000 |
237 | @@ -0,0 +1,29 @@ |
238 | +# - Find lcov |
239 | +# Will define: |
240 | +# |
241 | +# LCOV_EXECUTABLE - the lcov binary |
242 | +# GENHTML_EXECUTABLE - the genhtml executable |
243 | +# |
244 | +# Copyright (C) 2010 by Johannes Wienke <jwienke at techfak dot uni-bielefeld dot de> |
245 | +# |
246 | +# This program is free software; you can redistribute it |
247 | +# and/or modify it under the terms of the GNU General |
248 | +# Public License as published by the Free Software Foundation; |
249 | +# either version 2, or (at your option) |
250 | +# any later version. |
251 | +# |
252 | +# This program is distributed in the hope that it will be useful, |
253 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
254 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
255 | +# GNU General Public License for more details. |
256 | +# |
257 | + |
258 | +INCLUDE(FindPackageHandleStandardArgs) |
259 | + |
260 | +FIND_PROGRAM(LCOV_EXECUTABLE lcov) |
261 | +FIND_PROGRAM(GENHTML_EXECUTABLE genhtml) |
262 | + |
263 | +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lcov DEFAULT_MSG LCOV_EXECUTABLE GENHTML_EXECUTABLE) |
264 | + |
265 | +# only visible in advanced view |
266 | +MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE) |
267 | |
268 | === added file 'cmake/Findgcovr.cmake' |
269 | --- cmake/Findgcovr.cmake 1970-01-01 00:00:00 +0000 |
270 | +++ cmake/Findgcovr.cmake 2015-07-07 10:47:30 +0000 |
271 | @@ -0,0 +1,31 @@ |
272 | +# - Find gcovr scrip |
273 | +# Will define: |
274 | +# |
275 | +# GCOVR_EXECUTABLE - the gcovr script |
276 | +# |
277 | +# Uses: |
278 | +# |
279 | +# GCOVR_ROOT - root to search for the script |
280 | +# |
281 | +# Copyright (C) 2011 by Johannes Wienke <jwienke at techfak dot uni-bielefeld dot de> |
282 | +# |
283 | +# This program is free software; you can redistribute it |
284 | +# and/or modify it under the terms of the GNU General |
285 | +# Public License as published by the Free Software Foundation; |
286 | +# either version 2, or (at your option) |
287 | +# any later version. |
288 | +# |
289 | +# This program is distributed in the hope that it will be useful, |
290 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
291 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
292 | +# GNU General Public License for more details. |
293 | +# |
294 | + |
295 | +INCLUDE(FindPackageHandleStandardArgs) |
296 | + |
297 | +FIND_PROGRAM(GCOVR_EXECUTABLE gcovr HINTS ${GCOVR_ROOT} "${GCOVR_ROOT}/bin") |
298 | + |
299 | +FIND_PACKAGE_HANDLE_STANDARD_ARGS(gcovr DEFAULT_MSG GCOVR_EXECUTABLE) |
300 | + |
301 | +# only visible in advanced view |
302 | +MARK_AS_ADVANCED(GCOVR_EXECUTABLE) |
303 | |
304 | === added file 'cmake/ParseArguments.cmake' |
305 | --- cmake/ParseArguments.cmake 1970-01-01 00:00:00 +0000 |
306 | +++ cmake/ParseArguments.cmake 2015-07-07 10:47:30 +0000 |
307 | @@ -0,0 +1,52 @@ |
308 | +# Parse arguments passed to a function into several lists separated by |
309 | +# upper-case identifiers and options that do not have an associated list e.g.: |
310 | +# |
311 | +# SET(arguments |
312 | +# hello OPTION3 world |
313 | +# LIST3 foo bar |
314 | +# OPTION2 |
315 | +# LIST1 fuz baz |
316 | +# ) |
317 | +# PARSE_ARGUMENTS(ARG "LIST1;LIST2;LIST3" "OPTION1;OPTION2;OPTION3" ${arguments}) |
318 | +# |
319 | +# results in 7 distinct variables: |
320 | +# * ARG_DEFAULT_ARGS: hello;world |
321 | +# * ARG_LIST1: fuz;baz |
322 | +# * ARG_LIST2: |
323 | +# * ARG_LIST3: foo;bar |
324 | +# * ARG_OPTION1: FALSE |
325 | +# * ARG_OPTION2: TRUE |
326 | +# * ARG_OPTION3: TRUE |
327 | +# |
328 | +# taken from http://www.cmake.org/Wiki/CMakeMacroParseArguments |
329 | + |
330 | +MACRO(PARSE_ARGUMENTS prefix arg_names option_names) |
331 | + SET(DEFAULT_ARGS) |
332 | + FOREACH(arg_name ${arg_names}) |
333 | + SET(${prefix}_${arg_name}) |
334 | + ENDFOREACH(arg_name) |
335 | + FOREACH(option ${option_names}) |
336 | + SET(${prefix}_${option} FALSE) |
337 | + ENDFOREACH(option) |
338 | + |
339 | + SET(current_arg_name DEFAULT_ARGS) |
340 | + SET(current_arg_list) |
341 | + FOREACH(arg ${ARGN}) |
342 | + SET(larg_names ${arg_names}) |
343 | + LIST(FIND larg_names "${arg}" is_arg_name) |
344 | + IF (is_arg_name GREATER -1) |
345 | + SET(${prefix}_${current_arg_name} ${current_arg_list}) |
346 | + SET(current_arg_name ${arg}) |
347 | + SET(current_arg_list) |
348 | + ELSE (is_arg_name GREATER -1) |
349 | + SET(loption_names ${option_names}) |
350 | + LIST(FIND loption_names "${arg}" is_option) |
351 | + IF (is_option GREATER -1) |
352 | + SET(${prefix}_${arg} TRUE) |
353 | + ELSE (is_option GREATER -1) |
354 | + SET(current_arg_list ${current_arg_list} ${arg}) |
355 | + ENDIF (is_option GREATER -1) |
356 | + ENDIF (is_arg_name GREATER -1) |
357 | + ENDFOREACH(arg) |
358 | + SET(${prefix}_${current_arg_name} ${current_arg_list}) |
359 | +ENDMACRO(PARSE_ARGUMENTS) |
360 | |
361 | === modified file 'src/class.h' |
362 | --- src/class.h 2015-06-11 05:51:30 +0000 |
363 | +++ src/class.h 2015-07-07 10:47:30 +0000 |
364 | @@ -72,22 +72,16 @@ |
365 | |
366 | // Add class member |
367 | template <typename P> |
368 | - Class& add_member(char const* name, P property, bool readonly = false) |
369 | + Class& add_member(char const* name, P property) |
370 | { |
371 | v8::HandleScope scope(class_.isolate()); |
372 | |
373 | v8::AccessorGetterCallback getter = &internal::Class<T>::template get_member<P>; |
374 | v8::AccessorSetterCallback setter = &internal::Class<T>::template set_member<P>; |
375 | - if (readonly) |
376 | - { |
377 | - setter = nullptr; |
378 | - } |
379 | - |
380 | v8::Handle<v8::Value> data = internal::export_value(class_.isolate(), property); |
381 | - v8::PropertyAttribute prop_attrs = v8::PropertyAttribute(v8::DontDelete | (setter ? 0 : v8::ReadOnly)); |
382 | |
383 | class_.class_template()->PrototypeTemplate()->SetAccessor(to_v8(class_.isolate(), name), getter, setter, data, |
384 | - v8::DEFAULT, prop_attrs); |
385 | + v8::DEFAULT, v8::DontDelete); |
386 | return *this; |
387 | } |
388 | |
389 | |
390 | === modified file 'src/internal/require.h' |
391 | --- src/internal/require.h 2015-07-02 11:58:21 +0000 |
392 | +++ src/internal/require.h 2015-07-07 10:47:30 +0000 |
393 | @@ -63,27 +63,28 @@ |
394 | { |
395 | for (int i = 0; i < args.Length(); ++i) |
396 | { |
397 | - if (args[i]->IsInt32()) |
398 | - { |
399 | - std::cout << v8cpp::from_v8<int>(v8::Isolate::GetCurrent(), args[i]) << std::endl; |
400 | - } |
401 | if (args[i]->IsUint32()) |
402 | { |
403 | - std::cout << v8cpp::from_v8<unsigned int>(v8::Isolate::GetCurrent(), args[i]) << std::endl; |
404 | + std::cout << v8cpp::from_v8<unsigned int>(v8::Isolate::GetCurrent(), args[i]); |
405 | + } |
406 | + else if (args[i]->IsInt32()) |
407 | + { |
408 | + std::cout << v8cpp::from_v8<int>(v8::Isolate::GetCurrent(), args[i]); |
409 | } |
410 | else if (args[i]->IsNumber()) |
411 | { |
412 | - std::cout << v8cpp::from_v8<float>(v8::Isolate::GetCurrent(), args[i]) << std::endl; |
413 | + std::cout << v8cpp::from_v8<float>(v8::Isolate::GetCurrent(), args[i]); |
414 | } |
415 | else if (args[i]->IsBoolean()) |
416 | { |
417 | - std::cout << v8cpp::from_v8<bool>(v8::Isolate::GetCurrent(), args[i]) << std::endl; |
418 | + std::cout << v8cpp::from_v8<bool>(v8::Isolate::GetCurrent(), args[i]); |
419 | } |
420 | else if (args[i]->IsString()) |
421 | { |
422 | - std::cout << v8cpp::from_v8<std::string>(v8::Isolate::GetCurrent(), args[i]) << std::endl; |
423 | + std::cout << v8cpp::from_v8<std::string>(v8::Isolate::GetCurrent(), args[i]); |
424 | } |
425 | } |
426 | + std::cout << std::endl; |
427 | std::cout.flush(); |
428 | } |
429 | }; |
430 | @@ -108,8 +109,7 @@ |
431 | module = dlopen(suffixed_module_path.c_str(), RTLD_LAZY); |
432 | if (!module) |
433 | { |
434 | - std::cerr << "dlopen failed: " << dlerror() << std::endl; |
435 | - return exports; |
436 | + throw std::runtime_error("dlopen failed: " + std::string(dlerror())); |
437 | } |
438 | } |
439 | } |
440 | @@ -123,8 +123,7 @@ |
441 | auto v8cpp_init_func = (ModuleInitFunc*)dlsym(module, "init_module"); |
442 | if (!v8cpp_init_func) |
443 | { |
444 | - std::cerr << "dlsym failed: " << dlerror() << std::endl; |
445 | - return exports; |
446 | + throw std::runtime_error("dlsym failed: " + std::string(dlerror())); |
447 | } |
448 | |
449 | v8cpp_init_func(exports); |
450 | |
451 | === modified file 'src/run.h' |
452 | --- src/run.h 2015-07-02 11:59:20 +0000 |
453 | +++ src/run.h 2015-07-07 10:47:30 +0000 |
454 | @@ -77,7 +77,16 @@ |
455 | } |
456 | } |
457 | |
458 | - return v8cpp::from_v8<T>(isolate, script->Run()); |
459 | + v8::TryCatch try_catch; |
460 | + |
461 | + auto result = script->Run(); |
462 | + |
463 | + if (try_catch.HasCaught()) |
464 | + { |
465 | + throw std::runtime_error(v8cpp::from_v8<std::string>(isolate, try_catch.Message()->Get())); |
466 | + } |
467 | + |
468 | + return v8cpp::from_v8<T>(isolate, result); |
469 | } |
470 | |
471 | template <typename T = v8::Handle<v8::Value>> |
472 | |
473 | === modified file 'tests/CMakeLists.txt' |
474 | --- tests/CMakeLists.txt 2015-07-01 11:55:28 +0000 |
475 | +++ tests/CMakeLists.txt 2015-07-07 10:47:30 +0000 |
476 | @@ -6,7 +6,9 @@ |
477 | ${TEST_INCLUDE_DIRS} |
478 | ) |
479 | |
480 | +add_subdirectory(errors) |
481 | add_subdirectory(functions) |
482 | add_subdirectory(members) |
483 | add_subdirectory(methods) |
484 | add_subdirectory(objects) |
485 | +add_subdirectory(run) |
486 | |
487 | === added directory 'tests/errors' |
488 | === added file 'tests/errors/CMakeLists.txt' |
489 | --- tests/errors/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
490 | +++ tests/errors/CMakeLists.txt 2015-07-07 10:47:30 +0000 |
491 | @@ -0,0 +1,49 @@ |
492 | +# MODULE |
493 | +add_library( |
494 | + test-errors-module SHARED |
495 | + module.cpp |
496 | +) |
497 | + |
498 | +# This line sets the output binary name to "<target_name>.so" |
499 | +set_target_properties( |
500 | + test-errors-module |
501 | + PROPERTIES |
502 | + PREFIX "" |
503 | +) |
504 | + |
505 | +# FAIL-MODULE |
506 | +add_library( |
507 | + test-errors-fail-module SHARED |
508 | + fail-module.cpp |
509 | +) |
510 | + |
511 | +# This line sets the output binary name to "<target_name>.so" |
512 | +set_target_properties( |
513 | + test-errors-fail-module |
514 | + PROPERTIES |
515 | + PREFIX "" |
516 | +) |
517 | + |
518 | +# TEST |
519 | +configure_file(scripts/fail.js scripts/fail.js) |
520 | + |
521 | +add_executable( |
522 | + test-errors |
523 | + test.h |
524 | + test.cpp |
525 | +) |
526 | + |
527 | +target_link_libraries( |
528 | + test-errors |
529 | + |
530 | + v8-cpp |
531 | + |
532 | + ${GTEST_BOTH_LIBRARIES} |
533 | + ${GMOCK_LIBRARIES} |
534 | + ${TEST_LDFLAGS} |
535 | +) |
536 | + |
537 | +add_test( |
538 | + test-errors |
539 | + test-errors |
540 | +) |
541 | |
542 | === added file 'tests/errors/fail-module.cpp' |
543 | --- tests/errors/fail-module.cpp 1970-01-01 00:00:00 +0000 |
544 | +++ tests/errors/fail-module.cpp 2015-07-07 10:47:30 +0000 |
545 | @@ -0,0 +1,1 @@ |
546 | +// Intentionally blank |
547 | |
548 | === added file 'tests/errors/module.cpp' |
549 | --- tests/errors/module.cpp 1970-01-01 00:00:00 +0000 |
550 | +++ tests/errors/module.cpp 2015-07-07 10:47:30 +0000 |
551 | @@ -0,0 +1,27 @@ |
552 | +#include "test.h" |
553 | + |
554 | +#include <v8-cpp.h> |
555 | + |
556 | +using namespace v8; |
557 | + |
558 | +void InitAll(Handle<Object> exports) |
559 | +{ |
560 | + // Get current isolate |
561 | + Isolate* isolate = Isolate::GetCurrent(); |
562 | + |
563 | + // Prepare TestClass binding |
564 | + v8cpp::Class<TestClass> testclass(isolate); |
565 | + testclass |
566 | + .set_constructor<int, int>() |
567 | + .add_method("i", &TestClass::i) |
568 | + .add_method("throw_ex", &TestClass::throw_ex); |
569 | + |
570 | + // Prepare module |
571 | + v8cpp::Module module(isolate); |
572 | + |
573 | + module.add_class("TestClass", testclass); |
574 | + |
575 | + exports->SetPrototype(module.create_prototype()); |
576 | +} |
577 | + |
578 | +V8CPP_MODULE(addon, InitAll) |
579 | |
580 | === added directory 'tests/errors/scripts' |
581 | === added file 'tests/errors/scripts/fail.js' |
582 | --- tests/errors/scripts/fail.js 1970-01-01 00:00:00 +0000 |
583 | +++ tests/errors/scripts/fail.js 2015-07-07 10:47:30 +0000 |
584 | @@ -0,0 +1,1 @@ |
585 | +#!/usr/bin/env sh |
586 | |
587 | === added file 'tests/errors/test.cpp' |
588 | --- tests/errors/test.cpp 1970-01-01 00:00:00 +0000 |
589 | +++ tests/errors/test.cpp 2015-07-07 10:47:30 +0000 |
590 | @@ -0,0 +1,183 @@ |
591 | +#include "test.h" |
592 | + |
593 | +#include <v8-cpp.h> |
594 | + |
595 | +#include <gtest/gtest.h> |
596 | + |
597 | +TEST(Test, non_existent_script) |
598 | +{ |
599 | + v8::Isolate* isolate = v8::Isolate::New(); |
600 | + |
601 | + try |
602 | + { |
603 | + v8cpp::run_script_file(isolate, "./scripts/noexist.js"); |
604 | + } |
605 | + catch (std::exception const& e) |
606 | + { |
607 | + EXPECT_STREQ(e.what(), "run_script_file(): Failed to locate script file: \"./scripts/noexist.js\""); |
608 | + } |
609 | + |
610 | + isolate->Dispose(); |
611 | +} |
612 | + |
613 | +TEST(Test, non_existent_module) |
614 | +{ |
615 | + v8::Isolate* isolate = v8::Isolate::New(); |
616 | + |
617 | + try |
618 | + { |
619 | + v8cpp::run_script(isolate, "require('./noexist-module')"); |
620 | + } |
621 | + catch (std::exception const& e) |
622 | + { |
623 | + EXPECT_STREQ(e.what(), "Uncaught Error: dlopen failed: ./noexist-module: cannot open shared object file: No such file or directory"); |
624 | + } |
625 | + |
626 | + isolate->Dispose(); |
627 | +} |
628 | + |
629 | +TEST(Test, failing_module) |
630 | +{ |
631 | + v8::Isolate* isolate = v8::Isolate::New(); |
632 | + |
633 | + try |
634 | + { |
635 | + v8cpp::run_script(isolate, "require('./test-errors-fail-module')"); |
636 | + } |
637 | + catch (std::exception const& e) |
638 | + { |
639 | + EXPECT_STREQ(e.what(), "Uncaught Error: dlsym failed: ./test-errors-fail-module.so: undefined symbol: init_module"); |
640 | + } |
641 | + |
642 | + isolate->Dispose(); |
643 | +} |
644 | + |
645 | +TEST(Test, failing_script) |
646 | +{ |
647 | + v8::Isolate* isolate = v8::Isolate::New(); |
648 | + |
649 | + try |
650 | + { |
651 | + v8cpp::run_script(isolate, "#!/usr/bin/env sh"); |
652 | + } |
653 | + catch (std::exception const& e) |
654 | + { |
655 | + EXPECT_STREQ(e.what(), "run_script(): Failed to compile script."); |
656 | + } |
657 | + |
658 | + isolate->Dispose(); |
659 | +} |
660 | + |
661 | +TEST(Test, failing_script_file) |
662 | +{ |
663 | + v8::Isolate* isolate = v8::Isolate::New(); |
664 | + |
665 | + try |
666 | + { |
667 | + v8cpp::run_script_file(isolate, "./scripts/fail.js"); |
668 | + } |
669 | + catch (std::exception const& e) |
670 | + { |
671 | + EXPECT_STREQ(e.what(), "run_script(): Failed to compile script file: \"./scripts/fail.js\""); |
672 | + } |
673 | + |
674 | + isolate->Dispose(); |
675 | +} |
676 | + |
677 | +TEST(Test, incorrect_function_args) |
678 | +{ |
679 | + v8::Isolate* isolate = v8::Isolate::New(); |
680 | + |
681 | + try |
682 | + { |
683 | + v8cpp::run_script(isolate, |
684 | + R"( |
685 | + var module = require("./test-errors-module"); |
686 | + var test_object = new module.TestClass(1); |
687 | + test_object.i(); |
688 | + )"); |
689 | + } |
690 | + catch (std::exception const& e) |
691 | + { |
692 | + EXPECT_STREQ(e.what(), "Uncaught Error: argument count does not match the corresponding C++ function definition"); |
693 | + } |
694 | + |
695 | + isolate->Dispose(); |
696 | +} |
697 | + |
698 | +TEST(Test, conversion_errors) |
699 | +{ |
700 | + v8::Isolate* isolate = v8::Isolate::New(); |
701 | + |
702 | + try |
703 | + { |
704 | + v8cpp::run_script<std::string>(isolate, "1"); |
705 | + } |
706 | + catch (std::exception const& e) |
707 | + { |
708 | + EXPECT_STREQ(e.what(), "expected string value"); |
709 | + } |
710 | + try |
711 | + { |
712 | + v8cpp::run_script<bool>(isolate, "'hello'"); |
713 | + } |
714 | + catch (std::exception const& e) |
715 | + { |
716 | + EXPECT_STREQ(e.what(), "expected bool value"); |
717 | + } |
718 | + try |
719 | + { |
720 | + v8cpp::run_script<int>(isolate, "'hello'"); |
721 | + } |
722 | + catch (std::exception const& e) |
723 | + { |
724 | + EXPECT_STREQ(e.what(), "expected integer value"); |
725 | + } |
726 | + try |
727 | + { |
728 | + v8cpp::run_script<float>(isolate, "'hello'"); |
729 | + } |
730 | + catch (std::exception const& e) |
731 | + { |
732 | + EXPECT_STREQ(e.what(), "expected float value"); |
733 | + } |
734 | + try |
735 | + { |
736 | + v8cpp::run_script<std::vector<char>>(isolate, "1"); |
737 | + } |
738 | + catch (std::exception const& e) |
739 | + { |
740 | + EXPECT_STREQ(e.what(), "expected array value"); |
741 | + } |
742 | + try |
743 | + { |
744 | + v8cpp::run_script<TestClass>(isolate, "1"); |
745 | + } |
746 | + catch (std::exception const& e) |
747 | + { |
748 | + EXPECT_STREQ(e.what(), "expected an object"); |
749 | + } |
750 | + |
751 | + isolate->Dispose(); |
752 | +} |
753 | + |
754 | +TEST(Test, throw_from_module) |
755 | +{ |
756 | + v8::Isolate* isolate = v8::Isolate::New(); |
757 | + |
758 | + try |
759 | + { |
760 | + v8cpp::run_script(isolate, |
761 | + R"( |
762 | + var module = require("./test-errors-module"); |
763 | + var test_object = new module.TestClass(1, 2); |
764 | + test_object.throw_ex(); |
765 | + )"); |
766 | + } |
767 | + catch (std::exception const& e) |
768 | + { |
769 | + EXPECT_STREQ(e.what(), "Uncaught Error: BOOM!"); |
770 | + } |
771 | + |
772 | + isolate->Dispose(); |
773 | +} |
774 | |
775 | === added file 'tests/errors/test.h' |
776 | --- tests/errors/test.h 1970-01-01 00:00:00 +0000 |
777 | +++ tests/errors/test.h 2015-07-07 10:47:30 +0000 |
778 | @@ -0,0 +1,25 @@ |
779 | +#pragma once |
780 | + |
781 | +#include <gtest/gtest.h> |
782 | + |
783 | +class TestClass |
784 | +{ |
785 | +public: |
786 | + TestClass(int a, int b) |
787 | + { |
788 | + i_ = a + b; |
789 | + } |
790 | + |
791 | + int i() const |
792 | + { |
793 | + return i_; |
794 | + } |
795 | + |
796 | + void throw_ex() |
797 | + { |
798 | + throw std::runtime_error("BOOM!"); |
799 | + } |
800 | + |
801 | +private: |
802 | + int i_; |
803 | +}; |
804 | |
805 | === modified file 'tests/methods/CMakeLists.txt' |
806 | --- tests/methods/CMakeLists.txt 2015-07-01 11:55:28 +0000 |
807 | +++ tests/methods/CMakeLists.txt 2015-07-07 10:47:30 +0000 |
808 | @@ -4,12 +4,12 @@ |
809 | module.cpp |
810 | ) |
811 | |
812 | -# This line sets the output binary name to "<target_name>.node" |
813 | +# This line sets the output binary name to "<target_name>.so" |
814 | set_target_properties( |
815 | test-methods-module |
816 | PROPERTIES |
817 | PREFIX "" |
818 | - SUFFIX ".node" |
819 | + SUFFIX ".so" |
820 | ) |
821 | |
822 | # TEST |
823 | |
824 | === modified file 'tests/methods/module.cpp' |
825 | --- tests/methods/module.cpp 2015-07-02 09:43:58 +0000 |
826 | +++ tests/methods/module.cpp 2015-07-07 10:47:30 +0000 |
827 | @@ -12,12 +12,14 @@ |
828 | // Prepare TestClass binding |
829 | v8cpp::Class<TestClass_OL> testclass(isolate); |
830 | testclass |
831 | + .add_inheritance<BaseBaseTestClass>() |
832 | .add_inheritance<BaseTestClass>() |
833 | .add_inheritance<TestClass>() |
834 | .set_constructor() |
835 | .add_method("regular_method", &TestClass::regular_method) |
836 | .add_method("static_method", &TestClass::static_method) |
837 | .add_method("base_method", &BaseTestClass::base_method) |
838 | + .add_method("base_base_method", &BaseBaseTestClass::base_base_method) |
839 | .add_method("virtual_method", &TestClass::virtual_method) |
840 | .add_method("overload_method", &TestClass_OL::overload_method); |
841 | |
842 | |
843 | === modified file 'tests/methods/test.cpp' |
844 | --- tests/methods/test.cpp 2015-07-02 09:58:48 +0000 |
845 | +++ tests/methods/test.cpp 2015-07-07 10:47:30 +0000 |
846 | @@ -55,6 +55,15 @@ |
847 | |
848 | EXPECT_EQ(result, 1); |
849 | |
850 | + result = v8cpp::run_script<int>(isolate, |
851 | + R"( |
852 | + var module = require("./test-methods-module"); |
853 | + var test_object = new module.TestClass(); |
854 | + test_object.base_base_method(); |
855 | + )"); |
856 | + |
857 | + EXPECT_EQ(result, 0); |
858 | + |
859 | isolate->Dispose(); |
860 | } |
861 | |
862 | |
863 | === modified file 'tests/methods/test.h' |
864 | --- tests/methods/test.h 2015-07-02 11:25:17 +0000 |
865 | +++ tests/methods/test.h 2015-07-07 10:47:30 +0000 |
866 | @@ -4,7 +4,20 @@ |
867 | |
868 | #include <v8-cpp.h> |
869 | |
870 | -class BaseTestClass |
871 | +class BaseBaseTestClass |
872 | +{ |
873 | +public: |
874 | + virtual ~BaseBaseTestClass() = default; |
875 | + |
876 | + int base_base_method() |
877 | + { |
878 | + return 0; |
879 | + } |
880 | + |
881 | + virtual int virtual_method() = 0; |
882 | +}; |
883 | + |
884 | +class BaseTestClass : public BaseBaseTestClass |
885 | { |
886 | public: |
887 | virtual ~BaseTestClass() = default; |
888 | @@ -13,8 +26,6 @@ |
889 | { |
890 | return 1; |
891 | } |
892 | - |
893 | - virtual int virtual_method() = 0; |
894 | }; |
895 | |
896 | class TestClass : public BaseTestClass |
897 | |
898 | === modified file 'tests/objects/CMakeLists.txt' |
899 | --- tests/objects/CMakeLists.txt 2015-07-01 11:55:28 +0000 |
900 | +++ tests/objects/CMakeLists.txt 2015-07-07 10:47:30 +0000 |
901 | @@ -4,12 +4,12 @@ |
902 | module.cpp |
903 | ) |
904 | |
905 | -# This line sets the output binary name to "<target_name>.node" |
906 | +# This line sets the output binary name to "<target_name>" |
907 | set_target_properties( |
908 | test-objects-module |
909 | PROPERTIES |
910 | PREFIX "" |
911 | - SUFFIX ".node" |
912 | + SUFFIX "" |
913 | ) |
914 | |
915 | # TEST |
916 | |
917 | === added directory 'tests/run' |
918 | === added file 'tests/run/CMakeLists.txt' |
919 | --- tests/run/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
920 | +++ tests/run/CMakeLists.txt 2015-07-07 10:47:30 +0000 |
921 | @@ -0,0 +1,37 @@ |
922 | +# MODULE |
923 | +add_library( |
924 | + test-run-module SHARED |
925 | + module.cpp |
926 | +) |
927 | + |
928 | +# This line sets the output binary name to "<target_name>.so" |
929 | +set_target_properties( |
930 | + test-run-module |
931 | + PROPERTIES |
932 | + PREFIX "" |
933 | +) |
934 | + |
935 | +# TEST |
936 | +configure_file(scripts/test.js scripts/test.js) |
937 | +configure_file(scripts/test2.js scripts/test2.js) |
938 | + |
939 | +add_executable( |
940 | + test-run |
941 | + test.h |
942 | + test.cpp |
943 | +) |
944 | + |
945 | +target_link_libraries( |
946 | + test-run |
947 | + |
948 | + v8-cpp |
949 | + |
950 | + ${GTEST_BOTH_LIBRARIES} |
951 | + ${GMOCK_LIBRARIES} |
952 | + ${TEST_LDFLAGS} |
953 | +) |
954 | + |
955 | +add_test( |
956 | + test-run |
957 | + test-run |
958 | +) |
959 | |
960 | === added file 'tests/run/module.cpp' |
961 | --- tests/run/module.cpp 1970-01-01 00:00:00 +0000 |
962 | +++ tests/run/module.cpp 2015-07-07 10:47:30 +0000 |
963 | @@ -0,0 +1,26 @@ |
964 | +#include "test.h" |
965 | + |
966 | +#include <v8-cpp.h> |
967 | + |
968 | +using namespace v8; |
969 | + |
970 | +void InitAll(Handle<Object> exports) |
971 | +{ |
972 | + // Get current isolate |
973 | + Isolate* isolate = Isolate::GetCurrent(); |
974 | + |
975 | + // Prepare TestClass binding |
976 | + v8cpp::Class<TestClass> testclass(isolate); |
977 | + testclass |
978 | + .set_constructor<int, int>() |
979 | + .add_method("i", &TestClass::i); |
980 | + |
981 | + // Prepare module |
982 | + v8cpp::Module module(isolate); |
983 | + |
984 | + module.add_class("TestClass", testclass); |
985 | + |
986 | + exports->SetPrototype(module.create_prototype()); |
987 | +} |
988 | + |
989 | +V8CPP_MODULE(addon, InitAll) |
990 | |
991 | === added directory 'tests/run/scripts' |
992 | === added file 'tests/run/scripts/test.js' |
993 | --- tests/run/scripts/test.js 1970-01-01 00:00:00 +0000 |
994 | +++ tests/run/scripts/test.js 2015-07-07 10:47:30 +0000 |
995 | @@ -0,0 +1,3 @@ |
996 | +var module = require("../test-run-module"); |
997 | +var test_object = new module.TestClass(1, 2); |
998 | +test_object; |
999 | |
1000 | === added file 'tests/run/scripts/test2.js' |
1001 | --- tests/run/scripts/test2.js 1970-01-01 00:00:00 +0000 |
1002 | +++ tests/run/scripts/test2.js 2015-07-07 10:47:30 +0000 |
1003 | @@ -0,0 +1,7 @@ |
1004 | +console.log(6354, " > ", -23); |
1005 | +console.log(-9.21, " < ", 0.359); |
1006 | +console.log(true, " > ", false); |
1007 | +console.log("hello", " ", "there"); |
1008 | + |
1009 | +var module = require("../test-run-module"); |
1010 | +new module.TestClass(3, 4); |
1011 | |
1012 | === added file 'tests/run/test.cpp' |
1013 | --- tests/run/test.cpp 1970-01-01 00:00:00 +0000 |
1014 | +++ tests/run/test.cpp 2015-07-07 10:47:30 +0000 |
1015 | @@ -0,0 +1,27 @@ |
1016 | +#include "test.h" |
1017 | + |
1018 | +#include <v8-cpp.h> |
1019 | + |
1020 | +#include <gtest/gtest.h> |
1021 | + |
1022 | +TEST(Test, run_test_script) |
1023 | +{ |
1024 | + v8::Isolate* isolate = v8::Isolate::New(); |
1025 | + |
1026 | + auto test_object = v8cpp::run_script_file<TestClass>(isolate, "./scripts/test.js"); |
1027 | + |
1028 | + EXPECT_EQ(test_object.i(), 3); |
1029 | + |
1030 | + isolate->Dispose(); |
1031 | +} |
1032 | + |
1033 | +TEST(Test, run_test_script_2) |
1034 | +{ |
1035 | + v8::Isolate* isolate = v8::Isolate::New(); |
1036 | + |
1037 | + auto test_object = v8cpp::run_script_file<TestClass>(isolate, "./scripts/test2.js"); |
1038 | + |
1039 | + EXPECT_EQ(test_object.i(), 7); |
1040 | + |
1041 | + isolate->Dispose(); |
1042 | +} |
1043 | |
1044 | === added file 'tests/run/test.h' |
1045 | --- tests/run/test.h 1970-01-01 00:00:00 +0000 |
1046 | +++ tests/run/test.h 2015-07-07 10:47:30 +0000 |
1047 | @@ -0,0 +1,20 @@ |
1048 | +#pragma once |
1049 | + |
1050 | +#include <gtest/gtest.h> |
1051 | + |
1052 | +class TestClass |
1053 | +{ |
1054 | +public: |
1055 | + TestClass(int a, int b) |
1056 | + { |
1057 | + i_ = a + b; |
1058 | + } |
1059 | + |
1060 | + int i() const |
1061 | + { |
1062 | + return i_; |
1063 | + } |
1064 | + |
1065 | +private: |
1066 | + int i_; |
1067 | +}; |