Commit 272ebdc9 authored by Niels Lohmann's avatar Niels Lohmann

🔖 Merge branch 'release/2.0.8'

parents 79a9d00e 44c0f811
......@@ -14,3 +14,7 @@ doc/html
me.nlohmann.json.docset
benchmarks/files/numbers/*.json
.idea
cmake-build-debug
......@@ -84,49 +84,40 @@ matrix:
# Coverity (only for branch coverity_scan)
- os: linux
compiler: gcc
compiler: clang
before_install: echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5', 'valgrind']
packages: ['valgrind']
coverity_scan:
project:
name: "nlohmann/json"
description: "Build submitted via Travis CI"
notification_email: niels.lohmann@gmail.com
build_command_prepend: "make clean ; sudo cp $(which g++-5) $(which g++)"
build_command_prepend: "make clean"
build_command: "make"
branch_pattern: coverity_scan
env:
- COMPILER=g++-5
- LLVM_VERSION=3.6.0
- SPECIAL=coverity
# OSX / Clang
- os: osx
osx_image: beta-xcode6.1
- os: osx
osx_image: beta-xcode6.2
- os: osx
osx_image: beta-xcode6.3
- os: osx
osx_image: xcode6.4
- os: osx
osx_image: xcode7.1
osx_image: xcode7.3
- os: osx
osx_image: xcode7.2
osx_image: xcode8
- os: osx
osx_image: xcode7.3
osx_image: xcode8.1
- os: osx
osx_image: xcode8
osx_image: xcode8.2
# Linux / GCC
......
cmake_minimum_required(VERSION 3.0)
# define the project
project(nlohmann_json VERSION 2.0.7 LANGUAGES CXX)
project(nlohmann_json VERSION 2.0.8 LANGUAGES CXX)
enable_testing()
......
This diff is collapsed.
The library is licensed under the MIT License
JSON for Modern C++ is licensed under the MIT License
<http://opensource.org/licenses/MIT>:
Copyright (c) 2013-2016 Niels Lohmann
......
......@@ -95,7 +95,7 @@ pretty:
# benchmarks
json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp
cd benchmarks/files/numbers ; python generate.py
$(CXX) -std=c++11 $(CXXFLAGS) -DNDEBUG -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@
$(CXX) -std=c++11 -pthread $(CXXFLAGS) -DNDEBUG -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@
./json_benchmarks
......
......@@ -3,6 +3,7 @@
[![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json)
[![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json)
[![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
[![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/fsf5FqYe6GoX68W6)
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
......@@ -24,7 +25,7 @@ Other aspects were not so important to us:
- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs.
- **Speed**. We currently implement the parser as naive [recursive descent parser](http://en.wikipedia.org/wiki/Recursive_descent_parser) with hand coded string handling. It is fast enough, but a [LALR-parser](http://en.wikipedia.org/wiki/LALR_parser) may be even faster (but would consist of more files which makes the integration harder).
- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set.
See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information.
......@@ -129,6 +130,8 @@ json array_not_object = { json::array({"currency", "USD"}), json::array({"value"
### Serialization / Deserialization
#### To/from strings
You can create an object (deserialization) by appending `_json` to a string literal:
```cpp
......@@ -162,6 +165,8 @@ std::cout << j.dump(4) << std::endl;
// }
```
#### To/from streams (e.g. files, string streams)
You can also use streams to serialize and deserialize:
```cpp
......@@ -176,10 +181,37 @@ std::cout << j;
std::cout << std::setw(4) << j << std::endl;
```
These operators work for any subclasses of `std::istream` or `std::ostream`.
These operators work for any subclasses of `std::istream` or `std::ostream`. Here is the same example with files:
```cpp
// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;
// write prettified JSON to another file
std::ofstream o("pretty.json");
o << std::setw(4) << j << std::endl;
```
Please note that setting the exception bit for `failbit` is inappropriate for this use case. It will result in program termination due to the `noexcept` specifier in use.
#### Read from iterator range
You can also read JSON from an iterator range; that is, from any container accessible by iterators whose content is stored as contiguous byte sequence, for instance a `std::vector<uint8_t>`:
```cpp
std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v.begin(), v.end());
```
You may leave the iterators for the range [begin, end):
```cpp
std::vector<uint8_t> v = {'t', 'r', 'u', 'e'};
json j = json::parse(v);
```
### STL-like access
......@@ -192,6 +224,9 @@ j.push_back("foo");
j.push_back(1);
j.push_back(true);
// also use emplace_back
j.emplace_back(1.78);
// iterate the array
for (json::iterator it = j.begin(); it != j.end(); ++it) {
std::cout << *it << '\n';
......@@ -230,6 +265,9 @@ o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;
// also use emplace
o.emplace("weather", "sunny");
// special iterator member functions for objects
for (json::iterator it = o.begin(); it != o.end(); ++it) {
std::cout << it.key() << " : " << it.value() << "\n";
......@@ -423,14 +461,11 @@ The following compilers are currently used in continuous integration at [Travis]
| Clang 3.7.1 | Ubuntu 14.04.4 LTS | clang version 3.7.1 (tags/RELEASE_371/final) |
| Clang 3.8.0 | Ubuntu 14.04.4 LTS | clang version 3.8.0 (tags/RELEASE_380/final) |
| Clang 3.8.1 | Ubuntu 14.04.4 LTS | clang version 3.8.1 (tags/RELEASE_381/final) |
| Clang Xcode 6.1 | Darwin Kernel Version 13.4.0 (OSX 10.9.5) | Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn) |
| Clang Xcode 6.2 | Darwin Kernel Version 13.4.0 (OSX 10.9.5) | Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) |
| Clang Xcode 6.3 | Darwin Kernel Version 14.3.0 (OSX 10.10.3) | Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn) |
| Clang Xcode 6.4 | Darwin Kernel Version 14.3.0 (OSX 10.10.3) | Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) |
| Clang Xcode 7.1 | Darwin Kernel Version 14.5.0 (OSX 10.10.5) | Apple LLVM version 7.0.0 (clang-700.1.76) |
| Clang Xcode 7.2 | Darwin Kernel Version 15.0.0 (OSX 10.10.5) | Apple LLVM version 7.0.2 (clang-700.1.81) |
| Clang Xcode 7.3 | Darwin Kernel Version 15.0.0 (OSX 10.10.5) | Apple LLVM version 7.3.0 (clang-703.0.29) |
| Clang Xcode 8.0 | Darwin Kernel Version 15.6.0 (OSX 10.11.6) | Apple LLVM version 8.0.0 (clang-800.0.38) |
| Clang Xcode 8.0 | Darwin Kernel Version 15.6.0 | Apple LLVM version 8.0.0 (clang-800.0.38) |
| Clang Xcode 8.1 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) |
| Clang Xcode 8.2 | Darwin Kernel Version 16.1.0 (macOS 10.12.1) | Apple LLVM version 8.0.0 (clang-800.0.42.1) |
| Visual Studio 14 2015 | Windows Server 2012 R2 (x64) | Microsoft (R) Build Engine version 14.0.25123.0 |
......@@ -499,6 +534,9 @@ I deeply appreciate the help of the following people.
- [ChristophJud](https://github.com/ChristophJud) overworked the CMake files to ease project inclusion.
- [Vladimir Petrigo](https://github.com/vpetrigo) made a SFINAE hack more readable.
- [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file.
- [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function.
- [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](http://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling, found some nice performance improvements in the parser and improved the benchmarking code.
- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan.
Thanks a lot for helping out!
......@@ -522,7 +560,7 @@ To compile and run the tests, you need to execute
$ make check
===============================================================================
All tests passed (8905491 assertions in 36 test cases)
All tests passed (8905518 assertions in 36 test cases)
```
Alternatively, you can use [CMake](https://cmake.org) and run
......
#define BENCHPRESS_CONFIG_MAIN
#include <fstream>
#include <sstream>
#include <benchpress.hpp>
#include <json.hpp>
#include <pthread.h>
#include <thread>
BENCHMARK("parse jeopardy.json", [](benchpress::context* ctx)
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
{
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
nlohmann::json j;
j << input_file;
}
})
using json = nlohmann::json;
BENCHMARK("parse canada.json", [](benchpress::context* ctx)
struct StartUp
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
StartUp()
{
std::ifstream input_file("benchmarks/files/nativejson-benchmark/canada.json");
nlohmann::json j;
j << input_file;
#ifndef __llvm__
// pin thread to a single CPU
cpu_set_t cpuset;
pthread_t thread;
thread = pthread_self();
CPU_ZERO(&cpuset);
CPU_SET(std::thread::hardware_concurrency() - 1, &cpuset);
pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
#endif
}
})
};
StartUp startup;
BENCHMARK("parse citm_catalog.json", [](benchpress::context* ctx)
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
{
std::ifstream input_file("benchmarks/files/nativejson-benchmark/citm_catalog.json");
nlohmann::json j;
j << input_file;
}
})
enum class EMode { input, output_no_indent, output_with_indent };
BENCHMARK("parse twitter.json", [](benchpress::context* ctx)
static void bench(benchpress::context& ctx,
const std::string& in_path,
const EMode mode)
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
// using string streams for benchmarking to factor-out cold-cache disk
// access.
std::stringstream istr;
{
std::ifstream input_file("benchmarks/files/nativejson-benchmark/twitter.json");
nlohmann::json j;
j << input_file;
}
})
// read file into string stream
std::ifstream input_file(in_path);
istr << input_file.rdbuf();
input_file.close();
BENCHMARK("parse numbers/floats.json", [](benchpress::context* ctx)
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
{
std::ifstream input_file("benchmarks/files/numbers/floats.json");
nlohmann::json j;
j << input_file;
// read the stream once
json j;
j << istr;
// clear flags and rewind
istr.clear();
istr.seekg(0);
}
})
BENCHMARK("parse numbers/signed_ints.json", [](benchpress::context* ctx)
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
switch (mode)
{
std::ifstream input_file("benchmarks/files/numbers/signed_ints.json");
nlohmann::json j;
j << input_file;
}
})
// benchmarking input
case EMode::input:
{
ctx.reset_timer();
BENCHMARK("parse numbers/unsigned_ints.json", [](benchpress::context* ctx)
{
for (size_t i = 0; i < ctx->num_iterations(); ++i)
{
std::ifstream input_file("benchmarks/files/numbers/unsigned_ints.json");
nlohmann::json j;
j << input_file;
}
})
for (size_t i = 0; i < ctx.num_iterations(); ++i)
{
// clear flags and rewind
istr.clear();
istr.seekg(0);
json j;
j << istr;
}
BENCHMARK("dump jeopardy.json", [](benchpress::context* ctx)
{
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
nlohmann::json j;
j << input_file;
std::ofstream output_file("jeopardy.dump.json");
break;
}
ctx->reset_timer();
for (size_t i = 0; i < ctx->num_iterations(); ++i)
{
output_file << j;
}
// benchmarking output
case EMode::output_no_indent:
case EMode::output_with_indent:
{
// create JSON value from input
json j;
j << istr;
std::stringstream ostr;
std::remove("jeopardy.dump.json");
})
ctx.reset_timer();
for (size_t i = 0; i < ctx.num_iterations(); ++i)
{
if (mode == EMode::output_no_indent)
{
ostr << j;
}
else
{
ostr << std::setw(4) << j;
}
BENCHMARK("dump jeopardy.json with indent", [](benchpress::context* ctx)
{
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
nlohmann::json j;
j << input_file;
std::ofstream output_file("jeopardy.dump.json");
// reset data
ostr.str(std::string());
}
ctx->reset_timer();
for (size_t i = 0; i < ctx->num_iterations(); ++i)
{
output_file << std::setw(4) << j;
break;
}
}
}
#define BENCHMARK_I(mode, title, in_path) \
BENCHMARK((title), [](benchpress::context* ctx) \
{ \
bench(*ctx, (in_path), (mode)); \
})
BENCHMARK_I(EMode::input, "parse jeopardy.json", "benchmarks/files/jeopardy/jeopardy.json");
BENCHMARK_I(EMode::input, "parse canada.json", "benchmarks/files/nativejson-benchmark/canada.json");
BENCHMARK_I(EMode::input, "parse citm_catalog.json", "benchmarks/files/nativejson-benchmark/citm_catalog.json");
BENCHMARK_I(EMode::input, "parse twitter.json", "benchmarks/files/nativejson-benchmark/twitter.json");
BENCHMARK_I(EMode::input, "parse numbers/floats.json", "benchmarks/files/numbers/floats.json");
BENCHMARK_I(EMode::input, "parse numbers/signed_ints.json", "benchmarks/files/numbers/signed_ints.json");
BENCHMARK_I(EMode::input, "parse numbers/unsigned_ints.json", "benchmarks/files/numbers/unsigned_ints.json");
std::remove("jeopardy.dump.json");
})
BENCHMARK_I(EMode::output_no_indent, "dump jeopardy.json", "benchmarks/files/jeopardy/jeopardy.json");
BENCHMARK_I(EMode::output_with_indent, "dump jeopardy.json with indent", "benchmarks/files/jeopardy/jeopardy.json");
BENCHMARK_I(EMode::output_no_indent, "dump numbers/floats.json", "benchmarks/files/numbers/floats.json");
BENCHMARK_I(EMode::output_no_indent, "dump numbers/signed_ints.json", "benchmarks/files/numbers/signed_ints.json");
......@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "JSON for Modern C++"
PROJECT_NUMBER = 2.0.7
PROJECT_NUMBER = 2.0.8
PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = .
......
<a target="_blank" href="http://melpon.org/wandbox/permlink/fsf5FqYe6GoX68W6"><b>online</b></a>
\ No newline at end of file
<a target="_blank" href="http://melpon.org/wandbox/permlink/G6Pdtdxq01HJvvJz"><b>online</b></a>
\ No newline at end of file
#include <json.hpp>
using json = nlohmann::json;
int main()
{
// create JSON values
json object = {{"one", 1}, {"two", 2}};
json null;
// print values
std::cout << object << '\n';
std::cout << null << '\n';
// add values
auto res1 = object.emplace("three", 3);
null.emplace("A", "a");
null.emplace("B", "b");
// the following call will not add an object, because there is already
// a value stored at key "B"
auto res2 = null.emplace("B", "c");
// print values
std::cout << object << '\n';
std::cout << *res1.first << " " << std::boolalpha << res1.second << '\n';
std::cout << null << '\n';
std::cout << *res2.first << " " << std::boolalpha << res2.second << '\n';
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/B6ILaoysGMliouEO"><b>online</b></a>
\ No newline at end of file
{"one":1,"two":2}
null
{"one":1,"three":3,"two":2}
3 true
{"A":"a","B":"b"}
"b" false
#include <json.hpp>
using json = nlohmann::json;
int main()
{
// create JSON values
json array = {1, 2, 3, 4, 5};
json null;
// print values
std::cout << array << '\n';
std::cout << null << '\n';
// add values
array.emplace_back(6);
null.emplace_back("first");
null.emplace_back(3, "second");
// print values
std::cout << array << '\n';
std::cout << null << '\n';
}
<a target="_blank" href="http://melpon.org/wandbox/permlink/jdch45YEMX94DvlH"><b>online</b></a>
\ No newline at end of file
[1,2,3,4,5]
null
[1,2,3,4,5,6]
["first",["second","second","second"]]
......@@ -197,7 +197,7 @@ The container functions known from STL have been extended to support the differe
<td class="ok_green">@link nlohmann::basic_json::max_size `max_size` @endlink (returns `0`)</td>
</tr>
<tr>
<td rowspan="5">modifiers</td>
<td rowspan="6">modifiers</td>
<td>`clear`</td>
<td class="ok_green">@link nlohmann::basic_json::clear `clear` @endlink</td>
<td class="ok_green">@link nlohmann::basic_json::clear `clear` @endlink</td>
......@@ -233,6 +233,15 @@ The container functions known from STL have been extended to support the differe
<td class="nok_throws">throws `std::domain_error`</td>
<td class="ok_green">@link nlohmann::basic_json::push_back(const typename object_t::value_type & val) `push_back` @endlink (creates object)<br>@link nlohmann::basic_json::push_back(const nlohmann::basic_json &) `push_back` @endlink (creates array)</td>
</tr>
<tr>
<td>`emplace` / `emplace_back`</td>
<td class="ok_green">@link nlohmann::basic_json::emplace() `emplace` @endlink</td>
<td class="ok_green">@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink</td>
<td class="nok_throws">throws `std::domain_error`</td>
<td class="nok_throws">throws `std::domain_error`</td>
<td class="nok_throws">throws `std::domain_error`</td>
<td class="ok_green">@link nlohmann::basic_json::emplace() `emplace` @endlink (creates object)<br>@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink (creates array)</td>
</tr>
<tr>
<td>`swap`</td>
<td class="ok_green">@link nlohmann::basic_json::swap `swap` @endlink</td>
......@@ -268,4 +277,4 @@ The container functions known from STL have been extended to support the differe
@author [Niels Lohmann](http://nlohmann.me)
@see https://github.com/nlohmann/json to download the source code
@version 2.0.7
@version 2.0.8
doc/json.gif

444 KB | W: | H:

doc/json.gif

1.16 MB | W: | H:

doc/json.gif
doc/json.gif
doc/json.gif
doc/json.gif
  • 2-up
  • Swipe
  • Onion skin
This diff is collapsed.
This diff is collapsed.
/*
* Catch v1.5.6
* Generated: 2016-06-09 19:20:41.460328
* Catch v1.5.8
* Generated: 2016-10-26 12:07:30.938259
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
......@@ -3223,10 +3223,11 @@ namespace Catch {
bool matches( TestCaseInfo const& testCase ) const {
// All patterns in a filter must match for the filter to be a match
for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
if( !(*it)->matches( testCase ) )
return false;
return true;
}
return true;
}
};
......@@ -4719,8 +4720,11 @@ namespace Catch {
std::string line;
while( std::getline( f, line ) ) {
line = trim(line);
if( !line.empty() && !startsWith( line, "#" ) )
addTestOrTags( config, "\"" + line + "\"," );
if( !line.empty() && !startsWith( line, "#" ) ) {
if( !startsWith( line, "\"" ) )
line = "\"" + line + "\"";
addTestOrTags( config, line + "," );
}
}
}
......@@ -5368,7 +5372,10 @@ namespace Catch {
++it ) {
matchedTests++;
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
Catch::cout() << testCaseInfo.name << std::endl;
if( startsWith( testCaseInfo.name, "#" ) )
Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl;
else
Catch::cout() << testCaseInfo.name << std::endl;
}
return matchedTests;
}
......@@ -6454,7 +6461,7 @@ namespace Catch {
namespace Catch {
struct RandomNumberGenerator {
typedef int result_type;
typedef std::ptrdiff_t result_type;
result_type operator()( result_type n ) const { return std::rand() % n; }
......@@ -7571,7 +7578,7 @@ namespace Catch {
return os;
}
Version libraryVersion( 1, 5, 6, "", 0 );
Version libraryVersion( 1, 5, 8, "", 0 );
}
......@@ -7802,8 +7809,11 @@ namespace Catch {
bool contains( std::string const& s, std::string const& infix ) {
return s.find( infix ) != std::string::npos;
}
char toLowerCh(char c) {
return static_cast<char>( ::tolower( c ) );
}
void toLowerInPlace( std::string& s ) {
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
}
std::string toLower( std::string const& s ) {
std::string lc = s;
......@@ -8951,9 +8961,10 @@ namespace Catch {
break;
default:
// Escape control chars - based on contribution by @espenalb in PR #465
// Escape control chars - based on contribution by @espenalb in PR #465 and
// by @mrpi PR #588
if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';
else
os << c;
}
......@@ -9008,13 +9019,20 @@ namespace Catch {
: m_tagIsOpen( false ),
m_needsNewline( false ),
m_os( &Catch::cout() )
{}
{
// We encode control characters, which requires
// XML 1.1
// see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
}
XmlWriter( std::ostream& os )
: m_tagIsOpen( false ),
m_needsNewline( false ),
m_os( &os )
{}
{
*m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
}
~XmlWriter() {
while( !m_tags.empty() )
......@@ -9181,7 +9199,7 @@ namespace Catch {
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseStarting(testInfo);
m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name );
if ( m_config->showDurations() == ShowDurations::Always )
m_testCaseTimer.start();
......@@ -9243,7 +9261,7 @@ namespace Catch {
.writeText( assertionResult.getMessage() );
break;
case ResultWas::FatalErrorCondition:
m_xml.scopedElement( "Fatal Error Condition" )
m_xml.scopedElement( "FatalErrorCondition" )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() );
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (fuzz test support)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Run "make fuzz_testing" and follow the instructions.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......@@ -258,6 +258,103 @@ TEST_CASE("modifiers")
}
}
SECTION("emplace_back()")
{
SECTION("to array")
{
SECTION("null")
{
json j;
j.emplace_back(1);
j.emplace_back(2);
CHECK(j.type() == json::value_t::array);
CHECK(j == json({1, 2}));
}
SECTION("array")
{
json j = {1, 2, 3};
j.emplace_back("Hello");
CHECK(j.type() == json::value_t::array);
CHECK(j == json({1, 2, 3, "Hello"}));
}
SECTION("multiple values")
{
json j;
j.emplace_back(3, "foo");
CHECK(j.type() == json::value_t::array);
CHECK(j == json({{"foo", "foo", "foo"}}));
}
}
SECTION("other type")
{
json j = 1;
CHECK_THROWS_AS(j.emplace_back("Hello"), std::domain_error);
CHECK_THROWS_WITH(j.emplace_back("Hello"), "cannot use emplace_back() with number");
}
}
SECTION("emplace()")
{
SECTION("to object")
{
SECTION("null")
{
// start with a null value
json j;
// add a new key
auto res1 = j.emplace("foo", "bar");
CHECK(res1.second == true);
CHECK(*res1.first == "bar");
// the null value is changed to an object
CHECK(j.type() == json::value_t::object);
// add a new key
auto res2 = j.emplace("baz", "bam");
CHECK(res2.second == true);
CHECK(*res2.first == "bam");
// we try to insert at given key - no change
auto res3 = j.emplace("baz", "bad");
CHECK(res3.second == false);
CHECK(*res3.first == "bam");
// the final object
CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}}));
}
SECTION("object")
{
// start with an object
json j = {{"foo", "bar"}};
// add a new key
auto res1 = j.emplace("baz", "bam");
CHECK(res1.second == true);
CHECK(*res1.first == "bam");
// add an existing key
auto res2 = j.emplace("foo", "bad");
CHECK(res2.second == false);
CHECK(*res2.first == "bar");
// check final object
CHECK(j == json({{"baz", "bam"}, {"foo", "bar"}}));
}
}
SECTION("other type")
{
json j = 1;
CHECK_THROWS_AS(j.emplace("foo", "bar"), std::domain_error);
CHECK_THROWS_WITH(j.emplace("foo", "bar"), "cannot use emplace() with number");
}
}
SECTION("operator+=")
{
SECTION("to array")
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......@@ -495,4 +495,25 @@ TEST_CASE("regression tests")
json j = json::parse("22e2222");
CHECK(j == json());
}
SECTION("issue #366 - json::parse on failed stream gets stuck")
{
std::ifstream f("file_not_found.json");
CHECK_THROWS_AS(json::parse(f), std::invalid_argument);
}
SECTION("issue #367 - calling stream at EOF")
{
std::stringstream ss;
json j;
ss << "123";
CHECK_NOTHROW(j << ss);
// see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:
// ss is not at EOF; this yielded an error before the fix
// (threw basic_string::append). No, it should just throw
// a parse error because of the EOF.
CHECK_THROWS_AS(j << ss, std::invalid_argument);
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
}
}
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 2.0.7
| | |__ | | | | | | version 2.0.8
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment