mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-03 13:46:46 +02:00
Compare commits
125 Commits
Author | SHA1 | Date | |
---|---|---|---|
b33966c755 | |||
d2cd13bf2e | |||
06b2263329 | |||
d4bb839ce9 | |||
6013a1a56f | |||
34b38e07c7 | |||
1ec16ca94f | |||
b350a96643 | |||
bf93779b4f | |||
dd0f7019ef | |||
175e5b3062 | |||
7885155634 | |||
1909ffe0f9 | |||
3345255f16 | |||
c49adfd6da | |||
5094b84a46 | |||
191fc5dff4 | |||
cb9c90f2d0 | |||
09f9bd6b8b | |||
67abbef818 | |||
7ed2559e9e | |||
ac8e5f01db | |||
396d2a7b3b | |||
de725e0a4e | |||
2a32803e9e | |||
d602232b9f | |||
b0730f04f7 | |||
ef8ed28aec | |||
b8eff868e6 | |||
d0b619ea93 | |||
652d70fe2c | |||
8228aec74b | |||
2f2e0e9415 | |||
3a9803679f | |||
dc42d93b0f | |||
dff07ebfe8 | |||
4c456a95a3 | |||
83e5d9d150 | |||
7079aa99d7 | |||
208a22e324 | |||
9afae963e8 | |||
1828dec658 | |||
afe2434baf | |||
e08f8d5b51 | |||
7e3b40f379 | |||
584770dc6f | |||
5d2a440c69 | |||
ac14f29e6c | |||
3d62fa8af2 | |||
0f85a55cac | |||
21db92af47 | |||
6447520b5b | |||
079ccadbee | |||
615f675840 | |||
2182c83b87 | |||
b8d1dccb21 | |||
c3d5e9382d | |||
ecb72f9a9d | |||
7004c39af6 | |||
057956225c | |||
b27990f780 | |||
61c6f8ba59 | |||
d8d37ba7ad | |||
92d6bae25c | |||
6e17c3e6f9 | |||
8ee67b0229 | |||
07b9153ae4 | |||
abfcac4674 | |||
cde8cd50f8 | |||
cf4436e581 | |||
2b6bb78a09 | |||
ffa7f8d22d | |||
f73be9cf0f | |||
8002722f3b | |||
62e83133cd | |||
1d21027e2a | |||
5705247e5f | |||
dde9e9fc26 | |||
a6da4ad452 | |||
e2a29eef24 | |||
043ee651a9 | |||
84b7037b3e | |||
c5838a876b | |||
750cd0be92 | |||
758580bfb6 | |||
04872b6db8 | |||
58c7c919f2 | |||
cd8373ad32 | |||
3b3ab8c4e1 | |||
5b06b1564e | |||
77b4270d97 | |||
7c2ca773ff | |||
e2bb2cec7b | |||
ff4e837df5 | |||
fb904033d3 | |||
e6cd16aec4 | |||
ee74c3bb1c | |||
37faa7ce13 | |||
3d6c328a4f | |||
5577d18377 | |||
1d103a1528 | |||
7b19a4b6e7 | |||
ac1d29fac0 | |||
98037e5742 | |||
d0e3808dd0 | |||
3760a643cb | |||
fc9d8aa31e | |||
ccfbb5fd1d | |||
c9fbc5e40a | |||
67b6797b6d | |||
8d9504239b | |||
bf5d0c790c | |||
f4379f97ae | |||
3dc67c5663 | |||
47f90b02c3 | |||
27c924746b | |||
7abf875071 | |||
e3e375f5cd | |||
ff06292d74 | |||
c1278797f2 | |||
421ecec0dd | |||
89ed54362b | |||
986f77fa15 | |||
f831ed395d | |||
a880614a75 |
@ -5,6 +5,8 @@ Standard: Cpp03
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
IncludeBlocks: Preserve
|
||||
IndentPPDirectives: AfterHash
|
||||
DerivePointerAlignment: false
|
||||
|
||||
# Always break after if to get accurate coverage
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
|
135
.github/workflows/ci.yml
vendored
135
.github/workflows/ci.yml
vendored
@ -10,18 +10,25 @@ jobs:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y clang-format
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Symlinks
|
||||
run: find * -type l -printf "::error::%p is a symlink. This is forbidden by the Arduino Library Specification." -exec false {} +
|
||||
- name: Clang-format
|
||||
run: |
|
||||
find src/ extras/ -name '*.[ch]pp' | xargs clang-format -i --verbose --style=file
|
||||
git diff --exit-code
|
||||
- name: Check URLs
|
||||
run: |
|
||||
grep -hREo "(http|https)://[a-zA-Z0-9./?=_%:-]*" src/ | sort -u | while read -r URL
|
||||
do
|
||||
STATUS=$(curl -s -o /dev/null -I -w "%{http_code}" "$URL")
|
||||
[ "$STATUS" -ge 400 ] && echo "::warning title=HTTP $STATUS::$URL returned $STATUS"
|
||||
done || true
|
||||
|
||||
gcc:
|
||||
name: GCC
|
||||
needs: lint
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@ -40,21 +47,20 @@ jobs:
|
||||
- gcc: "9"
|
||||
cxxflags: -fsanitize=address -fno-sanitize-recover=all
|
||||
- gcc: "10"
|
||||
cxxflags: -funsigned-char # Issue #1715
|
||||
- gcc: "11"
|
||||
steps:
|
||||
- name: Install
|
||||
run: |
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo add-apt-repository -yn 'deb http://mirrors.kernel.org/ubuntu hirsute main universe'
|
||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 3B4FE6ACC0B21F32
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty main universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ focal main universe'
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure
|
||||
run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
||||
env:
|
||||
@ -64,7 +70,11 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build .
|
||||
- name: Test
|
||||
run: ctest --output-on-failure -C Debug .
|
||||
run: |
|
||||
echo "## CTest output" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
ctest --output-on-failure -C Debug . | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
@ -103,13 +113,13 @@ jobs:
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang-${{ matrix.clang }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure
|
||||
run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
||||
env:
|
||||
@ -121,7 +131,11 @@ jobs:
|
||||
- name: Build
|
||||
run: cmake --build .
|
||||
- name: Test
|
||||
run: ctest --output-on-failure -C Debug .
|
||||
run: |
|
||||
echo "## CTest output" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
ctest --output-on-failure -C Debug . | tee -a $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
env:
|
||||
UBSAN_OPTIONS: print_stacktrace=1
|
||||
|
||||
@ -131,9 +145,11 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y g++-multilib
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y g++-multilib
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: GCC 32-bit
|
||||
run: g++ -std=c++11 -m32 -Isrc extras/conf_test/x86.cpp
|
||||
- name: GCC 64-bit
|
||||
@ -149,7 +165,7 @@ jobs:
|
||||
needs: [gcc, clang]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: 32-bit
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
|
||||
@ -164,17 +180,17 @@ jobs:
|
||||
xcode:
|
||||
name: XCode
|
||||
needs: clang
|
||||
runs-on: macos-10.15
|
||||
runs-on: macos-11
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- xcode: "10.3"
|
||||
- xcode: "11.7"
|
||||
- xcode: "12.4"
|
||||
- xcode: "13.2.1"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Select XCode version
|
||||
run: sudo xcode-select --switch /Applications/Xcode_${{ matrix.xcode }}.app
|
||||
- name: Configure
|
||||
@ -196,7 +212,7 @@ jobs:
|
||||
# runs-on: ${{ matrix.os }}
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v2
|
||||
# uses: actions/checkout@v3
|
||||
# - name: Configure
|
||||
# run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
||||
# - name: Build
|
||||
@ -218,9 +234,9 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Install arduino-cli
|
||||
run: brew update && brew install arduino-cli
|
||||
run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
|
||||
- name: Install core
|
||||
run: arduino-cli core install ${{ matrix.core }}
|
||||
- name: Install libraries
|
||||
@ -291,14 +307,14 @@ jobs:
|
||||
conf_test: esp8266
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up cache for pip
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install PlatformIO
|
||||
@ -310,7 +326,7 @@ jobs:
|
||||
if: ${{ matrix.platform == 'nordicnrf52' }}
|
||||
run: find examples/ -name '*.ino' -exec sed -i 's/\(#include <ArduinoJson.h>\)/\1\n#include <Adafruit_TinyUSB.h>/' {} +
|
||||
- name: Set up cache for platformio
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-platformio-${{ matrix.platform }}
|
||||
@ -359,7 +375,7 @@ jobs:
|
||||
- board: argon
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Particle CLI
|
||||
run: sudo npm install -g particle-cli
|
||||
- name: Login to Particle
|
||||
@ -377,7 +393,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y g++-arm-linux-gnueabihf
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure
|
||||
run: cmake .
|
||||
env:
|
||||
@ -394,7 +410,7 @@ jobs:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y lcov ninja-build
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure
|
||||
run: cmake -G Ninja -DCOVERAGE=true .
|
||||
- name: Build
|
||||
@ -408,7 +424,7 @@ jobs:
|
||||
- name: genhtml
|
||||
run: mkdir coverage && genhtml coverage_filtered.info -o coverage -t ArduinoJson
|
||||
- name: Upload HTML report
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Coverage report
|
||||
path: coverage
|
||||
@ -424,9 +440,11 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y valgrind ninja-build
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y valgrind ninja-build
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure
|
||||
run: cmake -G Ninja -D MEMORYCHECK_COMMAND_OPTIONS="--error-exitcode=1 --leak-check=full" .
|
||||
- name: Build
|
||||
@ -446,7 +464,7 @@ jobs:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y clang-tidy cmake ninja-build
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure
|
||||
run: cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy-10;--warnings-as-errors=*" -DCMAKE_BUILD_TYPE=Debug .
|
||||
env:
|
||||
@ -461,7 +479,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Amalgamate
|
||||
id: amalgamate
|
||||
run: |
|
||||
@ -473,7 +491,7 @@ jobs:
|
||||
INPUT=src/ArduinoJson.h
|
||||
OUTPUT=ArduinoJson-$VERSION.h
|
||||
extras/scripts/build-single-header.sh "$INPUT" "$OUTPUT"
|
||||
echo ::set-output name=filename::${OUTPUT}
|
||||
echo "filename=${OUTPUT}" >> $GITHUB_OUTPUT
|
||||
- name: Smoke test
|
||||
run: |
|
||||
g++ -x c++ - <<END
|
||||
@ -484,7 +502,7 @@ jobs:
|
||||
}
|
||||
END
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Single headers
|
||||
path: ${{ steps.amalgamate.outputs.filename }}
|
||||
@ -495,7 +513,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Amalgamate
|
||||
id: amalgamate
|
||||
run: |
|
||||
@ -507,7 +525,7 @@ jobs:
|
||||
INPUT=src/ArduinoJson.hpp
|
||||
OUTPUT=ArduinoJson-$VERSION.hpp
|
||||
extras/scripts/build-single-header.sh "$INPUT" "$OUTPUT"
|
||||
echo ::set-output name=filename::${OUTPUT}
|
||||
echo "filename=${OUTPUT}" >> $GITHUB_OUTPUT
|
||||
- name: Smoke test
|
||||
run: |
|
||||
g++ -x c++ - <<END
|
||||
@ -518,7 +536,7 @@ jobs:
|
||||
}
|
||||
END
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Single headers
|
||||
path: ${{ steps.amalgamate.outputs.filename }}
|
||||
@ -529,14 +547,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.espressif
|
||||
key: ${{ runner.os }}-esp-idf
|
||||
- name: Checkout ArduinoJson
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Checkout ESP-IDF
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: espressif/esp-idf
|
||||
path: esp-idf
|
||||
@ -553,3 +571,32 @@ jobs:
|
||||
source esp-idf/export.sh
|
||||
cd extras/ci/espidf
|
||||
idf.py build
|
||||
|
||||
codeql:
|
||||
name: CodeQL
|
||||
runs-on: ubuntu-20.04
|
||||
needs: gcc
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug .
|
||||
cmake --build .
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:cpp"
|
||||
|
6
.github/workflows/lock.yml
vendored
6
.github/workflows/lock.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: 'Lock Threads'
|
||||
name: Lock Threads
|
||||
|
||||
on:
|
||||
schedule:
|
||||
@ -8,7 +8,7 @@ jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
- uses: dessant/lock-threads@v4
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: 30
|
||||
issue-inactive-days: 30
|
||||
|
39
.github/workflows/release.yml
vendored
39
.github/workflows/release.yml
vendored
@ -13,39 +13,62 @@ jobs:
|
||||
- name: Set variables
|
||||
id: init
|
||||
run: |
|
||||
echo ::set-output name=tag::${GITHUB_REF#refs/tags/}
|
||||
echo ::set-output name=version::${GITHUB_REF#refs/tags/v}
|
||||
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Write release body
|
||||
id: body
|
||||
run: |
|
||||
FILENAME=RELEASE.md
|
||||
extras/scripts/get-release-body.sh ${{ steps.init.outputs.tag }} CHANGELOG.md | tee $FILENAME
|
||||
echo ::set-output name=filename::$FILENAME
|
||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
||||
- name: Amalgamate ArduinoJson.h
|
||||
id: amalgamate_h
|
||||
run: |
|
||||
FILENAME=ArduinoJson-${{ steps.init.outputs.tag }}.h
|
||||
extras/scripts/build-single-header.sh src/ArduinoJson.h "$FILENAME"
|
||||
echo ::set-output name=filename::$FILENAME
|
||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
||||
- name: Amalgamate ArduinoJson.hpp
|
||||
id: amalgamate_hpp
|
||||
run: |
|
||||
FILENAME=ArduinoJson-${{ steps.init.outputs.tag }}.hpp
|
||||
extras/scripts/build-single-header.sh src/ArduinoJson.hpp "$FILENAME"
|
||||
echo ::set-output name=filename::$FILENAME
|
||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
||||
- name: Create Arduino package
|
||||
id: arduino
|
||||
run: |
|
||||
FILENAME=ArduinoJson-${{ steps.init.outputs.tag }}.zip
|
||||
extras/scripts/build-arduino-package.sh . "$FILENAME"
|
||||
echo ::set-output name=filename::$FILENAME
|
||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
||||
- name: Create release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
bodyFile: ${{ steps.body.outputs.filename }}
|
||||
draft: true
|
||||
name: ArduinoJson ${{ steps.init.outputs.version }}
|
||||
artifacts: ${{ steps.amalgamate_h.outputs.filename }},${{ steps.amalgamate_hpp.outputs.filename }},${{ steps.arduino.outputs.filename }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
idf:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Upload component to the component registry
|
||||
uses: espressif/upload-components-ci-action@v1
|
||||
with:
|
||||
name: ArduinoJson
|
||||
namespace: bblanchon
|
||||
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
|
||||
|
||||
particle:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install
|
||||
run: npm install -g particle-cli
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Login
|
||||
run: particle login --token ${{ secrets.PARTICLE_TOKEN }}
|
||||
- name: Publish
|
||||
run: extras/scripts/publish-particle-library.sh
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,3 +15,6 @@
|
||||
# Used by CI for Particle
|
||||
/src/*.ino
|
||||
/project.properties
|
||||
|
||||
# Used by IDF
|
||||
/dist/
|
||||
|
16
.vscode/settings.json
vendored
16
.vscode/settings.json
vendored
@ -5,18 +5,10 @@
|
||||
"git.inputValidationSubjectLength": 72,
|
||||
"files.insertFinalNewline": true,
|
||||
"files.trimFinalNewlines": true,
|
||||
"files.associations": {
|
||||
"fstream": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"vector": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xstring": "cpp"
|
||||
},
|
||||
"search.exclude": {
|
||||
"/extras/tests/catch/*": true
|
||||
}
|
||||
},
|
||||
"C_Cpp.default.includePath": [
|
||||
"/src"
|
||||
]
|
||||
}
|
||||
|
58
CHANGELOG.md
58
CHANGELOG.md
@ -1,6 +1,64 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v6.20.1 (2023-02-08)
|
||||
-------
|
||||
|
||||
* Remove explicit exclusion of `as<char*>()` and `as<char>()` (issue #1860)
|
||||
If you try to call them, you'll now get the same error message as any unsupported type.
|
||||
You could also add a custom converter for `char*` and `char`.
|
||||
|
||||
v6.20.0 (2022-12-26)
|
||||
-------
|
||||
|
||||
* Add `JsonVariant::shallowCopy()` (issue #1343)
|
||||
* Fix `9.22337e+18 is outside the range of representable values of type 'long'`
|
||||
* Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst`
|
||||
* Fix lax parsing of `true`, `false`, and `null` (issue #1781)
|
||||
* Remove undocumented `accept()` functions
|
||||
* Rename `addElement()` to `add()`
|
||||
* Remove `getElement()`, `getOrAddElement()`, `getMember()`, and `getOrAddMember()`
|
||||
* Remove undocumented `JsonDocument::data()` and `JsonDocument::memoryPool()`
|
||||
* Remove undocumented `JsonArrayIterator::internal()` and `JsonObjectIterator::internal()`
|
||||
* Rename things in `ARDUINOJSON_NAMESPACE` to match the public names
|
||||
* Add documentation to most public symbols
|
||||
* Remove support for naked `char` (was deprecated since 6.18.0)
|
||||
|
||||
> ### BREAKING CHANGES
|
||||
>
|
||||
> This release hides `JsonVariant`'s functions that were only intended for internal use.
|
||||
> If you were using them in your programs, you must replace with `operator[]` and `to<JsonVariant>()`, like so:
|
||||
>
|
||||
> ```c++
|
||||
> // before
|
||||
> JsonVariant a = variant.getElement(idx);
|
||||
> JsonVariant b = variant.getOrAddElement(idx);
|
||||
> JsonVariant c = variant.getMember(key);
|
||||
> JsonVariant d = variant.getOrAddMember(key);
|
||||
>
|
||||
> // after
|
||||
> JsonVariant a = variant[idx];
|
||||
> JsonVariant b = idx < variant.size() ? variant[idx] : variant[idx].to<JsonVariant>();
|
||||
> JsonVariant c = variant[key];
|
||||
> JsonVariant d = variant.containsKey(key) ? variant[key] : variant[key].to<JsonVariant>();
|
||||
> ```
|
||||
|
||||
v6.19.4 (2022-04-05)
|
||||
-------
|
||||
|
||||
* Add `ElementProxy::memoryUsage()`
|
||||
* Add `MemberProxy::memoryUsage()` (issue #1730)
|
||||
* Add implicit conversion from `JsonDocument` to `JsonVariant`
|
||||
* Fix comparisons operators with `const JsonDocument&`
|
||||
|
||||
v6.19.3 (2022-03-08)
|
||||
-------
|
||||
|
||||
* Fix `call of overloaded 'String(const char*, int)' is ambiguous`
|
||||
* Fix `JsonString` operator `==` and `!=` for non-zero-terminated string
|
||||
* Fix `-Wsign-conversion` on GCC 8 (issue #1715)
|
||||
* MessagePack: serialize round floats as integers (issue #1718)
|
||||
|
||||
v6.19.2 (2022-02-14)
|
||||
-------
|
||||
|
||||
|
@ -10,7 +10,7 @@ if(ESP_PLATFORM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(ArduinoJson VERSION 6.19.2)
|
||||
project(ArduinoJson VERSION 6.20.1)
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
include(CTest)
|
||||
|
@ -1,10 +1,10 @@
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014-2022, Benoit BLANCHON
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014-2022, Benoit BLANCHON
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
88
README.md
88
README.md
@ -1,47 +1,49 @@
|
||||

|
||||
<p align="center">
|
||||
<a href="https://arduinojson.org/"><img alt="ArduinoJson" src="https://arduinojson.org/images/logo.svg" width="200" /></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
[](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
|
||||
[](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
|
||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
[](https://lgtm.com/projects/g/bblanchon/ArduinoJson/)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.19.2)
|
||||
[](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.2)
|
||||
[](https://github.com/bblanchon/ArduinoJson/stargazers)
|
||||
[](https://github.com/sponsors/bblanchon)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.20.1)
|
||||
[](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.20.1)
|
||||
[](https://components.espressif.com/components/bblanchon/arduinojson)
|
||||
[](https://github.com/bblanchon/ArduinoJson/stargazers)
|
||||
[](https://github.com/sponsors/bblanchon)
|
||||
|
||||
ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
||||
|
||||
## Features
|
||||
|
||||
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#filtering)
|
||||
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/)
|
||||
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/)
|
||||
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/)
|
||||
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/)
|
||||
* [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/#filtering)
|
||||
* Supports single quotes as a string delimiter
|
||||
* Compatible with [NDJSON](http://ndjson.org/) and [JSON Lines](https://jsonlines.org/)
|
||||
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/?utm_source=github&utm_medium=readme)
|
||||
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/?utm_source=github&utm_medium=readme)
|
||||
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/?utm_source=github&utm_medium=readme)
|
||||
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/)
|
||||
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/)
|
||||
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/)
|
||||
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/)
|
||||
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/)
|
||||
* Efficient
|
||||
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
|
||||
* [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/?utm_source=github&utm_medium=readme)
|
||||
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
|
||||
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
|
||||
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
|
||||
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/)
|
||||
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/)
|
||||
* [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/)
|
||||
* Versatile
|
||||
* Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
|
||||
* Supports [`String`](https://arduinojson.org/v6/api/config/enable_arduino_string/?utm_source=github&utm_medium=readme), [`std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme), and [`std::string_view`](https://arduinojson.org/v6/api/config/enable_string_view/?utm_source=github&utm_medium=readme)
|
||||
* Supports [`Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/?utm_source=github&utm_medium=readme) and [`std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
||||
* Supports [Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
||||
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
|
||||
* Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/?utm_source=github&utm_medium=readme)
|
||||
* Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/)
|
||||
* Supports [`String`](https://arduinojson.org/v6/api/config/enable_arduino_string/), [`std::string`](https://arduinojson.org/v6/api/config/enable_std_string/), and [`std::string_view`](https://arduinojson.org/v6/api/config/enable_string_view/)
|
||||
* Supports [`Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/) and [`std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/)
|
||||
* Supports [Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/)
|
||||
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/#custom-writer)
|
||||
* Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/)
|
||||
* Portable
|
||||
* Usable on any C++ project (not limited to Arduino)
|
||||
* Compatible with C++98, C++11, C++14 and C++17
|
||||
@ -69,15 +71,15 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
||||
* [Visual Micro](http://www.visualmicro.com/)
|
||||
* [Visual Studio](https://www.visualstudio.com/)
|
||||
* [Even works with online compilers like wandbox.org](https://wandbox.org/permlink/RlZSKy17DjJ6HcdN)
|
||||
* [CMake friendly](https://arduinojson.org/v6/how-to/use-arduinojson-with-cmake/?utm_source=github&utm_medium=readme)
|
||||
* [CMake friendly](https://arduinojson.org/v6/how-to/use-arduinojson-with-cmake/)
|
||||
* Well designed
|
||||
* [Elegant API](http://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [Elegant API](http://arduinojson.org/v6/example/)
|
||||
* [Thread-safe](https://en.wikipedia.org/wiki/Thread_safety)
|
||||
* Self-contained (no external dependency)
|
||||
* `const` friendly
|
||||
* [`for` friendly](https://arduinojson.org/v6/api/jsonobject/begin_end/?utm_source=github&utm_medium=readme)
|
||||
* [`for` friendly](https://arduinojson.org/v6/api/jsonobject/begin_end/)
|
||||
* [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming)
|
||||
* Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/?utm_source=github&utm_medium=readme#integer-overflows)
|
||||
* Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/#integer-overflows)
|
||||
* Well tested
|
||||
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
* Continuously tested on
|
||||
@ -87,18 +89,17 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
||||
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
* Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/)
|
||||
* Well documented
|
||||
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
|
||||
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
|
||||
* [Troubleshooter](https://arduinojson.org/v6/troubleshooter/?utm_source=github&utm_medium=readme)
|
||||
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
|
||||
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/)
|
||||
* [Examples](https://arduinojson.org/v6/example/)
|
||||
* [How-tos](https://arduinojson.org/v6/example/)
|
||||
* [FAQ](https://arduinojson.org/v6/faq/)
|
||||
* [Troubleshooter](https://arduinojson.org/v6/troubleshooter/)
|
||||
* [Book](https://arduinojson.org/book/)
|
||||
* [Changelog](CHANGELOG.md)
|
||||
* Vibrant user community
|
||||
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories)
|
||||
* [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson)
|
||||
* [Responsive support](https://github.com/bblanchon/ArduinoJson/issues?q=is%3Aissue+is%3Aclosed)
|
||||
* [Discord server](https://discord.gg/DzN6hHHD4h)
|
||||
|
||||
## Quickstart
|
||||
|
||||
@ -118,7 +119,7 @@ double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
```
|
||||
|
||||
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=github&utm_medium=readme)
|
||||
See the [tutorial on arduinojson.org](https://arduinojson.org/v6/doc/deserialization/)
|
||||
|
||||
### Serialization
|
||||
|
||||
@ -137,16 +138,13 @@ serializeJson(doc, Serial);
|
||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
```
|
||||
|
||||
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=github&utm_medium=readme)
|
||||
See the [tutorial on arduinojson.org](https://arduinojson.org/v6/doc/serialization/)
|
||||
|
||||
## Sponsors
|
||||
|
||||
ArduinoJson is thankful to its sponsors. Please give them a visit; they deserve it!
|
||||
|
||||
<p>
|
||||
<a href="https://techexplorations.com/" rel="sponsored">
|
||||
<img alt="Tech Explorations" src="https://arduinojson.org/images/2021/10/techexplorations.png" width="200">
|
||||
</a>
|
||||
<a href="https://www.programmingelectronics.com/" rel="sponsored">
|
||||
<img src="https://arduinojson.org/images/2021/10/programmingeleactronicsacademy.png" alt="Programming Electronics Academy" width="200">
|
||||
</a>
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 6.19.2.{build}
|
||||
version: 6.20.1.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
|
367
banner.svg
367
banner.svg
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 32 KiB |
@ -2,7 +2,7 @@
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to use DeserializationOpion::Filter
|
||||
// This example shows how to use DeserializationOption::Filter
|
||||
//
|
||||
// https://arduinojson.org/v6/example/filter/
|
||||
|
||||
|
@ -20,28 +20,27 @@ void setup() {
|
||||
// WARNING: the strings in the input will be duplicated in the JsonDocument.
|
||||
deserializeJson(doc, F("{\"sensor\":\"gps\",\"time\":1351824120,"
|
||||
"\"data\":[48.756080,2.302038]}"));
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
// You can use a Flash String to get an element of a JsonObject
|
||||
// You can use a Flash String as a key to get a member from JsonDocument
|
||||
// No duplication is done.
|
||||
long time = obj[F("time")];
|
||||
long time = doc[F("time")];
|
||||
|
||||
// You can use a Flash String to set an element of a JsonObject
|
||||
// You can use a Flash String as a key to set a member of a JsonDocument
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonDocument.
|
||||
obj[F("time")] = time;
|
||||
doc[F("time")] = time;
|
||||
|
||||
// You can set a Flash String to a JsonObject or JsonArray:
|
||||
// You can set a Flash String as the content of a JsonVariant
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonDocument.
|
||||
obj["sensor"] = F("gps");
|
||||
doc["sensor"] = F("gps");
|
||||
|
||||
// It works with serialized() too:
|
||||
obj["sensor"] = serialized(F("\"gps\""));
|
||||
obj["sensor"] = serialized(F("\xA3gps"), 3);
|
||||
doc["sensor"] = serialized(F("\"gps\""));
|
||||
doc["sensor"] = serialized(F("\xA3gps"), 3);
|
||||
|
||||
// You can compare the content of a JsonVariant to a Flash String
|
||||
if (obj["sensor"] == F("gps")) {
|
||||
if (doc["sensor"] == F("gps")) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
@ -20,42 +20,42 @@ void setup() {
|
||||
String input =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
deserializeJson(doc, input);
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
// You can use a String to get an element of a JsonObject
|
||||
// You can use a String as a key to get a member from JsonDocument
|
||||
// No duplication is done.
|
||||
long time = obj[String("time")];
|
||||
long time = doc[String("time")];
|
||||
|
||||
// You can use a String to set an element of a JsonObject
|
||||
// You can use a String as a key to set a member of a JsonDocument
|
||||
// WARNING: the content of the String will be duplicated in the JsonDocument.
|
||||
obj[String("time")] = time;
|
||||
doc[String("time")] = time;
|
||||
|
||||
// You can get a String from a JsonObject or JsonArray:
|
||||
// You can get the content of a JsonVariant as a String
|
||||
// No duplication is done, at least not in the JsonDocument.
|
||||
String sensor = obj["sensor"];
|
||||
String sensor = doc["sensor"];
|
||||
|
||||
// Unfortunately, the following doesn't work (issue #118):
|
||||
// sensor = obj["sensor"]; // <- error "ambiguous overload for 'operator='"
|
||||
// sensor = doc["sensor"]; // <- error "ambiguous overload for 'operator='"
|
||||
// As a workaround, you need to replace by:
|
||||
sensor = obj["sensor"].as<String>();
|
||||
sensor = doc["sensor"].as<String>();
|
||||
|
||||
// You can set a String to a JsonObject or JsonArray:
|
||||
// You can set a String as the content of a JsonVariant
|
||||
// WARNING: the content of the String will be duplicated in the JsonDocument.
|
||||
obj["sensor"] = sensor;
|
||||
doc["sensor"] = sensor;
|
||||
|
||||
// It works with serialized() too:
|
||||
obj["sensor"] = serialized(sensor);
|
||||
doc["sensor"] = serialized(sensor);
|
||||
|
||||
// You can also concatenate strings
|
||||
// WARNING: the content of the String will be duplicated in the JsonDocument.
|
||||
obj[String("sen") + "sor"] = String("gp") + "s";
|
||||
doc[String("sen") + "sor"] = String("gp") + "s";
|
||||
|
||||
// You can compare the content of a JsonObject with a String
|
||||
if (obj["sensor"] == sensor) {
|
||||
if (doc["sensor"] == sensor) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Lastly, you can print the resulting JSON to a String
|
||||
// WARNING: it doesn't replace the content but appends to it
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
-Wparentheses
|
||||
-Wredundant-decls
|
||||
-Wshadow
|
||||
-Wsign-conversion
|
||||
-Wsign-promo
|
||||
-Wstrict-aliasing
|
||||
-Wundef
|
||||
@ -92,3 +93,9 @@ if(MSVC)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
# Static link on MinGW to avoid linking with the wrong DLLs when multiple
|
||||
# versions are installed.
|
||||
add_link_options(-static)
|
||||
endif()
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
DynamicJsonDocument doc(4096);
|
||||
DeserializationError error = deserializeJson(doc, data, size);
|
||||
if (!error) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
DynamicJsonDocument doc(4096);
|
||||
DeserializationError error = deserializeMsgPack(doc, data, size);
|
||||
if (!error) {
|
||||
|
@ -18,6 +18,6 @@ rm -f "$OUTPUT"
|
||||
src \
|
||||
keywords.txt \
|
||||
library.properties \
|
||||
LICENSE.md \
|
||||
LICENSE.txt \
|
||||
README.md \
|
||||
ArduinoJson.h
|
||||
|
@ -9,7 +9,7 @@ trap 'rm -rf "$WORK_DIR"' EXIT
|
||||
cp "$SOURCE_DIR/README.md" "$WORK_DIR/README.md"
|
||||
cp "$SOURCE_DIR/CHANGELOG.md" "$WORK_DIR/CHANGELOG.md"
|
||||
cp "$SOURCE_DIR/library.properties" "$WORK_DIR/library.properties"
|
||||
cp "$SOURCE_DIR/LICENSE.md" "$WORK_DIR/LICENSE.txt"
|
||||
cp "$SOURCE_DIR/LICENSE.txt" "$WORK_DIR/LICENSE.txt"
|
||||
cp -r "$SOURCE_DIR/src" "$WORK_DIR/"
|
||||
cp -r "$SOURCE_DIR/examples" "$WORK_DIR/"
|
||||
|
||||
|
@ -38,6 +38,9 @@ update_version_in_source () {
|
||||
sed -i~ -bE "s/version: .*$/version: $VERSION.{build}/" appveyor.yml
|
||||
rm appveyor.yml~
|
||||
|
||||
sed -i~ -bE "s/^version: .*$/version: \"$VERSION\"/" idf_component.yml
|
||||
rm idf_component.yml~
|
||||
|
||||
sed -i~ -bE \
|
||||
-e "s/ARDUINOJSON_VERSION .*$/ARDUINOJSON_VERSION \"$VERSION\"/" \
|
||||
-e "s/ARDUINOJSON_VERSION_MAJOR .*$/ARDUINOJSON_VERSION_MAJOR $MAJOR/" \
|
||||
|
@ -15,6 +15,10 @@ if("cxx_long_long_type" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
list(APPEND SOURCES use_long_long_0.cpp use_long_long_1.cpp)
|
||||
endif()
|
||||
|
||||
if("cxx_range_for" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND "cxx_generalized_initializers" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
|
||||
list(APPEND SOURCES stl_containers.cpp)
|
||||
endif()
|
||||
|
||||
if(NOT SOURCES)
|
||||
return()
|
||||
endif()
|
||||
@ -28,5 +32,5 @@ add_test(Cpp11 Cpp11Tests)
|
||||
|
||||
set_tests_properties(Cpp11
|
||||
PROPERTIES
|
||||
LABELS "Catch"
|
||||
LABELS "Catch"
|
||||
)
|
||||
|
138
extras/tests/Cpp11/stl_containers.cpp
Normal file
138
extras/tests/Cpp11/stl_containers.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <stdint.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename T>
|
||||
struct Converter<std::vector<T> > {
|
||||
static void toJson(const std::vector<T>& src, JsonVariant dst) {
|
||||
JsonArray array = dst.to<JsonArray>();
|
||||
for (T item : src)
|
||||
array.add(item);
|
||||
}
|
||||
|
||||
static std::vector<T> fromJson(JsonVariantConst src) {
|
||||
std::vector<T> dst;
|
||||
for (T item : src.as<JsonArrayConst>())
|
||||
dst.push_back(item);
|
||||
return dst;
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
JsonArrayConst array = src;
|
||||
bool result = array;
|
||||
for (JsonVariantConst item : array)
|
||||
result &= item.is<T>();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct Converter<std::array<T, N> > {
|
||||
static void toJson(const std::array<T, N>& src, JsonVariant dst) {
|
||||
JsonArray array = dst.to<JsonArray>();
|
||||
for (T item : src)
|
||||
array.add(item);
|
||||
}
|
||||
|
||||
static std::array<T, N> fromJson(JsonVariantConst src) {
|
||||
std::array<T, N> dst;
|
||||
dst.fill(0);
|
||||
size_t idx = 0;
|
||||
for (T item : src.as<JsonArrayConst>())
|
||||
dst[idx++] = item;
|
||||
return dst;
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
JsonArrayConst array = src;
|
||||
bool result = array;
|
||||
size_t size = 0;
|
||||
for (JsonVariantConst item : array) {
|
||||
result &= item.is<T>();
|
||||
size++;
|
||||
}
|
||||
return result && size == N;
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
TEST_CASE("vector<int>") {
|
||||
SECTION("toJson") {
|
||||
std::vector<int> v = {1, 2};
|
||||
|
||||
StaticJsonDocument<128> doc;
|
||||
doc.set(v);
|
||||
REQUIRE(doc.as<std::string>() == "[1,2]");
|
||||
}
|
||||
|
||||
SECTION("fromJson") {
|
||||
StaticJsonDocument<128> doc;
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
|
||||
auto v = doc.as<std::vector<int> >();
|
||||
REQUIRE(v.size() == 2);
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
}
|
||||
|
||||
SECTION("checkJson") {
|
||||
StaticJsonDocument<128> doc;
|
||||
CHECK(doc.is<std::vector<int> >() == false);
|
||||
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
CHECK(doc.is<std::vector<int> >() == true);
|
||||
|
||||
doc.add("foo");
|
||||
CHECK(doc.is<std::vector<int> >() == false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("array<int, 2>") {
|
||||
typedef std::array<int, 2> array_type;
|
||||
|
||||
SECTION("toJson") {
|
||||
array_type v;
|
||||
v[0] = 1;
|
||||
v[1] = 2;
|
||||
|
||||
StaticJsonDocument<128> doc;
|
||||
doc.set(v);
|
||||
REQUIRE(doc.as<std::string>() == "[1,2]");
|
||||
}
|
||||
|
||||
SECTION("fromJson") {
|
||||
StaticJsonDocument<128> doc;
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
|
||||
auto v = doc.as<array_type>();
|
||||
REQUIRE(v.size() == 2);
|
||||
CHECK(v[0] == 1);
|
||||
CHECK(v[1] == 2);
|
||||
}
|
||||
|
||||
SECTION("checkJson") {
|
||||
StaticJsonDocument<128> doc;
|
||||
CHECK(doc.is<array_type>() == false);
|
||||
|
||||
doc.add(1);
|
||||
CHECK(doc.is<array_type>() == false);
|
||||
|
||||
doc.add(2);
|
||||
CHECK(doc.is<array_type>() == true);
|
||||
|
||||
doc[0] = "foo";
|
||||
CHECK(doc.is<array_type>() == false);
|
||||
}
|
||||
}
|
@ -7,6 +7,5 @@
|
||||
#include "api/Print.h"
|
||||
#include "api/Stream.h"
|
||||
#include "api/String.h"
|
||||
#include "progmem_emulation.hpp"
|
||||
|
||||
#define ARDUINO_H_INCLUDED 1
|
||||
|
@ -62,7 +62,7 @@ class String {
|
||||
size_t _maxCapacity;
|
||||
};
|
||||
|
||||
class StringSumHelper;
|
||||
class StringSumHelper : public ::String {};
|
||||
|
||||
inline bool operator==(const std::string& lhs, const ::String& rhs) {
|
||||
return lhs == rhs.c_str();
|
||||
|
@ -2,13 +2,13 @@
|
||||
# Copyright © 2014-2022, Benoit BLANCHON
|
||||
# MIT License
|
||||
|
||||
add_executable(JsonArrayTests
|
||||
add_executable(JsonArrayTests
|
||||
add.cpp
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
copyArray.cpp
|
||||
createNested.cpp
|
||||
equals.cpp
|
||||
get.cpp
|
||||
isNull.cpp
|
||||
iterator.cpp
|
||||
memoryUsage.cpp
|
||||
|
@ -40,7 +40,7 @@ TEST_CASE("JsonArray::add()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("vla") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
|
512
extras/tests/JsonArray/compare.cpp
Normal file
512
extras/tests/JsonArray/compare.cpp
Normal file
@ -0,0 +1,512 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("Compare JsonArray with JsonArray") {
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
JsonArray unbound;
|
||||
|
||||
CHECK(array != unbound);
|
||||
CHECK_FALSE(array == unbound);
|
||||
CHECK_FALSE(array <= unbound);
|
||||
CHECK_FALSE(array >= unbound);
|
||||
CHECK_FALSE(array > unbound);
|
||||
CHECK_FALSE(array < unbound);
|
||||
|
||||
CHECK(unbound != array);
|
||||
CHECK_FALSE(unbound == array);
|
||||
CHECK_FALSE(unbound <= array);
|
||||
CHECK_FALSE(unbound >= array);
|
||||
CHECK_FALSE(unbound > array);
|
||||
CHECK_FALSE(unbound < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
|
||||
CHECK(array == array);
|
||||
CHECK(array <= array);
|
||||
CHECK(array >= array);
|
||||
CHECK_FALSE(array != array);
|
||||
CHECK_FALSE(array > array);
|
||||
CHECK_FALSE(array < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello");
|
||||
array1.createNestedObject();
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello");
|
||||
array2.createNestedObject();
|
||||
|
||||
CHECK(array1 == array2);
|
||||
CHECK(array1 <= array2);
|
||||
CHECK(array1 >= array2);
|
||||
CHECK_FALSE(array1 != array2);
|
||||
CHECK_FALSE(array1 > array2);
|
||||
CHECK_FALSE(array1 < array2);
|
||||
}
|
||||
|
||||
SECTION("Compare with different array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello1");
|
||||
array1.createNestedObject();
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello2");
|
||||
array2.createNestedObject();
|
||||
|
||||
CHECK(array1 != array2);
|
||||
CHECK_FALSE(array1 == array2);
|
||||
CHECK_FALSE(array1 > array2);
|
||||
CHECK_FALSE(array1 < array2);
|
||||
CHECK_FALSE(array1 <= array2);
|
||||
CHECK_FALSE(array1 >= array2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonArray with JsonVariant") {
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
|
||||
JsonVariant variant = array;
|
||||
|
||||
CHECK(array == variant);
|
||||
CHECK(array <= variant);
|
||||
CHECK(array >= variant);
|
||||
CHECK_FALSE(array != variant);
|
||||
CHECK_FALSE(array > variant);
|
||||
CHECK_FALSE(array < variant);
|
||||
|
||||
CHECK(variant == array);
|
||||
CHECK(variant <= array);
|
||||
CHECK(variant >= array);
|
||||
CHECK_FALSE(variant != array);
|
||||
CHECK_FALSE(variant > array);
|
||||
CHECK_FALSE(variant < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical array") {
|
||||
JsonArray array = doc.createNestedArray();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
array.createNestedObject();
|
||||
|
||||
JsonVariant variant = doc.createNestedArray();
|
||||
variant.add(1);
|
||||
variant.add("hello");
|
||||
variant.createNestedObject();
|
||||
|
||||
CHECK(array == variant);
|
||||
CHECK(array <= variant);
|
||||
CHECK(array >= variant);
|
||||
CHECK_FALSE(array != variant);
|
||||
CHECK_FALSE(array > variant);
|
||||
CHECK_FALSE(array < variant);
|
||||
|
||||
CHECK(variant == array);
|
||||
CHECK(variant <= array);
|
||||
CHECK(variant >= array);
|
||||
CHECK_FALSE(variant != array);
|
||||
CHECK_FALSE(variant > array);
|
||||
CHECK_FALSE(variant < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with different array") {
|
||||
JsonArray array = doc.createNestedArray();
|
||||
array.add(1);
|
||||
array.add("hello1");
|
||||
array.createNestedObject();
|
||||
|
||||
JsonVariant variant = doc.createNestedArray();
|
||||
variant.add(1);
|
||||
variant.add("hello2");
|
||||
variant.createNestedObject();
|
||||
|
||||
CHECK(array != variant);
|
||||
CHECK_FALSE(array == variant);
|
||||
CHECK_FALSE(array > variant);
|
||||
CHECK_FALSE(array < variant);
|
||||
CHECK_FALSE(array <= variant);
|
||||
CHECK_FALSE(array >= variant);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonArray with JsonVariantConst") {
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
JsonVariantConst unbound;
|
||||
|
||||
CHECK(array != unbound);
|
||||
CHECK_FALSE(array == unbound);
|
||||
CHECK_FALSE(array <= unbound);
|
||||
CHECK_FALSE(array >= unbound);
|
||||
CHECK_FALSE(array > unbound);
|
||||
CHECK_FALSE(array < unbound);
|
||||
|
||||
CHECK(unbound != array);
|
||||
CHECK_FALSE(unbound == array);
|
||||
CHECK_FALSE(unbound <= array);
|
||||
CHECK_FALSE(unbound >= array);
|
||||
CHECK_FALSE(unbound > array);
|
||||
CHECK_FALSE(unbound < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
|
||||
JsonVariantConst variant = array;
|
||||
|
||||
CHECK(array == variant);
|
||||
CHECK(array <= variant);
|
||||
CHECK(array >= variant);
|
||||
CHECK_FALSE(array != variant);
|
||||
CHECK_FALSE(array > variant);
|
||||
CHECK_FALSE(array < variant);
|
||||
|
||||
CHECK(variant == array);
|
||||
CHECK(variant <= array);
|
||||
CHECK(variant >= array);
|
||||
CHECK_FALSE(variant != array);
|
||||
CHECK_FALSE(variant > array);
|
||||
CHECK_FALSE(variant < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical array") {
|
||||
JsonArray array = doc.createNestedArray();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
array.createNestedObject();
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello");
|
||||
array2.createNestedObject();
|
||||
JsonVariantConst variant = array2;
|
||||
|
||||
CHECK(array == variant);
|
||||
CHECK(array <= variant);
|
||||
CHECK(array >= variant);
|
||||
CHECK_FALSE(array != variant);
|
||||
CHECK_FALSE(array > variant);
|
||||
CHECK_FALSE(array < variant);
|
||||
|
||||
CHECK(variant == array);
|
||||
CHECK(variant <= array);
|
||||
CHECK(variant >= array);
|
||||
CHECK_FALSE(variant != array);
|
||||
CHECK_FALSE(variant > array);
|
||||
CHECK_FALSE(variant < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with different array") {
|
||||
JsonArray array = doc.createNestedArray();
|
||||
array.add(1);
|
||||
array.add("hello1");
|
||||
array.createNestedObject();
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello2");
|
||||
array2.createNestedObject();
|
||||
JsonVariantConst variant = array2;
|
||||
|
||||
CHECK(array != variant);
|
||||
CHECK_FALSE(array == variant);
|
||||
CHECK_FALSE(array > variant);
|
||||
CHECK_FALSE(array < variant);
|
||||
CHECK_FALSE(array <= variant);
|
||||
CHECK_FALSE(array >= variant);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonArray with JsonArrayConst") {
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
JsonArrayConst unbound;
|
||||
|
||||
CHECK(array != unbound);
|
||||
CHECK_FALSE(array == unbound);
|
||||
CHECK_FALSE(array <= unbound);
|
||||
CHECK_FALSE(array >= unbound);
|
||||
CHECK_FALSE(array > unbound);
|
||||
CHECK_FALSE(array < unbound);
|
||||
|
||||
CHECK(unbound != array);
|
||||
CHECK_FALSE(unbound == array);
|
||||
CHECK_FALSE(unbound <= array);
|
||||
CHECK_FALSE(unbound >= array);
|
||||
CHECK_FALSE(unbound > array);
|
||||
CHECK_FALSE(unbound < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
JsonArrayConst carray = array;
|
||||
|
||||
CHECK(array == carray);
|
||||
CHECK(array <= carray);
|
||||
CHECK(array >= carray);
|
||||
CHECK_FALSE(array != carray);
|
||||
CHECK_FALSE(array > carray);
|
||||
CHECK_FALSE(array < carray);
|
||||
|
||||
CHECK(carray == array);
|
||||
CHECK(carray <= array);
|
||||
CHECK(carray >= array);
|
||||
CHECK_FALSE(carray != array);
|
||||
CHECK_FALSE(carray > array);
|
||||
CHECK_FALSE(carray < array);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello");
|
||||
array1.createNestedObject();
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello");
|
||||
array2.createNestedObject();
|
||||
JsonArrayConst carray2 = array2;
|
||||
|
||||
CHECK(array1 == carray2);
|
||||
CHECK(array1 <= carray2);
|
||||
CHECK(array1 >= carray2);
|
||||
CHECK_FALSE(array1 != carray2);
|
||||
CHECK_FALSE(array1 > carray2);
|
||||
CHECK_FALSE(array1 < carray2);
|
||||
|
||||
CHECK(carray2 == array1);
|
||||
CHECK(carray2 <= array1);
|
||||
CHECK(carray2 >= array1);
|
||||
CHECK_FALSE(carray2 != array1);
|
||||
CHECK_FALSE(carray2 > array1);
|
||||
CHECK_FALSE(carray2 < array1);
|
||||
}
|
||||
|
||||
SECTION("Compare with different array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello1");
|
||||
array1.createNestedObject();
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello2");
|
||||
array2.createNestedObject();
|
||||
JsonArrayConst carray2 = array2;
|
||||
|
||||
CHECK(array1 != carray2);
|
||||
CHECK_FALSE(array1 == carray2);
|
||||
CHECK_FALSE(array1 > carray2);
|
||||
CHECK_FALSE(array1 < carray2);
|
||||
CHECK_FALSE(array1 <= carray2);
|
||||
CHECK_FALSE(array1 >= carray2);
|
||||
|
||||
CHECK(carray2 != array1);
|
||||
CHECK_FALSE(carray2 == array1);
|
||||
CHECK_FALSE(carray2 > array1);
|
||||
CHECK_FALSE(carray2 < array1);
|
||||
CHECK_FALSE(carray2 <= array1);
|
||||
CHECK_FALSE(carray2 >= array1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonArrayConst with JsonArrayConst") {
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
|
||||
JsonArrayConst carray = array;
|
||||
JsonArrayConst unbound;
|
||||
|
||||
CHECK(carray != unbound);
|
||||
CHECK_FALSE(carray == unbound);
|
||||
CHECK_FALSE(carray <= unbound);
|
||||
CHECK_FALSE(carray >= unbound);
|
||||
CHECK_FALSE(carray > unbound);
|
||||
CHECK_FALSE(carray < unbound);
|
||||
|
||||
CHECK(unbound != carray);
|
||||
CHECK_FALSE(unbound == carray);
|
||||
CHECK_FALSE(unbound <= carray);
|
||||
CHECK_FALSE(unbound >= carray);
|
||||
CHECK_FALSE(unbound > carray);
|
||||
CHECK_FALSE(unbound < carray);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
JsonArrayConst carray = array;
|
||||
|
||||
CHECK(carray == carray);
|
||||
CHECK(carray <= carray);
|
||||
CHECK(carray >= carray);
|
||||
CHECK_FALSE(carray != carray);
|
||||
CHECK_FALSE(carray > carray);
|
||||
CHECK_FALSE(carray < carray);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello");
|
||||
array1.createNestedObject();
|
||||
JsonArrayConst carray1 = array1;
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello");
|
||||
array2.createNestedObject();
|
||||
JsonArrayConst carray2 = array2;
|
||||
|
||||
CHECK(carray1 == carray2);
|
||||
CHECK(carray1 <= carray2);
|
||||
CHECK(carray1 >= carray2);
|
||||
CHECK_FALSE(carray1 != carray2);
|
||||
CHECK_FALSE(carray1 > carray2);
|
||||
CHECK_FALSE(carray1 < carray2);
|
||||
}
|
||||
|
||||
SECTION("Compare with different array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello1");
|
||||
array1.createNestedObject();
|
||||
JsonArrayConst carray1 = array1;
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello2");
|
||||
array2.createNestedObject();
|
||||
JsonArrayConst carray2 = array2;
|
||||
|
||||
CHECK(carray1 != carray2);
|
||||
CHECK_FALSE(carray1 == carray2);
|
||||
CHECK_FALSE(carray1 > carray2);
|
||||
CHECK_FALSE(carray1 < carray2);
|
||||
CHECK_FALSE(carray1 <= carray2);
|
||||
CHECK_FALSE(carray1 >= carray2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonArrayConst with JsonVariant") {
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(1);
|
||||
array.add("hello");
|
||||
JsonArrayConst carray = array;
|
||||
JsonVariant variant = array;
|
||||
|
||||
CHECK(carray == variant);
|
||||
CHECK(carray <= variant);
|
||||
CHECK(carray >= variant);
|
||||
CHECK_FALSE(carray != variant);
|
||||
CHECK_FALSE(carray > variant);
|
||||
CHECK_FALSE(carray < variant);
|
||||
|
||||
CHECK(variant == carray);
|
||||
CHECK(variant <= carray);
|
||||
CHECK(variant >= carray);
|
||||
CHECK_FALSE(variant != carray);
|
||||
CHECK_FALSE(variant > carray);
|
||||
CHECK_FALSE(variant < carray);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello");
|
||||
array1.createNestedObject();
|
||||
JsonArrayConst carray1 = array1;
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello");
|
||||
array2.createNestedObject();
|
||||
JsonVariant variant2 = array2;
|
||||
|
||||
CHECK(carray1 == variant2);
|
||||
CHECK(carray1 <= variant2);
|
||||
CHECK(carray1 >= variant2);
|
||||
CHECK_FALSE(carray1 != variant2);
|
||||
CHECK_FALSE(carray1 > variant2);
|
||||
CHECK_FALSE(carray1 < variant2);
|
||||
|
||||
CHECK(variant2 == carray1);
|
||||
CHECK(variant2 <= carray1);
|
||||
CHECK(variant2 >= carray1);
|
||||
CHECK_FALSE(variant2 != carray1);
|
||||
CHECK_FALSE(variant2 > carray1);
|
||||
CHECK_FALSE(variant2 < carray1);
|
||||
}
|
||||
|
||||
SECTION("Compare with different array") {
|
||||
JsonArray array1 = doc.createNestedArray();
|
||||
array1.add(1);
|
||||
array1.add("hello1");
|
||||
array1.createNestedObject();
|
||||
JsonArrayConst carray1 = array1;
|
||||
|
||||
JsonArray array2 = doc.createNestedArray();
|
||||
array2.add(1);
|
||||
array2.add("hello2");
|
||||
array2.createNestedObject();
|
||||
JsonVariant variant2 = array2;
|
||||
|
||||
CHECK(carray1 != variant2);
|
||||
CHECK_FALSE(carray1 == variant2);
|
||||
CHECK_FALSE(carray1 > variant2);
|
||||
CHECK_FALSE(carray1 < variant2);
|
||||
CHECK_FALSE(carray1 <= variant2);
|
||||
CHECK_FALSE(carray1 >= variant2);
|
||||
|
||||
CHECK(variant2 != carray1);
|
||||
CHECK_FALSE(variant2 == carray1);
|
||||
CHECK_FALSE(variant2 > carray1);
|
||||
CHECK_FALSE(variant2 < carray1);
|
||||
CHECK_FALSE(variant2 <= carray1);
|
||||
CHECK_FALSE(variant2 >= carray1);
|
||||
}
|
||||
}
|
@ -165,7 +165,7 @@ TEST_CASE("copyArray()") {
|
||||
char json[32] = "";
|
||||
int source[][3] = {{1, 2, 3}, {4, 5, 6}};
|
||||
|
||||
CAPTURE(SIZE)
|
||||
CAPTURE(SIZE);
|
||||
|
||||
bool ok = copyArray(source, array);
|
||||
CAPTURE(doc.memoryUsage());
|
||||
|
@ -1,16 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonArray::get()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
deserializeJson(doc, "[1,2,3]");
|
||||
JsonArray array = doc.as<JsonArray>();
|
||||
|
||||
SECTION("Overflow") {
|
||||
REQUIRE(array.getElement(3).isNull());
|
||||
}
|
||||
}
|
@ -5,9 +5,10 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
static void eraseString(std::string &str) {
|
||||
char *p = const_cast<char *>(str.c_str());
|
||||
while (*p) *p++ = '*';
|
||||
static void eraseString(std::string& str) {
|
||||
char* p = const_cast<char*>(str.c_str());
|
||||
while (*p)
|
||||
*p++ = '*';
|
||||
}
|
||||
|
||||
TEST_CASE("std::string") {
|
||||
|
@ -135,7 +135,7 @@ TEST_CASE("JsonArray::operator[]") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("set(VLA)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
@ -146,7 +146,7 @@ TEST_CASE("JsonArray::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("operator=(VLA)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
|
@ -71,6 +71,15 @@ TEST_CASE("Filtering") {
|
||||
"{\"example\":null}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// Member is a number, but filter wants an array
|
||||
"{\"example\":42}",
|
||||
"{\"example\":[true]}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":null}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// Input is an array, but filter wants an object
|
||||
"[\"hello\",\"world\"]",
|
||||
@ -117,7 +126,7 @@ TEST_CASE("Filtering") {
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip a boolean
|
||||
// skip false
|
||||
"{\"a_bool\":false,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
@ -125,6 +134,24 @@ TEST_CASE("Filtering") {
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// skip true
|
||||
"{\"a_bool\":true,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// skip null
|
||||
"{\"a_bool\":null,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip a double-quoted string
|
||||
"{\"a_double_quoted_string\":\"hello\",example:42}",
|
||||
@ -366,7 +393,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up element error even if array is skipped
|
||||
// bubble up element error even if array is skipped
|
||||
"[1,'2,3]",
|
||||
"false",
|
||||
10,
|
||||
@ -375,7 +402,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up member error even if object is skipped
|
||||
// bubble up member error even if object is skipped
|
||||
"{'hello':'worl}",
|
||||
"false",
|
||||
10,
|
||||
@ -384,7 +411,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up colon error even if object is skipped
|
||||
// bubble up colon error even if object is skipped
|
||||
"{'hello','world'}",
|
||||
"false",
|
||||
10,
|
||||
@ -393,7 +420,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up key error even if object is skipped
|
||||
// bubble up key error even if object is skipped
|
||||
"{'hello:1}",
|
||||
"false",
|
||||
10,
|
||||
@ -404,7 +431,7 @@ TEST_CASE("Filtering") {
|
||||
{
|
||||
// detect invalid value in skipped object
|
||||
"{'hello':!}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
@ -413,235 +440,244 @@ TEST_CASE("Filtering") {
|
||||
{
|
||||
// ignore invalid value in skipped object
|
||||
"{'hello':\\}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored objects
|
||||
"{}",
|
||||
"false",
|
||||
"false",
|
||||
0,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored objects
|
||||
"{'hello':{}}",
|
||||
"false",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored values in objects
|
||||
"{'hello':{}}",
|
||||
"{}",
|
||||
"{}",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored arrays
|
||||
"[]",
|
||||
"false",
|
||||
"false",
|
||||
0,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored arrays
|
||||
"[[]]",
|
||||
"false",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored values in arrays
|
||||
"[[]]",
|
||||
"[]",
|
||||
"[]",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"[]",
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// supports back-slash at the end of skipped string
|
||||
"\"hell\\",
|
||||
"false",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment at after an element in a skipped array
|
||||
"[1/]",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete comment at after an element in a skipped array
|
||||
"[1/*]",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// missing comma in a skipped array
|
||||
"[1 2]",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment at the beginning of array
|
||||
"[/1]",
|
||||
"[false]",
|
||||
"[false]",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"[]",
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment at the begining of an array
|
||||
"[/*]",
|
||||
"[false]",
|
||||
"[false]",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"[]",
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment before key
|
||||
"{/1:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment before key
|
||||
"{/*:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment after key
|
||||
"{\"example\"/1:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment after key
|
||||
"{\"example\"/*:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment after colon
|
||||
"{\"example\":/12}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment after colon
|
||||
"{\"example\":/*2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// comment next to an integer
|
||||
"{\"ignore\":1//,\"example\":2\n}",
|
||||
"{\"example\":true}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment after opening brace of a skipped object
|
||||
"{/1:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete after opening brace of a skipped object
|
||||
"{/*:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment after key of a skipped object
|
||||
"{\"example\"/:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete after after key of a skipped object
|
||||
// incomplete comment after key of a skipped object
|
||||
"{\"example\"/*:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment after value in a skipped object
|
||||
"{\"example\":2/}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete after after value of a skipped object
|
||||
// incomplete comment after value of a skipped object
|
||||
"{\"example\":2/*}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete comment after comma in skipped object
|
||||
"{\"example\":2,/*}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
}; // clang-format on
|
||||
@ -708,7 +744,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, Filter(filter));
|
||||
@ -736,7 +772,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter, NestingLimit") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, Filter(filter), NestingLimit(5));
|
||||
@ -764,7 +800,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], NestingLimit, Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, NestingLimit(5), Filter(filter));
|
||||
|
@ -121,7 +121,7 @@ TEST_CASE("deserializeJson(std::istream&)") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
TEST_CASE("deserializeJson(VLA)") {
|
||||
int i = 9;
|
||||
size_t i = 9;
|
||||
char vla[i];
|
||||
strcpy(vla, "{\"a\":42}");
|
||||
|
||||
|
@ -9,7 +9,8 @@
|
||||
TEST_CASE("Invalid JSON input") {
|
||||
const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'", "'\\u000G'",
|
||||
"'\\u000/'", "\\x1234", "6a9", "1,",
|
||||
"2]", "3}"};
|
||||
"nulL", "tru3", "fals3", "2]",
|
||||
"3}"};
|
||||
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
|
||||
|
||||
DynamicJsonDocument doc(4096);
|
||||
@ -23,9 +24,6 @@ TEST_CASE("Invalid JSON input") {
|
||||
|
||||
TEST_CASE("Invalid JSON input that should pass") {
|
||||
const char* testCases[] = {
|
||||
"nulL",
|
||||
"tru3",
|
||||
"fals3",
|
||||
"'\\ud83d'", // leading surrogate without a trailing surrogate
|
||||
"'\\udda4'", // trailing surrogate without a leading surrogate
|
||||
"'\\ud83d\\ud83d'", // two leading surrogates
|
||||
|
@ -100,7 +100,7 @@ TEST_CASE("deserialize JSON object") {
|
||||
REQUIRE(obj["key"] == "value");
|
||||
}
|
||||
|
||||
SECTION("Before the colon") {
|
||||
SECTION("Before the comma") {
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
@ -112,9 +112,9 @@ TEST_CASE("deserialize JSON object") {
|
||||
REQUIRE(obj["key2"] == "value2");
|
||||
}
|
||||
|
||||
SECTION("After the colon") {
|
||||
SECTION("After the comma") {
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
|
||||
deserializeJson(doc, "{\"key1\":\"value1\", \"key2\":\"value2\"}");
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
|
@ -5,6 +5,7 @@
|
||||
add_executable(JsonDocumentTests
|
||||
add.cpp
|
||||
BasicJsonDocument.cpp
|
||||
cast.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
createNested.cpp
|
||||
|
@ -205,4 +205,26 @@ TEST_CASE("DynamicJsonDocument assignment") {
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from MemberProxy") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
doc1["value"] = 42;
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1["value"];
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from ElementProxy") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
doc1[0] = 42;
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1[0];
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
}
|
||||
|
@ -5,12 +5,12 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
typedef ARDUINOJSON_NAMESPACE::ElementProxy<JsonDocument&> ElementProxy;
|
||||
|
||||
TEST_CASE("ElementProxy::add()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("add(int)") {
|
||||
ep.add(42);
|
||||
@ -35,8 +35,8 @@ TEST_CASE("ElementProxy::add()") {
|
||||
|
||||
TEST_CASE("ElementProxy::clear()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("size goes back to zero") {
|
||||
ep.add(42);
|
||||
@ -95,8 +95,8 @@ TEST_CASE("ElementProxy::operator==()") {
|
||||
|
||||
TEST_CASE("ElementProxy::remove()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("remove(int)") {
|
||||
ep.add(1);
|
||||
@ -131,7 +131,7 @@ TEST_CASE("ElementProxy::remove()") {
|
||||
ep["a"] = 1;
|
||||
ep["b"] = 2;
|
||||
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
ep.remove(vla);
|
||||
@ -143,7 +143,7 @@ TEST_CASE("ElementProxy::remove()") {
|
||||
|
||||
TEST_CASE("ElementProxy::set()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("set(int)") {
|
||||
ep.set(42);
|
||||
@ -168,8 +168,8 @@ TEST_CASE("ElementProxy::set()") {
|
||||
|
||||
TEST_CASE("ElementProxy::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("returns 0") {
|
||||
REQUIRE(ep.size() == 0);
|
||||
@ -188,9 +188,24 @@ TEST_CASE("ElementProxy::size()") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::memoryUsage()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("returns 0 for null") {
|
||||
REQUIRE(ep.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("returns size for string") {
|
||||
ep.set(std::string("hello"));
|
||||
REQUIRE(ep.memoryUsage() == 6);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy<JsonDocument&> ep = doc[1];
|
||||
ElementProxy ep = doc[1];
|
||||
|
||||
SECTION("set member") {
|
||||
ep["world"] = 42;
|
||||
@ -204,3 +219,37 @@ TEST_CASE("ElementProxy::operator[]") {
|
||||
REQUIRE(doc.as<std::string>() == "[null,[null,null,42]]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy cast to JsonVariantConst") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc[0] = "world";
|
||||
|
||||
const ElementProxy ep = doc[0];
|
||||
|
||||
JsonVariantConst var = ep;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy cast to JsonVariant") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc[0] = "world";
|
||||
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
JsonVariant var = ep;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
|
||||
var.set("toto");
|
||||
|
||||
CHECK(doc.as<std::string>() == "[\"toto\"]");
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::shallowCopy()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
doc2["hello"] = "world";
|
||||
doc1[0].shallowCopy(doc2);
|
||||
|
||||
CHECK(doc1.as<std::string>() == "[{\"hello\":\"world\"}]");
|
||||
}
|
||||
|
@ -5,11 +5,12 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
typedef ARDUINOJSON_NAMESPACE::MemberProxy<JsonDocument&, const char*>
|
||||
MemberProxy;
|
||||
|
||||
TEST_CASE("MemberProxy::add()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("add(int)") {
|
||||
mp.add(42);
|
||||
@ -26,7 +27,7 @@ TEST_CASE("MemberProxy::add()") {
|
||||
|
||||
TEST_CASE("MemberProxy::clear()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("size goes back to zero") {
|
||||
mp.add(42);
|
||||
@ -85,7 +86,7 @@ TEST_CASE("MemberProxy::operator==()") {
|
||||
|
||||
TEST_CASE("MemberProxy::containsKey()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("containsKey(const char*)") {
|
||||
mp["key"] = "value";
|
||||
@ -115,9 +116,9 @@ TEST_CASE("MemberProxy::operator|()") {
|
||||
SECTION("Issue #1411") {
|
||||
doc["sensor"] = "gps";
|
||||
|
||||
const char *test = "test"; // <- the literal must be captured in a variable
|
||||
const char* test = "test"; // <- the literal must be captured in a variable
|
||||
// to trigger the bug
|
||||
const char *sensor = doc["sensor"] | test; // "gps"
|
||||
const char* sensor = doc["sensor"] | test; // "gps"
|
||||
|
||||
REQUIRE(sensor == std::string("gps"));
|
||||
}
|
||||
@ -136,7 +137,7 @@ TEST_CASE("MemberProxy::operator|()") {
|
||||
|
||||
TEST_CASE("MemberProxy::remove()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("remove(int)") {
|
||||
mp.add(1);
|
||||
@ -171,7 +172,7 @@ TEST_CASE("MemberProxy::remove()") {
|
||||
mp["a"] = 1;
|
||||
mp["b"] = 2;
|
||||
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
mp.remove(vla);
|
||||
@ -183,7 +184,7 @@ TEST_CASE("MemberProxy::remove()") {
|
||||
|
||||
TEST_CASE("MemberProxy::set()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("set(int)") {
|
||||
mp.set(42);
|
||||
@ -208,7 +209,7 @@ TEST_CASE("MemberProxy::set()") {
|
||||
|
||||
TEST_CASE("MemberProxy::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("returns 0") {
|
||||
REQUIRE(mp.size() == 0);
|
||||
@ -229,9 +230,23 @@ TEST_CASE("MemberProxy::size()") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::memoryUsage()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("returns 0 when null") {
|
||||
REQUIRE(mp.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("return the size for a string") {
|
||||
mp.set(std::string("hello"));
|
||||
REQUIRE(mp.memoryUsage() == 6);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("set member") {
|
||||
mp["world"] = 42;
|
||||
@ -245,3 +260,69 @@ TEST_CASE("MemberProxy::operator[]") {
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":[null,null,42]}");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy cast to JsonVariantConst") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc["hello"] = "world";
|
||||
|
||||
const MemberProxy mp = doc["hello"];
|
||||
|
||||
JsonVariantConst var = mp;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy cast to JsonVariant") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc["hello"] = "world";
|
||||
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
JsonVariant var = mp;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
|
||||
var.set("toto");
|
||||
|
||||
CHECK(doc.as<std::string>() == "{\"hello\":\"toto\"}");
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedArray()") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonArray arr = doc["items"].createNestedArray();
|
||||
arr.add(42);
|
||||
|
||||
CHECK(doc["items"][0][0] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedArray(key)") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonArray arr = doc["weather"].createNestedArray("temp");
|
||||
arr.add(42);
|
||||
|
||||
CHECK(doc["weather"]["temp"][0] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedObject()") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonObject obj = doc["items"].createNestedObject();
|
||||
obj["value"] = 42;
|
||||
|
||||
CHECK(doc["items"][0]["value"] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedObject(key)") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonObject obj = doc["status"].createNestedObject("weather");
|
||||
obj["temp"] = 42;
|
||||
|
||||
CHECK(doc["status"]["weather"]["temp"] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::shallowCopy()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
doc2["hello"] = "world";
|
||||
doc1["obj"].shallowCopy(doc2);
|
||||
|
||||
CHECK(doc1.as<std::string>() == "{\"obj\":{\"hello\":\"world\"}}");
|
||||
}
|
||||
|
18
extras/tests/JsonDocument/cast.cpp
Normal file
18
extras/tests/JsonDocument/cast.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("Implicit cast to JsonVariant") {
|
||||
StaticJsonDocument<128> doc;
|
||||
|
||||
doc["hello"] = "world";
|
||||
|
||||
JsonVariant var = doc;
|
||||
|
||||
CHECK(var.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
}
|
@ -75,3 +75,29 @@ TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") {
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument::operator==(const JsonDocument&)") {
|
||||
StaticJsonDocument<256> doc1;
|
||||
StaticJsonDocument<256> doc2;
|
||||
const JsonDocument& ref1 = doc1;
|
||||
const JsonDocument& ref2 = doc2;
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(ref1 == ref2);
|
||||
REQUIRE_FALSE(ref1 != ref2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(ref1 == ref2);
|
||||
REQUIRE_FALSE(ref1 != ref2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(ref1 == ref2);
|
||||
REQUIRE(ref1 != ref2);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ TEST_CASE("JsonDocument::remove()") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
doc.remove(vla);
|
||||
|
@ -2,8 +2,9 @@
|
||||
# Copyright © 2014-2022, Benoit BLANCHON
|
||||
# MIT License
|
||||
|
||||
add_executable(JsonObjectTests
|
||||
add_executable(JsonObjectTests
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
copy.cpp
|
||||
createNestedArray.cpp
|
||||
|
512
extras/tests/JsonObject/compare.cpp
Normal file
512
extras/tests/JsonObject/compare.cpp
Normal file
@ -0,0 +1,512 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("Compare JsonObject with JsonObject") {
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
JsonObject unbound;
|
||||
|
||||
CHECK(object != unbound);
|
||||
CHECK_FALSE(object == unbound);
|
||||
CHECK_FALSE(object <= unbound);
|
||||
CHECK_FALSE(object >= unbound);
|
||||
CHECK_FALSE(object > unbound);
|
||||
CHECK_FALSE(object < unbound);
|
||||
|
||||
CHECK(unbound != object);
|
||||
CHECK_FALSE(unbound == object);
|
||||
CHECK_FALSE(unbound <= object);
|
||||
CHECK_FALSE(unbound >= object);
|
||||
CHECK_FALSE(unbound > object);
|
||||
CHECK_FALSE(unbound < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
|
||||
CHECK(object == object);
|
||||
CHECK(object <= object);
|
||||
CHECK(object >= object);
|
||||
CHECK_FALSE(object != object);
|
||||
CHECK_FALSE(object > object);
|
||||
CHECK_FALSE(object < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello";
|
||||
object1["c"][0] = false;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello";
|
||||
object2["c"][0] = false;
|
||||
|
||||
CHECK(object1 == object2);
|
||||
CHECK(object1 <= object2);
|
||||
CHECK(object1 >= object2);
|
||||
CHECK_FALSE(object1 != object2);
|
||||
CHECK_FALSE(object1 > object2);
|
||||
CHECK_FALSE(object1 < object2);
|
||||
}
|
||||
|
||||
SECTION("Compare with different object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello1";
|
||||
object1["c"][0] = false;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello2";
|
||||
object2["c"][0] = false;
|
||||
|
||||
CHECK(object1 != object2);
|
||||
CHECK_FALSE(object1 == object2);
|
||||
CHECK_FALSE(object1 > object2);
|
||||
CHECK_FALSE(object1 < object2);
|
||||
CHECK_FALSE(object1 <= object2);
|
||||
CHECK_FALSE(object1 >= object2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonObject with JsonVariant") {
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
|
||||
JsonVariant variant = object;
|
||||
|
||||
CHECK(object == variant);
|
||||
CHECK(object <= variant);
|
||||
CHECK(object >= variant);
|
||||
CHECK_FALSE(object != variant);
|
||||
CHECK_FALSE(object > variant);
|
||||
CHECK_FALSE(object < variant);
|
||||
|
||||
CHECK(variant == object);
|
||||
CHECK(variant <= object);
|
||||
CHECK(variant >= object);
|
||||
CHECK_FALSE(variant != object);
|
||||
CHECK_FALSE(variant > object);
|
||||
CHECK_FALSE(variant < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical object") {
|
||||
JsonObject object = doc.createNestedObject();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
object["c"][0] = false;
|
||||
|
||||
JsonVariant variant = doc.createNestedObject();
|
||||
variant["a"] = 1;
|
||||
variant["b"] = "hello";
|
||||
variant["c"][0] = false;
|
||||
|
||||
CHECK(object == variant);
|
||||
CHECK(object <= variant);
|
||||
CHECK(object >= variant);
|
||||
CHECK_FALSE(object != variant);
|
||||
CHECK_FALSE(object > variant);
|
||||
CHECK_FALSE(object < variant);
|
||||
|
||||
CHECK(variant == object);
|
||||
CHECK(variant <= object);
|
||||
CHECK(variant >= object);
|
||||
CHECK_FALSE(variant != object);
|
||||
CHECK_FALSE(variant > object);
|
||||
CHECK_FALSE(variant < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with different object") {
|
||||
JsonObject object = doc.createNestedObject();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello1";
|
||||
object["c"][0] = false;
|
||||
|
||||
JsonVariant variant = doc.createNestedObject();
|
||||
variant["a"] = 1;
|
||||
variant["b"] = "hello2";
|
||||
variant["c"][0] = false;
|
||||
|
||||
CHECK(object != variant);
|
||||
CHECK_FALSE(object == variant);
|
||||
CHECK_FALSE(object > variant);
|
||||
CHECK_FALSE(object < variant);
|
||||
CHECK_FALSE(object <= variant);
|
||||
CHECK_FALSE(object >= variant);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonObject with JsonVariantConst") {
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
JsonVariantConst unbound;
|
||||
|
||||
CHECK(object != unbound);
|
||||
CHECK_FALSE(object == unbound);
|
||||
CHECK_FALSE(object <= unbound);
|
||||
CHECK_FALSE(object >= unbound);
|
||||
CHECK_FALSE(object > unbound);
|
||||
CHECK_FALSE(object < unbound);
|
||||
|
||||
CHECK(unbound != object);
|
||||
CHECK_FALSE(unbound == object);
|
||||
CHECK_FALSE(unbound <= object);
|
||||
CHECK_FALSE(unbound >= object);
|
||||
CHECK_FALSE(unbound > object);
|
||||
CHECK_FALSE(unbound < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
|
||||
JsonVariantConst variant = object;
|
||||
|
||||
CHECK(object == variant);
|
||||
CHECK(object <= variant);
|
||||
CHECK(object >= variant);
|
||||
CHECK_FALSE(object != variant);
|
||||
CHECK_FALSE(object > variant);
|
||||
CHECK_FALSE(object < variant);
|
||||
|
||||
CHECK(variant == object);
|
||||
CHECK(variant <= object);
|
||||
CHECK(variant >= object);
|
||||
CHECK_FALSE(variant != object);
|
||||
CHECK_FALSE(variant > object);
|
||||
CHECK_FALSE(variant < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical object") {
|
||||
JsonObject object = doc.createNestedObject();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
object["c"][0] = false;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello";
|
||||
object2["c"][0] = false;
|
||||
JsonVariantConst variant = object2;
|
||||
|
||||
CHECK(object == variant);
|
||||
CHECK(object <= variant);
|
||||
CHECK(object >= variant);
|
||||
CHECK_FALSE(object != variant);
|
||||
CHECK_FALSE(object > variant);
|
||||
CHECK_FALSE(object < variant);
|
||||
|
||||
CHECK(variant == object);
|
||||
CHECK(variant <= object);
|
||||
CHECK(variant >= object);
|
||||
CHECK_FALSE(variant != object);
|
||||
CHECK_FALSE(variant > object);
|
||||
CHECK_FALSE(variant < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with different object") {
|
||||
JsonObject object = doc.createNestedObject();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello1";
|
||||
object["c"][0] = false;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello2";
|
||||
object2["c"][0] = false;
|
||||
JsonVariantConst variant = object2;
|
||||
|
||||
CHECK(object != variant);
|
||||
CHECK_FALSE(object == variant);
|
||||
CHECK_FALSE(object > variant);
|
||||
CHECK_FALSE(object < variant);
|
||||
CHECK_FALSE(object <= variant);
|
||||
CHECK_FALSE(object >= variant);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonObject with JsonObjectConst") {
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
JsonObjectConst unbound;
|
||||
|
||||
CHECK(object != unbound);
|
||||
CHECK_FALSE(object == unbound);
|
||||
CHECK_FALSE(object <= unbound);
|
||||
CHECK_FALSE(object >= unbound);
|
||||
CHECK_FALSE(object > unbound);
|
||||
CHECK_FALSE(object < unbound);
|
||||
|
||||
CHECK(unbound != object);
|
||||
CHECK_FALSE(unbound == object);
|
||||
CHECK_FALSE(unbound <= object);
|
||||
CHECK_FALSE(unbound >= object);
|
||||
CHECK_FALSE(unbound > object);
|
||||
CHECK_FALSE(unbound < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
JsonObjectConst cobject = object;
|
||||
|
||||
CHECK(object == cobject);
|
||||
CHECK(object <= cobject);
|
||||
CHECK(object >= cobject);
|
||||
CHECK_FALSE(object != cobject);
|
||||
CHECK_FALSE(object > cobject);
|
||||
CHECK_FALSE(object < cobject);
|
||||
|
||||
CHECK(cobject == object);
|
||||
CHECK(cobject <= object);
|
||||
CHECK(cobject >= object);
|
||||
CHECK_FALSE(cobject != object);
|
||||
CHECK_FALSE(cobject > object);
|
||||
CHECK_FALSE(cobject < object);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello";
|
||||
object1["c"][0] = false;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello";
|
||||
object2["c"][0] = false;
|
||||
JsonObjectConst carray2 = object2;
|
||||
|
||||
CHECK(object1 == carray2);
|
||||
CHECK(object1 <= carray2);
|
||||
CHECK(object1 >= carray2);
|
||||
CHECK_FALSE(object1 != carray2);
|
||||
CHECK_FALSE(object1 > carray2);
|
||||
CHECK_FALSE(object1 < carray2);
|
||||
|
||||
CHECK(carray2 == object1);
|
||||
CHECK(carray2 <= object1);
|
||||
CHECK(carray2 >= object1);
|
||||
CHECK_FALSE(carray2 != object1);
|
||||
CHECK_FALSE(carray2 > object1);
|
||||
CHECK_FALSE(carray2 < object1);
|
||||
}
|
||||
|
||||
SECTION("Compare with different object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello1";
|
||||
object1["c"][0] = false;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello2";
|
||||
object2["c"][0] = false;
|
||||
JsonObjectConst carray2 = object2;
|
||||
|
||||
CHECK(object1 != carray2);
|
||||
CHECK_FALSE(object1 == carray2);
|
||||
CHECK_FALSE(object1 > carray2);
|
||||
CHECK_FALSE(object1 < carray2);
|
||||
CHECK_FALSE(object1 <= carray2);
|
||||
CHECK_FALSE(object1 >= carray2);
|
||||
|
||||
CHECK(carray2 != object1);
|
||||
CHECK_FALSE(carray2 == object1);
|
||||
CHECK_FALSE(carray2 > object1);
|
||||
CHECK_FALSE(carray2 < object1);
|
||||
CHECK_FALSE(carray2 <= object1);
|
||||
CHECK_FALSE(carray2 >= object1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonObjectConst with JsonObjectConst") {
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
SECTION("Compare with unbound") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
|
||||
JsonObjectConst cobject = object;
|
||||
JsonObjectConst unbound;
|
||||
|
||||
CHECK(cobject != unbound);
|
||||
CHECK_FALSE(cobject == unbound);
|
||||
CHECK_FALSE(cobject <= unbound);
|
||||
CHECK_FALSE(cobject >= unbound);
|
||||
CHECK_FALSE(cobject > unbound);
|
||||
CHECK_FALSE(cobject < unbound);
|
||||
|
||||
CHECK(unbound != cobject);
|
||||
CHECK_FALSE(unbound == cobject);
|
||||
CHECK_FALSE(unbound <= cobject);
|
||||
CHECK_FALSE(unbound >= cobject);
|
||||
CHECK_FALSE(unbound > cobject);
|
||||
CHECK_FALSE(unbound < cobject);
|
||||
}
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
JsonObjectConst cobject = object;
|
||||
|
||||
CHECK(cobject == cobject);
|
||||
CHECK(cobject <= cobject);
|
||||
CHECK(cobject >= cobject);
|
||||
CHECK_FALSE(cobject != cobject);
|
||||
CHECK_FALSE(cobject > cobject);
|
||||
CHECK_FALSE(cobject < cobject);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello";
|
||||
object1["c"][0] = false;
|
||||
JsonObjectConst carray1 = object1;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello";
|
||||
object2["c"][0] = false;
|
||||
JsonObjectConst carray2 = object2;
|
||||
|
||||
CHECK(carray1 == carray2);
|
||||
CHECK(carray1 <= carray2);
|
||||
CHECK(carray1 >= carray2);
|
||||
CHECK_FALSE(carray1 != carray2);
|
||||
CHECK_FALSE(carray1 > carray2);
|
||||
CHECK_FALSE(carray1 < carray2);
|
||||
}
|
||||
|
||||
SECTION("Compare with different object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello1";
|
||||
object1["c"][0] = false;
|
||||
JsonObjectConst carray1 = object1;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello2";
|
||||
object2["c"][0] = false;
|
||||
JsonObjectConst carray2 = object2;
|
||||
|
||||
CHECK(carray1 != carray2);
|
||||
CHECK_FALSE(carray1 == carray2);
|
||||
CHECK_FALSE(carray1 > carray2);
|
||||
CHECK_FALSE(carray1 < carray2);
|
||||
CHECK_FALSE(carray1 <= carray2);
|
||||
CHECK_FALSE(carray1 >= carray2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Compare JsonObjectConst with JsonVariant") {
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
SECTION("Compare with self") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["a"] = 1;
|
||||
object["b"] = "hello";
|
||||
JsonObjectConst cobject = object;
|
||||
JsonVariant variant = object;
|
||||
|
||||
CHECK(cobject == variant);
|
||||
CHECK(cobject <= variant);
|
||||
CHECK(cobject >= variant);
|
||||
CHECK_FALSE(cobject != variant);
|
||||
CHECK_FALSE(cobject > variant);
|
||||
CHECK_FALSE(cobject < variant);
|
||||
|
||||
CHECK(variant == cobject);
|
||||
CHECK(variant <= cobject);
|
||||
CHECK(variant >= cobject);
|
||||
CHECK_FALSE(variant != cobject);
|
||||
CHECK_FALSE(variant > cobject);
|
||||
CHECK_FALSE(variant < cobject);
|
||||
}
|
||||
|
||||
SECTION("Compare with identical object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello";
|
||||
object1["c"][0] = false;
|
||||
JsonObjectConst carray1 = object1;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello";
|
||||
object2["c"][0] = false;
|
||||
JsonVariant variant2 = object2;
|
||||
|
||||
CHECK(carray1 == variant2);
|
||||
CHECK(carray1 <= variant2);
|
||||
CHECK(carray1 >= variant2);
|
||||
CHECK_FALSE(carray1 != variant2);
|
||||
CHECK_FALSE(carray1 > variant2);
|
||||
CHECK_FALSE(carray1 < variant2);
|
||||
|
||||
CHECK(variant2 == carray1);
|
||||
CHECK(variant2 <= carray1);
|
||||
CHECK(variant2 >= carray1);
|
||||
CHECK_FALSE(variant2 != carray1);
|
||||
CHECK_FALSE(variant2 > carray1);
|
||||
CHECK_FALSE(variant2 < carray1);
|
||||
}
|
||||
|
||||
SECTION("Compare with different object") {
|
||||
JsonObject object1 = doc.createNestedObject();
|
||||
object1["a"] = 1;
|
||||
object1["b"] = "hello1";
|
||||
object1["c"][0] = false;
|
||||
JsonObjectConst carray1 = object1;
|
||||
|
||||
JsonObject object2 = doc.createNestedObject();
|
||||
object2["a"] = 1;
|
||||
object2["b"] = "hello2";
|
||||
object2["c"][0] = false;
|
||||
JsonVariant variant2 = object2;
|
||||
|
||||
CHECK(carray1 != variant2);
|
||||
CHECK_FALSE(carray1 == variant2);
|
||||
CHECK_FALSE(carray1 > variant2);
|
||||
CHECK_FALSE(carray1 < variant2);
|
||||
CHECK_FALSE(carray1 <= variant2);
|
||||
CHECK_FALSE(carray1 >= variant2);
|
||||
|
||||
CHECK(variant2 != carray1);
|
||||
CHECK_FALSE(variant2 == carray1);
|
||||
CHECK_FALSE(variant2 > carray1);
|
||||
CHECK_FALSE(variant2 < carray1);
|
||||
CHECK_FALSE(variant2 <= carray1);
|
||||
CHECK_FALSE(variant2 >= carray1);
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ TEST_CASE("JsonObject::containsKey()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -16,7 +16,7 @@ TEST_CASE("JsonObject::createNestedArray()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -15,7 +15,7 @@ TEST_CASE("JsonObject::createNestedObject()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -60,7 +60,7 @@ TEST_CASE("JsonObject::remove()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a vla") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
obj.remove(vla);
|
||||
|
@ -5,9 +5,10 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
static void eraseString(std::string &str) {
|
||||
char *p = const_cast<char *>(str.c_str());
|
||||
while (*p) *p++ = '*';
|
||||
static void eraseString(std::string& str) {
|
||||
char* p = const_cast<char*>(str.c_str());
|
||||
while (*p)
|
||||
*p++ = '*';
|
||||
}
|
||||
|
||||
TEST_CASE("std::string") {
|
||||
|
@ -141,13 +141,13 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("should duplicate a non-static JsonString key") {
|
||||
obj[JsonString("hello", false)] = "world";
|
||||
obj[JsonString("hello", JsonString::Copied)] = "world";
|
||||
const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5);
|
||||
REQUIRE(expectedSize == doc.memoryUsage());
|
||||
}
|
||||
|
||||
SECTION("should not duplicate a static JsonString key") {
|
||||
obj[JsonString("hello", true)] = "world";
|
||||
obj[JsonString("hello", JsonString::Linked)] = "world";
|
||||
const size_t expectedSize = JSON_OBJECT_SIZE(1);
|
||||
REQUIRE(expectedSize == doc.memoryUsage());
|
||||
}
|
||||
@ -172,7 +172,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
|
||||
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
|
||||
SECTION("obj[VLA] = str") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
@ -182,7 +182,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj[str] = VLA") { // issue #416
|
||||
int i = 32;
|
||||
size_t i = 32;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
@ -192,7 +192,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj.set(VLA, str)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
@ -202,7 +202,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj.set(str, VLA)") {
|
||||
int i = 32;
|
||||
size_t i = 32;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
@ -212,7 +212,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj[VLA]") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -14,18 +14,18 @@ class CustomWriter {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *s, size_t n) {
|
||||
_str.append(reinterpret_cast<const char *>(s), n);
|
||||
size_t write(const uint8_t* s, size_t n) {
|
||||
_str.append(reinterpret_cast<const char*>(s), n);
|
||||
return n;
|
||||
}
|
||||
|
||||
const std::string &str() const {
|
||||
const std::string& str() const {
|
||||
return _str;
|
||||
}
|
||||
|
||||
private:
|
||||
CustomWriter(const CustomWriter &); // non-copiable
|
||||
CustomWriter &operator=(const CustomWriter &);
|
||||
CustomWriter(const CustomWriter&); // non-copiable
|
||||
CustomWriter& operator=(const CustomWriter&);
|
||||
|
||||
std::string _str;
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ TEST_CASE("serializeJson(JsonArray)") {
|
||||
}
|
||||
|
||||
SECTION("Null") {
|
||||
array.add(static_cast<char *>(0));
|
||||
array.add(static_cast<char*>(0));
|
||||
|
||||
check(array, "[null]");
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <catch.hpp>
|
||||
#include <string>
|
||||
|
||||
static void checkObject(const JsonObject obj, const std::string &expected) {
|
||||
static void checkObject(const JsonObject obj, const std::string& expected) {
|
||||
char actual[256];
|
||||
memset(actual, '!', sizeof(actual));
|
||||
|
||||
@ -84,8 +84,8 @@ TEST_CASE("serializeJson(JsonObject)") {
|
||||
}
|
||||
|
||||
SECTION("TwoNull") {
|
||||
obj["a"] = static_cast<char *>(0);
|
||||
obj["b"] = static_cast<char *>(0);
|
||||
obj["a"] = static_cast<char*>(0);
|
||||
obj["b"] = static_cast<char*>(0);
|
||||
checkObject(obj, "{\"a\":null,\"b\":null}");
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <limits>
|
||||
|
||||
template <typename T>
|
||||
void check(T value, const std::string &expected) {
|
||||
void check(T value, const std::string& expected) {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.to<JsonVariant>().set(value);
|
||||
char buffer[256] = "";
|
||||
@ -22,7 +22,7 @@ TEST_CASE("serializeJson(JsonVariant)") {
|
||||
}
|
||||
|
||||
SECTION("Null string") {
|
||||
check(static_cast<char *>(0), "null");
|
||||
check(static_cast<char*>(0), "null");
|
||||
}
|
||||
|
||||
SECTION("const char*") {
|
||||
|
@ -8,8 +8,8 @@ add_executable(JsonVariantTests
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
copy.cpp
|
||||
converters.cpp
|
||||
copy.cpp
|
||||
createNested.cpp
|
||||
is.cpp
|
||||
isnull.cpp
|
||||
@ -20,6 +20,8 @@ add_executable(JsonVariantTests
|
||||
overflow.cpp
|
||||
remove.cpp
|
||||
set.cpp
|
||||
shallowCopy.cpp
|
||||
size.cpp
|
||||
subscript.cpp
|
||||
types.cpp
|
||||
unbound.cpp
|
||||
|
@ -136,7 +136,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
|
||||
REQUIRE(variant.as<long>() == 42L);
|
||||
REQUIRE(variant.as<JsonString>() == "42");
|
||||
REQUIRE(variant.as<JsonString>().isStatic() == true);
|
||||
REQUIRE(variant.as<JsonString>().isLinked() == true);
|
||||
}
|
||||
|
||||
SECTION("set(\"hello\")") {
|
||||
@ -159,7 +159,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<const char*>() == std::string("4.2"));
|
||||
REQUIRE(variant.as<std::string>() == std::string("4.2"));
|
||||
REQUIRE(variant.as<JsonString>() == "4.2");
|
||||
REQUIRE(variant.as<JsonString>().isStatic() == false);
|
||||
REQUIRE(variant.as<JsonString>().isLinked() == false);
|
||||
}
|
||||
|
||||
SECTION("set(\"true\")") {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
TEST_CASE("Compare JsonVariant with value") {
|
||||
StaticJsonDocument<256> doc;
|
||||
JsonVariant a = doc.addElement();
|
||||
JsonVariant a = doc.add();
|
||||
|
||||
SECTION("null vs (char*)0") {
|
||||
char* b = 0;
|
||||
@ -38,8 +38,8 @@ TEST_CASE("Compare JsonVariant with value") {
|
||||
|
||||
TEST_CASE("Compare JsonVariant with JsonVariant") {
|
||||
StaticJsonDocument<256> doc;
|
||||
JsonVariant a = doc.addElement();
|
||||
JsonVariant b = doc.addElement();
|
||||
JsonVariant a = doc.add();
|
||||
JsonVariant b = doc.add();
|
||||
|
||||
SECTION("'abc' vs 'abc'") {
|
||||
a.set("abc");
|
||||
|
@ -12,14 +12,14 @@ TEST_CASE("JsonVariant::containsKey()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonVariant var = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("containsKey(const char*) returns true") {
|
||||
SECTION("containsKey(const char*)") {
|
||||
var["hello"] = "world";
|
||||
|
||||
REQUIRE(var.containsKey("hello") == true);
|
||||
REQUIRE(var.containsKey("world") == false);
|
||||
}
|
||||
|
||||
SECTION("containsKey(std::string) returns true") {
|
||||
SECTION("containsKey(std::string)") {
|
||||
var["hello"] = "world";
|
||||
|
||||
REQUIRE(var.containsKey(std::string("hello")) == true);
|
||||
|
@ -91,16 +91,16 @@ class Complex {
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <>
|
||||
struct Converter<Complex> {
|
||||
static void toJson(const Complex& src, VariantRef dst) {
|
||||
static void toJson(const Complex& src, JsonVariant dst) {
|
||||
dst["real"] = src.real();
|
||||
dst["imag"] = src.imag();
|
||||
}
|
||||
|
||||
static Complex fromJson(VariantConstRef src) {
|
||||
static Complex fromJson(JsonVariantConst src) {
|
||||
return Complex(src["real"], src["imag"]);
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
return src["real"].is<double>() && src["imag"].is<double>();
|
||||
}
|
||||
};
|
||||
@ -140,3 +140,15 @@ TEST_CASE("Custom converter with specialization") {
|
||||
REQUIRE(doc["value"]["imag"] == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ConverterNeedsWriteableRef") {
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
CHECK(ConverterNeedsWriteableRef<int>::value == false);
|
||||
CHECK(ConverterNeedsWriteableRef<float>::value == false);
|
||||
CHECK(ConverterNeedsWriteableRef<JsonVariant>::value == true);
|
||||
CHECK(ConverterNeedsWriteableRef<JsonVariantConst>::value == false);
|
||||
CHECK(ConverterNeedsWriteableRef<JsonObject>::value == true);
|
||||
CHECK(ConverterNeedsWriteableRef<JsonObjectConst>::value == false);
|
||||
CHECK(ConverterNeedsWriteableRef<JsonArray>::value == true);
|
||||
CHECK(ConverterNeedsWriteableRef<JsonArrayConst>::value == false);
|
||||
}
|
||||
|
@ -18,13 +18,6 @@ TEST_CASE("JsonVariant::createNestedObject()") {
|
||||
REQUIRE(variant[0]["value"] == 42);
|
||||
REQUIRE(obj.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("works on MemberProxy") {
|
||||
JsonObject obj = variant["items"].createNestedObject();
|
||||
obj["value"] = 42;
|
||||
|
||||
REQUIRE(variant["items"][0]["value"] == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::createNestedArray()") {
|
||||
@ -37,13 +30,6 @@ TEST_CASE("JsonVariant::createNestedArray()") {
|
||||
REQUIRE(variant.is<JsonArray>() == true);
|
||||
REQUIRE(arr.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("works on MemberProxy") {
|
||||
JsonArray arr = variant["items"].createNestedArray();
|
||||
arr.add(42);
|
||||
|
||||
REQUIRE(variant["items"][0][0] == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::createNestedObject(key)") {
|
||||
@ -57,13 +43,6 @@ TEST_CASE("JsonVariant::createNestedObject(key)") {
|
||||
REQUIRE(variant.is<JsonObject>() == true);
|
||||
REQUIRE(variant["weather"]["temp"] == 42);
|
||||
}
|
||||
|
||||
SECTION("works on MemberProxy") {
|
||||
JsonObject obj = variant["status"].createNestedObject("weather");
|
||||
obj["temp"] = 42;
|
||||
|
||||
REQUIRE(variant["status"]["weather"]["temp"] == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::createNestedArray(key)") {
|
||||
@ -76,11 +55,4 @@ TEST_CASE("JsonVariant::createNestedArray(key)") {
|
||||
REQUIRE(variant.is<JsonObject>() == true);
|
||||
REQUIRE(arr.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("works on MemberProxy") {
|
||||
JsonArray arr = variant["weather"].createNestedArray("temp");
|
||||
arr.add(42);
|
||||
|
||||
REQUIRE(variant["weather"]["temp"][0] == 42);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<JsonVariant>() == false);
|
||||
CHECK(variant.is<JsonVariantConst>() == false);
|
||||
CHECK(variant.is<bool>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<std::string>() == false);
|
||||
CHECK(variant.is<JsonString>() == false);
|
||||
@ -34,7 +34,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<JsonObject>() == false);
|
||||
CHECK(variant.is<JsonArray>() == false);
|
||||
CHECK(variant.is<bool>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<std::string>() == false);
|
||||
CHECK(variant.is<JsonString>() == false);
|
||||
@ -50,7 +50,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<JsonVariantConst>() == true);
|
||||
CHECK(variant.is<JsonObject>() == false);
|
||||
CHECK(variant.is<JsonArray>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<std::string>() == false);
|
||||
CHECK(variant.is<JsonString>() == false);
|
||||
@ -66,7 +66,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<JsonVariantConst>() == true);
|
||||
CHECK(variant.is<JsonObject>() == false);
|
||||
CHECK(variant.is<JsonArray>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<std::string>() == false);
|
||||
CHECK(variant.is<JsonString>() == false);
|
||||
@ -88,7 +88,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<bool>() == false);
|
||||
CHECK(variant.is<JsonObject>() == false);
|
||||
CHECK(variant.is<JsonArray>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<std::string>() == false);
|
||||
CHECK(variant.is<JsonString>() == false);
|
||||
}
|
||||
@ -103,7 +103,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<bool>() == false);
|
||||
CHECK(variant.is<JsonObject>() == false);
|
||||
CHECK(variant.is<JsonArray>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<std::string>() == false);
|
||||
CHECK(variant.is<JsonString>() == false);
|
||||
@ -113,8 +113,8 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
SECTION("const char*") {
|
||||
variant.set("4.2");
|
||||
|
||||
CHECK(variant.is<const char *>() == true);
|
||||
CHECK(variant.is<const char *>() == true);
|
||||
CHECK(variant.is<const char*>() == true);
|
||||
CHECK(variant.is<const char*>() == true);
|
||||
CHECK(variant.is<std::string>() == true);
|
||||
CHECK(variant.is<JsonString>() == true);
|
||||
CHECK(variant.is<JsonVariant>() == true);
|
||||
@ -140,7 +140,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<float>() == false);
|
||||
CHECK(variant.is<bool>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<MYENUM2>() == false);
|
||||
}
|
||||
|
||||
@ -156,7 +156,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
||||
CHECK(variant.is<int>() == false);
|
||||
CHECK(variant.is<float>() == false);
|
||||
CHECK(variant.is<bool>() == false);
|
||||
CHECK(variant.is<const char *>() == false);
|
||||
CHECK(variant.is<const char*>() == false);
|
||||
CHECK(variant.is<MYENUM2>() == false);
|
||||
CHECK(variant.is<JsonVariant>() == true);
|
||||
CHECK(variant.is<JsonVariantConst>() == true);
|
||||
@ -178,7 +178,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<JsonVariant>() == false);
|
||||
CHECK(cvariant.is<JsonVariantConst>() == false);
|
||||
CHECK(cvariant.is<bool>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<std::string>() == false);
|
||||
CHECK(cvariant.is<JsonString>() == false);
|
||||
@ -192,7 +192,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<JsonArray>() == false);
|
||||
CHECK(cvariant.is<JsonVariant>() == false);
|
||||
CHECK(cvariant.is<bool>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<std::string>() == false);
|
||||
CHECK(cvariant.is<JsonString>() == false);
|
||||
@ -208,7 +208,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<JsonVariant>() == false);
|
||||
CHECK(cvariant.is<JsonObject>() == false);
|
||||
CHECK(cvariant.is<JsonArray>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<std::string>() == false);
|
||||
CHECK(cvariant.is<JsonString>() == false);
|
||||
@ -224,7 +224,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<JsonVariant>() == false);
|
||||
CHECK(cvariant.is<JsonObject>() == false);
|
||||
CHECK(cvariant.is<JsonArray>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<std::string>() == false);
|
||||
CHECK(cvariant.is<JsonString>() == false);
|
||||
@ -246,7 +246,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<JsonObject>() == false);
|
||||
CHECK(cvariant.is<JsonArray>() == false);
|
||||
CHECK(cvariant.is<JsonVariant>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<std::string>() == false);
|
||||
CHECK(cvariant.is<JsonString>() == false);
|
||||
}
|
||||
@ -261,7 +261,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<JsonObject>() == false);
|
||||
CHECK(cvariant.is<JsonArray>() == false);
|
||||
CHECK(cvariant.is<JsonVariant>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<std::string>() == false);
|
||||
CHECK(cvariant.is<JsonString>() == false);
|
||||
@ -271,8 +271,8 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
SECTION("const char*") {
|
||||
variant.set("4.2");
|
||||
|
||||
CHECK(cvariant.is<const char *>() == true);
|
||||
CHECK(cvariant.is<const char *>() == true);
|
||||
CHECK(cvariant.is<const char*>() == true);
|
||||
CHECK(cvariant.is<const char*>() == true);
|
||||
CHECK(cvariant.is<std::string>() == true);
|
||||
CHECK(cvariant.is<JsonString>() == true);
|
||||
CHECK(cvariant.is<double>() == false);
|
||||
@ -297,7 +297,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<float>() == false);
|
||||
CHECK(cvariant.is<bool>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<MYENUM2>() == false);
|
||||
}
|
||||
|
||||
@ -313,7 +313,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
||||
CHECK(cvariant.is<int>() == false);
|
||||
CHECK(cvariant.is<float>() == false);
|
||||
CHECK(cvariant.is<bool>() == false);
|
||||
CHECK(cvariant.is<const char *>() == false);
|
||||
CHECK(cvariant.is<const char*>() == false);
|
||||
CHECK(cvariant.is<MYENUM2>() == false);
|
||||
}
|
||||
}
|
||||
|
@ -9,17 +9,17 @@ TEST_CASE("JsonVariant::isNull()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonVariant variant = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("return true when Undefined") {
|
||||
SECTION("returns true when Undefined") {
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return false when Integer") {
|
||||
SECTION("returns false when Integer") {
|
||||
variant.set(42);
|
||||
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return false when EmptyArray") {
|
||||
SECTION("returns false when EmptyArray") {
|
||||
DynamicJsonDocument doc2(4096);
|
||||
JsonArray array = doc2.to<JsonArray>();
|
||||
|
||||
@ -27,7 +27,7 @@ TEST_CASE("JsonVariant::isNull()") {
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return false when EmptyObject") {
|
||||
SECTION("returns false when EmptyObject") {
|
||||
DynamicJsonDocument doc2(4096);
|
||||
JsonObject obj = doc2.to<JsonObject>();
|
||||
|
||||
@ -35,41 +35,54 @@ TEST_CASE("JsonVariant::isNull()") {
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return true after set(JsonArray())") {
|
||||
SECTION("returns true after set(JsonArray())") {
|
||||
variant.set(JsonArray());
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set(JsonObject())") {
|
||||
SECTION("returns true after set(JsonObject())") {
|
||||
variant.set(JsonObject());
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return false after set('hello')") {
|
||||
SECTION("returns false after set('hello')") {
|
||||
variant.set("hello");
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return true after set((char*)0)") {
|
||||
SECTION("returns true after set((char*)0)") {
|
||||
variant.set(static_cast<char*>(0));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set((const char*)0)") {
|
||||
SECTION("returns true after set((const char*)0)") {
|
||||
variant.set(static_cast<const char*>(0));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set(serialized((char*)0))") {
|
||||
SECTION("returns true after set(serialized((char*)0))") {
|
||||
variant.set(serialized(static_cast<char*>(0)));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set(serialized((const char*)0))") {
|
||||
SECTION("returns true after set(serialized((const char*)0))") {
|
||||
variant.set(serialized(static_cast<const char*>(0)));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("returns true for a shallow null copy") {
|
||||
StaticJsonDocument<128> doc2;
|
||||
variant.shallowCopy(doc2);
|
||||
CHECK(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false for a shallow array copy") {
|
||||
StaticJsonDocument<128> doc2;
|
||||
doc2[0] = 42;
|
||||
variant.shallowCopy(doc2);
|
||||
CHECK(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("works with JsonVariantConst") {
|
||||
variant.set(42);
|
||||
|
||||
|
@ -15,7 +15,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(static_cast<const char *>(str));
|
||||
bool result = variant.set(static_cast<const char*>(str));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
@ -23,7 +23,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
}
|
||||
|
||||
SECTION("(const char*)0") {
|
||||
bool result = variant.set(static_cast<const char *>(0));
|
||||
bool result = variant.set(static_cast<const char*>(0));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.isNull());
|
||||
@ -41,7 +41,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
}
|
||||
|
||||
SECTION("(char*)0") {
|
||||
bool result = variant.set(static_cast<char *>(0));
|
||||
bool result = variant.set(static_cast<char*>(0));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.isNull());
|
||||
@ -51,7 +51,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(reinterpret_cast<unsigned char *>(str));
|
||||
bool result = variant.set(reinterpret_cast<unsigned char*>(str));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
@ -62,7 +62,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(reinterpret_cast<signed char *>(str));
|
||||
bool result = variant.set(reinterpret_cast<signed char*>(str));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
@ -71,7 +71,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("VLA") {
|
||||
int n = 16;
|
||||
size_t n = 16;
|
||||
char str[n];
|
||||
|
||||
strcpy(str, "hello");
|
||||
@ -98,7 +98,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(JsonString(str, true));
|
||||
bool result = variant.set(JsonString(str, JsonString::Linked));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
@ -109,7 +109,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(JsonString(str, false));
|
||||
bool result = variant.set(JsonString(str, JsonString::Copied));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
|
87
extras/tests/JsonVariant/shallowCopy.cpp
Normal file
87
extras/tests/JsonVariant/shallowCopy.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonVariant::shallowCopy()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
JsonVariant variant = doc1.to<JsonVariant>();
|
||||
|
||||
SECTION("JsonVariant::shallowCopy(JsonDocument&)") {
|
||||
doc2["hello"] = "world";
|
||||
|
||||
variant.shallowCopy(doc2);
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
|
||||
// altering the linked document should change the result
|
||||
doc2["hello"] = "WORLD!";
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::shallowCopy(MemberProxy)") {
|
||||
doc2["obj"]["hello"] = "world";
|
||||
|
||||
variant.shallowCopy(doc2["obj"]);
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
|
||||
// altering the linked document should change the result
|
||||
doc2["obj"]["hello"] = "WORLD!";
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::shallowCopy(ElementProxy)") {
|
||||
doc2[0]["hello"] = "world";
|
||||
|
||||
variant.shallowCopy(doc2[0]);
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
|
||||
// altering the linked document should change the result
|
||||
doc2[0]["hello"] = "WORLD!";
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
|
||||
}
|
||||
|
||||
SECTION("target is unbound") {
|
||||
JsonVariant unbound;
|
||||
variant["hello"] = "world";
|
||||
|
||||
variant.shallowCopy(unbound);
|
||||
|
||||
CHECK(variant.isUnbound() == false);
|
||||
CHECK(variant.isNull() == true);
|
||||
CHECK(variant.memoryUsage() == 0);
|
||||
CHECK(variant.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("variant is unbound") {
|
||||
JsonVariant unbound;
|
||||
doc2["hello"] = "world";
|
||||
|
||||
unbound.shallowCopy(doc2);
|
||||
|
||||
CHECK(unbound.isUnbound() == true);
|
||||
CHECK(unbound.isNull() == true);
|
||||
CHECK(unbound.memoryUsage() == 0);
|
||||
CHECK(unbound.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("preserves owned key bit") {
|
||||
doc2.set(42);
|
||||
|
||||
doc1["a"].shallowCopy(doc2);
|
||||
doc1[std::string("b")].shallowCopy(doc2);
|
||||
|
||||
JsonObject::iterator it = doc1.as<JsonObject>().begin();
|
||||
|
||||
CHECK(it->key().isLinked() == true);
|
||||
++it;
|
||||
CHECK(it->key().isLinked() == false);
|
||||
}
|
||||
}
|
36
extras/tests/JsonVariant/size.cpp
Normal file
36
extras/tests/JsonVariant/size.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonVariant::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonVariant variant = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("unbound reference") {
|
||||
JsonVariant unbound;
|
||||
|
||||
CHECK(unbound.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("int") {
|
||||
variant.set(42);
|
||||
|
||||
CHECK(variant.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("string") {
|
||||
variant.set("hello");
|
||||
|
||||
CHECK(variant.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("object") {
|
||||
variant["a"] = 1;
|
||||
variant["b"] = 2;
|
||||
|
||||
CHECK(variant.size() == 2);
|
||||
}
|
||||
}
|
@ -108,7 +108,7 @@ TEST_CASE("JsonVariant::operator[]") {
|
||||
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
|
||||
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
@ -119,7 +119,7 @@ TEST_CASE("JsonVariant::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("key is a VLA, const JsonVariant") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -17,9 +17,9 @@ void checkValue(T expected) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void checkReference(T &expected) {
|
||||
void checkReference(T& expected) {
|
||||
JsonVariant variant = expected;
|
||||
REQUIRE(expected == variant.as<T &>());
|
||||
REQUIRE(expected == variant.as<T&>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -46,10 +46,10 @@ TEST_CASE("JsonVariant set()/get()") {
|
||||
#endif
|
||||
|
||||
SECTION("Null") {
|
||||
checkValue<const char *>(NULL);
|
||||
checkValue<const char*>(NULL);
|
||||
}
|
||||
SECTION("const char*") {
|
||||
checkValue<const char *>("hello");
|
||||
checkValue<const char*>("hello");
|
||||
}
|
||||
SECTION("std::string") {
|
||||
checkValue<std::string>("hello");
|
||||
|
@ -12,7 +12,7 @@ TEST_CASE("StringCopier") {
|
||||
|
||||
SECTION("Works when buffer is big enough") {
|
||||
MemoryPool pool(buffer, addPadding(JSON_STRING_SIZE(5)));
|
||||
StringCopier str(pool);
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
str.append("hello");
|
||||
@ -24,7 +24,7 @@ TEST_CASE("StringCopier") {
|
||||
|
||||
SECTION("Returns null when too small") {
|
||||
MemoryPool pool(buffer, sizeof(void*));
|
||||
StringCopier str(pool);
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
str.append("hello world!");
|
||||
@ -35,7 +35,7 @@ TEST_CASE("StringCopier") {
|
||||
|
||||
SECTION("Increases size of memory pool") {
|
||||
MemoryPool pool(buffer, addPadding(JSON_STRING_SIZE(6)));
|
||||
StringCopier str(pool);
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
str.save();
|
||||
@ -46,7 +46,7 @@ TEST_CASE("StringCopier") {
|
||||
|
||||
SECTION("Works when memory pool is 0 bytes") {
|
||||
MemoryPool pool(buffer, 0);
|
||||
StringCopier str(pool);
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
REQUIRE(str.isValid() == false);
|
||||
@ -55,7 +55,7 @@ TEST_CASE("StringCopier") {
|
||||
}
|
||||
|
||||
static const char* addStringToPool(MemoryPool& pool, const char* s) {
|
||||
StringCopier str(pool);
|
||||
StringCopier str(&pool);
|
||||
str.startString();
|
||||
str.append(s);
|
||||
return str.save().c_str();
|
||||
|
@ -22,7 +22,7 @@ TEST_CASE("MemoryPool::clear()") {
|
||||
}
|
||||
|
||||
SECTION("Discards allocated strings") {
|
||||
pool.saveString(adaptString(const_cast<char *>("123456789")));
|
||||
pool.saveString(adaptString(const_cast<char*>("123456789")));
|
||||
REQUIRE(pool.size() == 10);
|
||||
|
||||
pool.clear();
|
||||
|
@ -8,11 +8,11 @@
|
||||
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
|
||||
static const char *saveString(MemoryPool &pool, const char *s) {
|
||||
return pool.saveString(adaptString(const_cast<char *>(s)));
|
||||
static const char* saveString(MemoryPool& pool, const char* s) {
|
||||
return pool.saveString(adaptString(const_cast<char*>(s)));
|
||||
}
|
||||
|
||||
static const char *saveString(MemoryPool &pool, const char *s, size_t n) {
|
||||
static const char* saveString(MemoryPool& pool, const char* s, size_t n) {
|
||||
return pool.saveString(adaptString(s, n));
|
||||
}
|
||||
|
||||
@ -21,36 +21,36 @@ TEST_CASE("MemoryPool::saveString()") {
|
||||
MemoryPool pool(buffer, 32);
|
||||
|
||||
SECTION("Duplicates different strings") {
|
||||
const char *a = saveString(pool, "hello");
|
||||
const char *b = saveString(pool, "world");
|
||||
const char* a = saveString(pool, "hello");
|
||||
const char* b = saveString(pool, "world");
|
||||
REQUIRE(a != b);
|
||||
REQUIRE(pool.size() == 6 + 6);
|
||||
}
|
||||
|
||||
SECTION("Deduplicates identical strings") {
|
||||
const char *a = saveString(pool, "hello");
|
||||
const char *b = saveString(pool, "hello");
|
||||
const char* a = saveString(pool, "hello");
|
||||
const char* b = saveString(pool, "hello");
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(pool.size() == 6);
|
||||
}
|
||||
|
||||
SECTION("Deduplicates identical strings that contain NUL") {
|
||||
const char *a = saveString(pool, "hello\0world", 11);
|
||||
const char *b = saveString(pool, "hello\0world", 11);
|
||||
const char* a = saveString(pool, "hello\0world", 11);
|
||||
const char* b = saveString(pool, "hello\0world", 11);
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(pool.size() == 12);
|
||||
}
|
||||
|
||||
SECTION("Reuse part of a string if it ends with NUL") {
|
||||
const char *a = saveString(pool, "hello\0world", 11);
|
||||
const char *b = saveString(pool, "hello");
|
||||
const char* a = saveString(pool, "hello\0world", 11);
|
||||
const char* b = saveString(pool, "hello");
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(pool.size() == 12);
|
||||
}
|
||||
|
||||
SECTION("Don't stop on first NUL") {
|
||||
const char *a = saveString(pool, "hello");
|
||||
const char *b = saveString(pool, "hello\0world", 11);
|
||||
const char* a = saveString(pool, "hello");
|
||||
const char* b = saveString(pool, "hello\0world", 11);
|
||||
REQUIRE(a != b);
|
||||
REQUIRE(pool.size() == 18);
|
||||
}
|
||||
@ -58,16 +58,16 @@ TEST_CASE("MemoryPool::saveString()") {
|
||||
SECTION("Returns NULL when full") {
|
||||
REQUIRE(pool.capacity() == 32);
|
||||
|
||||
const void *p1 = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
const void* p1 = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
REQUIRE(p1 != 0);
|
||||
REQUIRE(pool.size() == 32);
|
||||
|
||||
const void *p2 = saveString(pool, "b");
|
||||
const void* p2 = saveString(pool, "b");
|
||||
REQUIRE(p2 == 0);
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when pool is too small") {
|
||||
const void *p = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
const void* p = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
REQUIRE(0 == p);
|
||||
}
|
||||
|
||||
@ -82,15 +82,15 @@ TEST_CASE("MemoryPool::saveString()") {
|
||||
}
|
||||
|
||||
SECTION("Returns same address after clear()") {
|
||||
const void *a = saveString(pool, "hello");
|
||||
const void* a = saveString(pool, "hello");
|
||||
pool.clear();
|
||||
const void *b = saveString(pool, "world");
|
||||
const void* b = saveString(pool, "world");
|
||||
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
|
||||
SECTION("Can use full capacity when fresh") {
|
||||
const void *a = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
const void* a = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
|
||||
REQUIRE(a != 0);
|
||||
}
|
||||
@ -99,7 +99,7 @@ TEST_CASE("MemoryPool::saveString()") {
|
||||
saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
pool.clear();
|
||||
|
||||
const void *a = saveString(pool, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
|
||||
const void* a = saveString(pool, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
|
||||
|
||||
REQUIRE(a != 0);
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ TEST_CASE("MemoryPool::size()") {
|
||||
SECTION("Doesn't grow when memory pool is full") {
|
||||
const size_t variantCount = sizeof(buffer) / sizeof(VariantSlot);
|
||||
|
||||
for (size_t i = 0; i < variantCount; i++) pool.allocVariant();
|
||||
for (size_t i = 0; i < variantCount; i++)
|
||||
pool.allocVariant();
|
||||
size_t size = pool.size();
|
||||
|
||||
pool.allocVariant();
|
||||
|
@ -5,7 +5,6 @@
|
||||
add_executable(MiscTests
|
||||
arithmeticCompare.cpp
|
||||
conflicts.cpp
|
||||
deprecated.cpp
|
||||
FloatParts.cpp
|
||||
JsonString.cpp
|
||||
NoArduinoHeader.cpp
|
||||
|
@ -13,45 +13,54 @@ TEST_CASE("JsonString") {
|
||||
|
||||
CHECK(s.isNull() == true);
|
||||
CHECK(s.c_str() == 0);
|
||||
CHECK(s.isStatic() == true);
|
||||
CHECK(s.isLinked() == true);
|
||||
CHECK(s == JsonString());
|
||||
CHECK(s != "");
|
||||
}
|
||||
|
||||
SECTION("Compare null with boolean") {
|
||||
SECTION("Null converts to false") {
|
||||
JsonString s;
|
||||
|
||||
CHECK(bool(s) == false);
|
||||
CHECK(false == bool(s));
|
||||
CHECK(bool(s) != true);
|
||||
CHECK(true != bool(s));
|
||||
}
|
||||
|
||||
SECTION("Compare non-null with boolean") {
|
||||
JsonString s("hello");
|
||||
SECTION("Empty string converts to true") {
|
||||
JsonString s("");
|
||||
|
||||
CHECK(bool(s) == true);
|
||||
CHECK(true == bool(s));
|
||||
CHECK(bool(s) != false);
|
||||
CHECK(false != bool(s));
|
||||
}
|
||||
|
||||
SECTION("Compare null with null") {
|
||||
SECTION("Non-empty string converts to true") {
|
||||
JsonString s("");
|
||||
|
||||
CHECK(bool(s) == true);
|
||||
}
|
||||
|
||||
SECTION("Null strings equals each others") {
|
||||
JsonString a, b;
|
||||
|
||||
CHECK(a == b);
|
||||
CHECK_FALSE(a != b);
|
||||
}
|
||||
|
||||
SECTION("Compare null with non-null") {
|
||||
JsonString a(0), b("hello");
|
||||
SECTION("Null and empty strings differ") {
|
||||
JsonString a, b("");
|
||||
|
||||
CHECK_FALSE(a == b);
|
||||
CHECK(a != b);
|
||||
|
||||
CHECK_FALSE(b == a);
|
||||
CHECK(b != a);
|
||||
}
|
||||
|
||||
SECTION("Compare non-null with null") {
|
||||
JsonString a("hello"), b(0);
|
||||
SECTION("Null and non-empty strings differ") {
|
||||
JsonString a, b("hello");
|
||||
|
||||
CHECK_FALSE(a == b);
|
||||
CHECK(a != b);
|
||||
|
||||
CHECK_FALSE(b == a);
|
||||
CHECK(b != a);
|
||||
}
|
||||
|
||||
SECTION("Compare different strings") {
|
||||
@ -82,4 +91,13 @@ TEST_CASE("JsonString") {
|
||||
ss << JsonString("hello world!");
|
||||
CHECK(ss.str() == "hello world!");
|
||||
}
|
||||
|
||||
SECTION("Construct with a size") {
|
||||
JsonString s("hello world", 5);
|
||||
|
||||
CHECK(s.size() == 5);
|
||||
CHECK(s.isLinked() == true);
|
||||
CHECK(s == "hello");
|
||||
CHECK(s != "hello world");
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,10 @@
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
|
||||
#include "custom_string.hpp"
|
||||
#include "progmem_emulation.hpp"
|
||||
#include "weird_strcmp.hpp"
|
||||
|
||||
#include <ArduinoJson/Strings/IsString.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
|
||||
#include <catch.hpp>
|
||||
@ -85,30 +87,18 @@ TEST_CASE("custom_string") {
|
||||
CHECK(s.size() == 5);
|
||||
}
|
||||
|
||||
struct EmptyStruct {};
|
||||
|
||||
TEST_CASE("IsString<T>") {
|
||||
SECTION("std::string") {
|
||||
CHECK(IsString<std::string>::value == true);
|
||||
}
|
||||
|
||||
SECTION("basic_string<wchar_t>") {
|
||||
CHECK(IsString<std::basic_string<wchar_t> >::value == false);
|
||||
}
|
||||
|
||||
SECTION("custom_string") {
|
||||
CHECK(IsString<custom_string>::value == true);
|
||||
}
|
||||
|
||||
SECTION("const __FlashStringHelper*") {
|
||||
CHECK(IsString<const __FlashStringHelper*>::value == true);
|
||||
}
|
||||
|
||||
SECTION("const char*") {
|
||||
CHECK(IsString<const char*>::value == true);
|
||||
}
|
||||
|
||||
SECTION("const char[]") {
|
||||
CHECK(IsString<const char[8]>::value == true);
|
||||
}
|
||||
CHECK(IsString<std::string>::value == true);
|
||||
CHECK(IsString<std::basic_string<wchar_t> >::value == false);
|
||||
CHECK(IsString<custom_string>::value == true);
|
||||
CHECK(IsString<const __FlashStringHelper*>::value == true);
|
||||
CHECK(IsString<const char*>::value == true);
|
||||
CHECK(IsString<const char[8]>::value == true);
|
||||
CHECK(IsString< ::String>::value == true);
|
||||
CHECK(IsString< ::StringSumHelper>::value == true);
|
||||
CHECK(IsString<const EmptyStruct*>::value == false);
|
||||
}
|
||||
|
||||
TEST_CASE("stringCompare") {
|
||||
|
@ -80,7 +80,7 @@ TEST_CASE("Polyfills/type_traits") {
|
||||
CHECK(is_integral<const volatile unsigned long>::value == true);
|
||||
CHECK(is_integral<const volatile unsigned short>::value == true);
|
||||
|
||||
CHECK(is_integral<UInt>::value == true);
|
||||
CHECK(is_integral<JsonUInt>::value == true);
|
||||
}
|
||||
|
||||
SECTION("is_signed") {
|
||||
@ -177,6 +177,24 @@ TEST_CASE("Polyfills/type_traits") {
|
||||
CHECK((is_convertible<EmptyEnum, int>::value == true));
|
||||
CHECK((is_convertible<int*, int>::value == false));
|
||||
CHECK((is_convertible<EmptyClass, int>::value == false));
|
||||
|
||||
CHECK((is_convertible<DeserializationError, JsonVariantConst>::value ==
|
||||
false));
|
||||
CHECK((is_convertible<JsonPair, JsonVariantConst>::value == false));
|
||||
CHECK((is_convertible<JsonVariant, JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<JsonVariantConst, JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<JsonArray, JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<ElementProxy<JsonArray>, JsonVariantConst>::value ==
|
||||
true));
|
||||
CHECK((is_convertible<JsonArrayConst, JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<JsonObject, JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<MemberProxy<JsonObject, const char*>,
|
||||
JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<JsonObjectConst, JsonVariantConst>::value == true));
|
||||
CHECK(
|
||||
(is_convertible<DynamicJsonDocument, JsonVariantConst>::value == true));
|
||||
CHECK((is_convertible<StaticJsonDocument<10>, JsonVariantConst>::value ==
|
||||
true));
|
||||
}
|
||||
|
||||
SECTION("is_class") {
|
||||
@ -194,19 +212,4 @@ TEST_CASE("Polyfills/type_traits") {
|
||||
CHECK(is_enum<bool>::value == false);
|
||||
CHECK(is_enum<double>::value == false);
|
||||
}
|
||||
|
||||
SECTION("IsVisitable") {
|
||||
CHECK(IsVisitable<DeserializationError>::value == false);
|
||||
CHECK(IsVisitable<JsonPair>::value == false);
|
||||
CHECK(IsVisitable<VariantRef>::value == true);
|
||||
CHECK(IsVisitable<VariantConstRef>::value == true);
|
||||
CHECK(IsVisitable<ArrayRef>::value == true);
|
||||
CHECK(IsVisitable<ElementProxy<ArrayRef> >::value == true);
|
||||
CHECK(IsVisitable<ArrayConstRef>::value == true);
|
||||
CHECK(IsVisitable<ObjectRef>::value == true);
|
||||
CHECK((IsVisitable<MemberProxy<ObjectRef, const char*> >::value == true));
|
||||
CHECK(IsVisitable<ObjectConstRef>::value == true);
|
||||
CHECK(IsVisitable<DynamicJsonDocument>::value == true);
|
||||
CHECK(IsVisitable<StaticJsonDocument<10> >::value == true);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ using namespace ARDUINOJSON_NAMESPACE;
|
||||
static void testCodepoint(uint32_t codepoint, std::string expected) {
|
||||
char buffer[4096];
|
||||
MemoryPool pool(buffer, 4096);
|
||||
StringCopier str(pool);
|
||||
StringCopier str(&pool);
|
||||
str.startString();
|
||||
|
||||
CAPTURE(codepoint);
|
||||
|
@ -1,115 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#define ARDUINOJSON_DEPRECATED(msg) // nothing
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("Deprecated features") {
|
||||
StaticJsonDocument<256> doc;
|
||||
const char* s = "hello";
|
||||
doc["s"] = s;
|
||||
doc["c"] = 42;
|
||||
doc["a"].add(s);
|
||||
doc["a"].add(42);
|
||||
|
||||
SECTION("JsonVariant::add(char)") {
|
||||
JsonVariant v = doc.to<JsonVariant>();
|
||||
v.add('*');
|
||||
REQUIRE(v[0] == 42);
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::as<char*>()") {
|
||||
JsonVariant v = doc["s"];
|
||||
REQUIRE(v.as<char*>() == s);
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::as<char>()") {
|
||||
JsonVariant v = doc["c"];
|
||||
REQUIRE(v.as<char>() == '*');
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::is<char*>()") {
|
||||
JsonVariant v = doc["s"];
|
||||
REQUIRE(v.is<char*>() == true);
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::is<char>()") {
|
||||
JsonVariant v = doc["c"];
|
||||
REQUIRE(v.is<char>() == true);
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::set(char)") {
|
||||
JsonVariant v = doc.to<JsonVariant>();
|
||||
v.set('*');
|
||||
REQUIRE(v.as<unsigned char>() == 42);
|
||||
}
|
||||
|
||||
SECTION("JsonVariantConst::as<char*>()") {
|
||||
JsonVariantConst v = doc["s"];
|
||||
REQUIRE(v.as<char*>() == s);
|
||||
}
|
||||
|
||||
SECTION("JsonVariantConst::as<char>()") {
|
||||
JsonVariantConst v = doc["c"];
|
||||
REQUIRE(v.as<char>() == '*');
|
||||
}
|
||||
|
||||
SECTION("JsonVariantConst::is<char*>()") {
|
||||
JsonVariantConst v = doc["s"];
|
||||
REQUIRE(v.is<char*>() == true);
|
||||
}
|
||||
|
||||
SECTION("JsonVariantConst::is<char>()") {
|
||||
JsonVariantConst v = doc["c"];
|
||||
REQUIRE(v.is<char>() == true);
|
||||
}
|
||||
|
||||
SECTION("MemberProxy::as<char*>()") {
|
||||
REQUIRE(doc["s"].as<char*>() == s);
|
||||
}
|
||||
|
||||
SECTION("MemberProxy::as<char>()") {
|
||||
REQUIRE(doc["c"].as<char>() == '*');
|
||||
}
|
||||
|
||||
SECTION("MemberProxy::as<char>()") {
|
||||
doc["x"].set('*');
|
||||
REQUIRE(doc["x"] == 42);
|
||||
}
|
||||
|
||||
SECTION("MemberProxy::is<char*>()") {
|
||||
REQUIRE(doc["s"].is<char*>() == true);
|
||||
REQUIRE(doc["c"].is<char*>() == false);
|
||||
}
|
||||
|
||||
SECTION("MemberProxy::is<char>()") {
|
||||
REQUIRE(doc["c"].is<char>() == true);
|
||||
REQUIRE(doc["s"].is<char>() == false);
|
||||
}
|
||||
|
||||
SECTION("ElementProxy::as<char*>()") {
|
||||
REQUIRE(doc["a"][0].as<char*>() == s);
|
||||
}
|
||||
|
||||
SECTION("ElementProxy::as<char>()") {
|
||||
REQUIRE(doc["a"][1].as<char>() == '*');
|
||||
}
|
||||
|
||||
SECTION("ElementProxy::as<char>()") {
|
||||
doc["a"][0].set('*');
|
||||
REQUIRE(doc["a"][0] == 42);
|
||||
}
|
||||
|
||||
SECTION("ElementProxy::is<char*>()") {
|
||||
REQUIRE(doc["a"][0].is<char*>() == true);
|
||||
REQUIRE(doc["a"][1].is<char*>() == false);
|
||||
}
|
||||
|
||||
SECTION("ElementProxy::is<char>()") {
|
||||
REQUIRE(doc["a"][1].is<char>() == true);
|
||||
REQUIRE(doc["a"][0].is<char>() == false);
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include "progmem_emulation.hpp"
|
||||
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include "progmem_emulation.hpp"
|
||||
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 0
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include "progmem_emulation.hpp"
|
||||
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1
|
||||
|
@ -5,6 +5,8 @@
|
||||
#define ARDUINO
|
||||
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
|
||||
|
||||
#include "progmem_emulation.hpp"
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
@ -1068,7 +1068,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeMsgPack(doc, vla, Filter(filter));
|
||||
@ -1096,7 +1096,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter, NestingLimit") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeMsgPack(doc, vla, Filter(filter), NestingLimit(5));
|
||||
@ -1124,7 +1124,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], NestingLimit, Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeMsgPack(doc, vla, NestingLimit(5), Filter(filter));
|
||||
|
@ -72,7 +72,7 @@ TEST_CASE("deserializeMsgPack(std::istream&)") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
TEST_CASE("deserializeMsgPack(VLA)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15);
|
||||
|
||||
|
@ -9,7 +9,7 @@ TEST_CASE("serialize MsgPack to various destination types") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["hello"] = "world";
|
||||
const char *expected_result = "\x81\xA5hello\xA5world";
|
||||
const char* expected_result = "\x81\xA5hello\xA5world";
|
||||
const size_t expected_length = 13;
|
||||
|
||||
SECTION("std::string") {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <limits>
|
||||
|
||||
template <typename T>
|
||||
void check(T value, const std::string &expected) {
|
||||
void check(T value, const std::string& expected) {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.to<JsonVariant>().set(value);
|
||||
char buffer[256] = "";
|
||||
|
@ -41,7 +41,8 @@ TEST_CASE("serialize MsgPack array") {
|
||||
}
|
||||
|
||||
SECTION("array 16") {
|
||||
for (int i = 0; i < 16; i++) array.add(i);
|
||||
for (int i = 0; i < 16; i++)
|
||||
array.add(i);
|
||||
|
||||
check(array,
|
||||
"\xDC\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D"
|
||||
@ -50,7 +51,8 @@ TEST_CASE("serialize MsgPack array") {
|
||||
|
||||
SECTION("array 32") {
|
||||
const char* nil = 0;
|
||||
for (int i = 0; i < 65536; i++) array.add(nil);
|
||||
for (int i = 0; i < 65536; i++)
|
||||
array.add(nil);
|
||||
|
||||
check(array,
|
||||
std::string("\xDD\x00\x01\x00\x00", 5) + std::string(65536, '\xc0'));
|
||||
|
@ -109,6 +109,7 @@ TEST_CASE("serialize MsgPack value") {
|
||||
|
||||
SECTION("float 32") {
|
||||
checkVariant(1.25, "\xCA\x3F\xA0\x00\x00");
|
||||
checkVariant(9.22337204e+18f, "\xca\x5f\x00\x00\x00");
|
||||
}
|
||||
|
||||
SECTION("float 64") {
|
||||
@ -144,4 +145,18 @@ TEST_CASE("serialize MsgPack value") {
|
||||
checkVariant(serialized("\xDA\xFF\xFF"), "\xDA\xFF\xFF");
|
||||
checkVariant(serialized("\xDB\x00\x01\x00\x00", 5), "\xDB\x00\x01\x00\x00");
|
||||
}
|
||||
|
||||
SECTION("serialize round double as integer") { // Issue #1718
|
||||
checkVariant(-32768.0, "\xD1\x80\x00");
|
||||
checkVariant(-129.0, "\xD1\xFF\x7F");
|
||||
checkVariant(-128.0, "\xD0\x80");
|
||||
checkVariant(-33.0, "\xD0\xDF");
|
||||
checkVariant(-32.0, "\xE0");
|
||||
checkVariant(-1.0, "\xFF");
|
||||
checkVariant(0.0, "\x00");
|
||||
checkVariant(127.0, "\x7F");
|
||||
checkVariant(128.0, "\xCC\x80");
|
||||
checkVariant(255.0, "\xCC\xFF");
|
||||
checkVariant(256.0, "\xCD\x01\x00");
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,10 @@
|
||||
# Copyright © 2014-2022, Benoit BLANCHON
|
||||
# MIT License
|
||||
|
||||
add_executable(NumbersTests
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED OFF)
|
||||
|
||||
add_executable(NumbersTests
|
||||
convertNumber.cpp
|
||||
parseFloat.cpp
|
||||
parseDouble.cpp
|
||||
|
@ -75,4 +75,62 @@ TEST_CASE("canConvertNumber<TOut, TIn>()") {
|
||||
CHECK((canConvertNumber<uint16_t, uint8_t>(128)) == true);
|
||||
CHECK((canConvertNumber<uint16_t, uint8_t>(255)) == true);
|
||||
}
|
||||
|
||||
SECTION("float -> int32_t") {
|
||||
CHECK((canConvertNumber<int32_t, float>(0)) == true);
|
||||
CHECK((canConvertNumber<int32_t, float>(-2.147483904e9f)) == false);
|
||||
CHECK((canConvertNumber<int32_t, float>(-2.147483648e+9f)) == true);
|
||||
CHECK((canConvertNumber<int32_t, float>(2.14748352e+9f)) == true);
|
||||
CHECK((canConvertNumber<int32_t, float>(2.14748365e+9f)) == false);
|
||||
}
|
||||
|
||||
SECTION("double -> int32_t") {
|
||||
CHECK((canConvertNumber<int32_t, double>(0)) == true);
|
||||
CHECK((canConvertNumber<int32_t, double>(-2.147483649e+9)) == false);
|
||||
CHECK((canConvertNumber<int32_t, double>(-2.147483648e+9)) == true);
|
||||
CHECK((canConvertNumber<int32_t, double>(2.147483647e+9)) == true);
|
||||
CHECK((canConvertNumber<int32_t, double>(2.147483648e+9)) == false);
|
||||
}
|
||||
|
||||
SECTION("float -> uint32_t") {
|
||||
CHECK((canConvertNumber<uint32_t, float>(0)) == true);
|
||||
CHECK((canConvertNumber<uint32_t, float>(-1.401298e-45f)) == false);
|
||||
CHECK((canConvertNumber<uint32_t, float>(4.29496704e+9f)) == true);
|
||||
CHECK((canConvertNumber<uint32_t, float>(4.294967296e+9f)) == false);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_HAS_LONG_LONG
|
||||
SECTION("float -> int64_t") {
|
||||
CHECK((canConvertNumber<int64_t, float>(0)) == true);
|
||||
CHECK((canConvertNumber<int64_t, float>(-9.22337204e+18f)) == true);
|
||||
CHECK((canConvertNumber<int64_t, float>(9.22337149e+18f)) == true);
|
||||
CHECK((canConvertNumber<int64_t, float>(9.22337204e+18f)) == false);
|
||||
}
|
||||
|
||||
SECTION("double -> int64_t") {
|
||||
CHECK((canConvertNumber<int64_t, double>(0)) == true);
|
||||
CHECK((canConvertNumber<int64_t, double>(-9.2233720368547758e+18)) == true);
|
||||
CHECK((canConvertNumber<int64_t, double>(9.2233720368547748e+18)) == true);
|
||||
CHECK((canConvertNumber<int64_t, double>(9.2233720368547758e+18)) == false);
|
||||
}
|
||||
|
||||
SECTION("float -> uint64_t") {
|
||||
CHECK((canConvertNumber<uint64_t, float>(0)) == true);
|
||||
CHECK((canConvertNumber<uint64_t, float>(-1.401298e-45f)) == false);
|
||||
CHECK((canConvertNumber<uint64_t, float>(1.844674297419792384e+19f)) ==
|
||||
true);
|
||||
CHECK((canConvertNumber<uint64_t, float>(1.8446744073709551616e+19f)) ==
|
||||
false);
|
||||
}
|
||||
|
||||
SECTION("double -> uint64_t") {
|
||||
CHECK((canConvertNumber<uint64_t, double>(0)) == true);
|
||||
CHECK((canConvertNumber<uint64_t, double>(-4.94065645841247e-324)) ==
|
||||
false);
|
||||
CHECK((canConvertNumber<uint64_t, double>(1.8446744073709549568e+19)) ==
|
||||
true);
|
||||
CHECK((canConvertNumber<uint64_t, double>(1.8446744073709551616e+19)) ==
|
||||
false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ TEST_CASE("Test unsigned integer overflow") {
|
||||
second.init();
|
||||
|
||||
// Avoids MSVC warning C4127 (conditional expression is constant)
|
||||
size_t integerSize = sizeof(Integer);
|
||||
size_t integerSize = sizeof(JsonInteger);
|
||||
|
||||
if (integerSize == 8) {
|
||||
parseNumber("18446744073709551615", first);
|
||||
@ -33,7 +33,7 @@ TEST_CASE("Test signed integer overflow") {
|
||||
second.init();
|
||||
|
||||
// Avoids MSVC warning C4127 (conditional expression is constant)
|
||||
size_t integerSize = sizeof(Integer);
|
||||
size_t integerSize = sizeof(JsonInteger);
|
||||
|
||||
if (integerSize == 8) {
|
||||
parseNumber("-9223372036854775808", first);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Catch v1.12.2
|
||||
* Generated: 2018-05-14 15:10:01.112442
|
||||
* Generated: 2023-01-17 08:45:40.979381
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
|
||||
@ -214,7 +214,7 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Use variadic macros if the compiler supports them
|
||||
#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
|
||||
#if ( defined _MSC_VER && _MSC_VER >= 1400 && !defined __EDGE__) || \
|
||||
( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
|
||||
( defined __GNUC__ && __GNUC__ >= 3 ) || \
|
||||
( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
|
||||
@ -2129,6 +2129,9 @@ namespace Catch{
|
||||
#define CATCH_TRAP() \
|
||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||
: : : "memory","r0","r3","r4" ) /* NOLINT */
|
||||
#elif defined(__aarch64__)
|
||||
// Backport of https://github.com/catchorg/Catch2/commit/a25c1a24af8bffd35727a888a307ff0280cf9387
|
||||
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
|
||||
#else
|
||||
#define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
|
||||
#endif
|
||||
@ -6392,18 +6395,21 @@ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
|
||||
// #included from: catch_fatal_condition.hpp
|
||||
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
// Report the error condition
|
||||
inline void reportFatal( std::string const& message ) {
|
||||
IContext& context = Catch::getCurrentContext();
|
||||
IResultCapture* resultCapture = context.getResultCapture();
|
||||
resultCapture->handleFatalErrorCondition( message );
|
||||
}
|
||||
//! Signals fatal error message to the run context
|
||||
inline void reportFatal(std::string const &message) {
|
||||
IContext &context = Catch::getCurrentContext();
|
||||
IResultCapture *resultCapture = context.getResultCapture();
|
||||
resultCapture->handleFatalErrorCondition(message);
|
||||
}
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
|
||||
#if defined(CATCH_PLATFORM_WINDOWS) /////////////////////////////////////////
|
||||
// #included from: catch_windows_h_proxy.h
|
||||
|
||||
#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
|
||||
@ -6429,176 +6435,307 @@ namespace Catch {
|
||||
#endif
|
||||
|
||||
|
||||
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
||||
#if !defined(CATCH_CONFIG_WINDOWS_SEH)
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
};
|
||||
class FatalConditionHandler {
|
||||
bool m_started;
|
||||
|
||||
// Install/disengage implementation for specific platform.
|
||||
// Should be if-defed to work on current platform, can assume
|
||||
// engage-disengage 1:1 pairing.
|
||||
void engage_platform() {}
|
||||
void disengage_platform() {}
|
||||
|
||||
public:
|
||||
// Should also have platform-specific implementations as needed
|
||||
FatalConditionHandler() : m_started(false) {}
|
||||
~FatalConditionHandler() {}
|
||||
|
||||
void engage() {
|
||||
assert(!m_started && "Handler cannot be installed twice.");
|
||||
m_started = true;
|
||||
engage_platform();
|
||||
}
|
||||
|
||||
void disengage() {
|
||||
assert(m_started &&
|
||||
"Handler cannot be uninstalled without being installed first");
|
||||
m_started = false;
|
||||
disengage_platform();
|
||||
}
|
||||
};
|
||||
} // namespace Catch
|
||||
|
||||
#else // CATCH_CONFIG_WINDOWS_SEH is defined
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct SignalDefs {
|
||||
DWORD id;
|
||||
const char *name;
|
||||
};
|
||||
extern SignalDefs signalDefs[];
|
||||
// There is no 1-1 mapping between signals and windows exceptions.
|
||||
// Windows can easily distinguish between SO and SigSegV,
|
||||
// but SigInt, SigTerm, etc are handled differently.
|
||||
SignalDefs signalDefs[] = {
|
||||
{EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"},
|
||||
{EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"},
|
||||
{EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"},
|
||||
{EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"},
|
||||
};
|
||||
|
||||
static LONG CALLBACK
|
||||
handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||
reportFatal(signalDefs[i].name);
|
||||
}
|
||||
}
|
||||
// If its not an exception we care about, pass it along.
|
||||
// This stops us from eating debugger breaks etc.
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
# else // CATCH_CONFIG_WINDOWS_SEH is defined
|
||||
// Since we do not support multiple instantiations, we put these
|
||||
// into global variables and rely on cleaning them up in outlined
|
||||
// constructors/destructors
|
||||
static PVOID exceptionHandlerHandle = CATCH_NULL;
|
||||
|
||||
namespace Catch {
|
||||
class FatalConditionHandler {
|
||||
bool m_started;
|
||||
|
||||
struct SignalDefs { DWORD id; const char* name; };
|
||||
extern SignalDefs signalDefs[];
|
||||
// There is no 1-1 mapping between signals and windows exceptions.
|
||||
// Windows can easily distinguish between SO and SigSegV,
|
||||
// but SigInt, SigTerm, etc are handled differently.
|
||||
SignalDefs signalDefs[] = {
|
||||
{ EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" },
|
||||
{ EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
|
||||
{ EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
|
||||
{ EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
|
||||
};
|
||||
// Install/disengage implementation for specific platform.
|
||||
// Should be if-defed to work on current platform, can assume
|
||||
// engage-disengage 1:1 pairing.
|
||||
|
||||
struct FatalConditionHandler {
|
||||
void engage_platform() {
|
||||
// Register as first handler in current chain
|
||||
exceptionHandlerHandle =
|
||||
AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
if (!exceptionHandlerHandle) {
|
||||
throw std::runtime_error("Could not register vectored exception handler");
|
||||
}
|
||||
}
|
||||
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
|
||||
reportFatal(signalDefs[i].name);
|
||||
}
|
||||
}
|
||||
// If its not an exception we care about, pass it along.
|
||||
// This stops us from eating debugger breaks etc.
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
void disengage_platform() {
|
||||
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
|
||||
throw std::runtime_error(
|
||||
"Could not unregister vectored exception handler");
|
||||
}
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
}
|
||||
|
||||
FatalConditionHandler() {
|
||||
isSet = true;
|
||||
// 32k seems enough for Catch to handle stack overflow,
|
||||
// but the value was found experimentally, so there is no strong guarantee
|
||||
guaranteeSize = 32 * 1024;
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
// Register as first handler in current chain
|
||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
// Pass in guarantee size to be filled
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
}
|
||||
public:
|
||||
FatalConditionHandler() : m_started(false) {
|
||||
ULONG guaranteeSize = static_cast<ULONG>(32 * 1024);
|
||||
if (!SetThreadStackGuarantee(&guaranteeSize)) {
|
||||
// We do not want to fully error out, because needing
|
||||
// the stack reserve should be rare enough anyway.
|
||||
Catch::cerr() << "Failed to reserve piece of stack."
|
||||
<< " Stack overflows will not be reported successfully.";
|
||||
}
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
if (isSet) {
|
||||
// Unregister handler and restore the old guarantee
|
||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
isSet = false;
|
||||
}
|
||||
}
|
||||
// We do not attempt to unset the stack guarantee, because
|
||||
// Windows does not support lowering the stack size guarantee.
|
||||
~FatalConditionHandler() {}
|
||||
|
||||
~FatalConditionHandler() {
|
||||
reset();
|
||||
}
|
||||
private:
|
||||
static bool isSet;
|
||||
static ULONG guaranteeSize;
|
||||
static PVOID exceptionHandlerHandle;
|
||||
};
|
||||
void engage() {
|
||||
assert(!m_started && "Handler cannot be installed twice.");
|
||||
m_started = true;
|
||||
engage_platform();
|
||||
}
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
|
||||
void disengage() {
|
||||
assert(m_started &&
|
||||
"Handler cannot be uninstalled without being installed first");
|
||||
m_started = false;
|
||||
disengage_platform();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_WINDOWS_SEH
|
||||
#endif // CATCH_CONFIG_WINDOWS_SEH
|
||||
|
||||
#else // Not Windows - assumed to be POSIX compatible //////////////////////////
|
||||
|
||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
#if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
};
|
||||
}
|
||||
class FatalConditionHandler {
|
||||
bool m_started;
|
||||
|
||||
# else // CATCH_CONFIG_POSIX_SIGNALS is defined
|
||||
// Install/disengage implementation for specific platform.
|
||||
// Should be if-defed to work on current platform, can assume
|
||||
// engage-disengage 1:1 pairing.
|
||||
void engage_platform() {}
|
||||
void disengage_platform() {}
|
||||
|
||||
public:
|
||||
// Should also have platform-specific implementations as needed
|
||||
FatalConditionHandler() : m_started(false) {}
|
||||
~FatalConditionHandler() {}
|
||||
|
||||
void engage() {
|
||||
assert(!m_started && "Handler cannot be installed twice.");
|
||||
m_started = true;
|
||||
engage_platform();
|
||||
}
|
||||
|
||||
void disengage() {
|
||||
assert(m_started &&
|
||||
"Handler cannot be uninstalled without being installed first");
|
||||
m_started = false;
|
||||
disengage_platform();
|
||||
}
|
||||
};
|
||||
} // namespace Catch
|
||||
|
||||
#else // CATCH_CONFIG_POSIX_SIGNALS is defined
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct SignalDefs {
|
||||
int id;
|
||||
const char* name;
|
||||
};
|
||||
extern SignalDefs signalDefs[];
|
||||
SignalDefs signalDefs[] = {
|
||||
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
||||
{ SIGILL, "SIGILL - Illegal instruction signal" },
|
||||
{ SIGFPE, "SIGFPE - Floating point error signal" },
|
||||
{ SIGSEGV, "SIGSEGV - Segmentation violation signal" },
|
||||
{ SIGTERM, "SIGTERM - Termination request signal" },
|
||||
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
||||
};
|
||||
struct SignalDefs {
|
||||
int id;
|
||||
const char *name;
|
||||
};
|
||||
extern SignalDefs signalDefs[];
|
||||
SignalDefs signalDefs[] = {
|
||||
{SIGINT, "SIGINT - Terminal interrupt signal"},
|
||||
{SIGILL, "SIGILL - Illegal instruction signal"},
|
||||
{SIGFPE, "SIGFPE - Floating point error signal"},
|
||||
{SIGSEGV, "SIGSEGV - Segmentation violation signal"},
|
||||
{SIGTERM, "SIGTERM - Termination request signal"},
|
||||
{SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}};
|
||||
|
||||
struct FatalConditionHandler {
|
||||
// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
|
||||
// which is zero initialization, but not explicit. We want to avoid
|
||||
// that.
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
static bool isSet;
|
||||
static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
|
||||
static stack_t oldSigStack;
|
||||
static char altStackMem[SIGSTKSZ];
|
||||
static char *altStackMem = CATCH_NULL;
|
||||
static std::size_t altStackSize = 0;
|
||||
static stack_t oldSigStack;
|
||||
static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)];
|
||||
|
||||
static void handleSignal( int sig ) {
|
||||
std::string name = "<unknown signal>";
|
||||
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
SignalDefs &def = signalDefs[i];
|
||||
if (sig == def.id) {
|
||||
name = def.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reset();
|
||||
reportFatal(name);
|
||||
raise( sig );
|
||||
}
|
||||
static void restorePreviousSignalHandlers() {
|
||||
// We set signal handlers back to the previous ones. Hopefully
|
||||
// nobody overwrote them in the meantime, and doesn't expect
|
||||
// their signal handlers to live past ours given that they
|
||||
// installed them after ours..
|
||||
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
||||
}
|
||||
// Return the old stack
|
||||
sigaltstack(&oldSigStack, CATCH_NULL);
|
||||
}
|
||||
|
||||
FatalConditionHandler() {
|
||||
isSet = true;
|
||||
stack_t sigStack;
|
||||
sigStack.ss_sp = altStackMem;
|
||||
sigStack.ss_size = SIGSTKSZ;
|
||||
sigStack.ss_flags = 0;
|
||||
sigaltstack(&sigStack, &oldSigStack);
|
||||
struct sigaction sa = { 0 };
|
||||
static void handleSignal(int sig) {
|
||||
char const *name = "<unknown signal>";
|
||||
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
SignalDefs &def = signalDefs[i];
|
||||
if (sig == def.id) {
|
||||
name = def.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We need to restore previous signal handlers and let them do
|
||||
// their thing, so that the users can have the debugger break
|
||||
// when a signal is raised, and so on.
|
||||
restorePreviousSignalHandlers();
|
||||
reportFatal(name);
|
||||
raise(sig);
|
||||
}
|
||||
|
||||
sa.sa_handler = handleSignal;
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
||||
}
|
||||
}
|
||||
class FatalConditionHandler {
|
||||
bool m_started;
|
||||
|
||||
~FatalConditionHandler() {
|
||||
reset();
|
||||
}
|
||||
static void reset() {
|
||||
if( isSet ) {
|
||||
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
|
||||
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
|
||||
sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
|
||||
}
|
||||
// Return the old stack
|
||||
sigaltstack(&oldSigStack, CATCH_NULL);
|
||||
isSet = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Install/disengage implementation for specific platform.
|
||||
// Should be if-defed to work on current platform, can assume
|
||||
// engage-disengage 1:1 pairing.
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
||||
stack_t FatalConditionHandler::oldSigStack = {};
|
||||
char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
|
||||
void engage_platform() {
|
||||
stack_t sigStack;
|
||||
sigStack.ss_sp = altStackMem;
|
||||
sigStack.ss_size = SIGSTKSZ;
|
||||
sigStack.ss_flags = 0;
|
||||
sigaltstack(&sigStack, &oldSigStack);
|
||||
struct sigaction sa = {0};
|
||||
|
||||
sa.sa_handler = handleSignal;
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void disengage_platform() { restorePreviousSignalHandlers(); }
|
||||
|
||||
public:
|
||||
FatalConditionHandler() : m_started(false) {
|
||||
assert(!altStackMem &&
|
||||
"Cannot initialize POSIX signal handler when one already exists");
|
||||
if (altStackSize == 0) {
|
||||
altStackSize = SIGSTKSZ;
|
||||
}
|
||||
altStackMem = new char[altStackSize]();
|
||||
}
|
||||
|
||||
~FatalConditionHandler() {
|
||||
delete[] altStackMem;
|
||||
// We signal that another instance can be constructed by zeroing
|
||||
// out the pointer.
|
||||
altStackMem = CATCH_NULL;
|
||||
}
|
||||
|
||||
void engage() {
|
||||
assert(!m_started && "Handler cannot be installed twice.");
|
||||
m_started = true;
|
||||
engage_platform();
|
||||
}
|
||||
|
||||
void disengage() {
|
||||
assert(m_started &&
|
||||
"Handler cannot be uninstalled without being installed first");
|
||||
m_started = false;
|
||||
disengage_platform();
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_POSIX_SIGNALS
|
||||
#endif // CATCH_CONFIG_POSIX_SIGNALS
|
||||
|
||||
#endif // not Windows
|
||||
|
||||
namespace Catch {
|
||||
|
||||
//! Simple RAII guard for (dis)engaging the FatalConditionHandler
|
||||
class FatalConditionHandlerGuard {
|
||||
FatalConditionHandler *m_handler;
|
||||
|
||||
public:
|
||||
FatalConditionHandlerGuard(FatalConditionHandler *handler)
|
||||
: m_handler(handler) {
|
||||
m_handler->engage();
|
||||
}
|
||||
~FatalConditionHandlerGuard() { m_handler->disengage(); }
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
#include <string>
|
||||
@ -6938,9 +7075,8 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void invokeActiveTestCase() {
|
||||
FatalConditionHandler fatalConditionHandler; // Handle signals
|
||||
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
|
||||
m_activeTestCase->invoke();
|
||||
fatalConditionHandler.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -6978,6 +7114,7 @@ namespace Catch {
|
||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||
std::vector<ITracker*> m_activeSections;
|
||||
TrackerContext m_trackerContext;
|
||||
FatalConditionHandler m_fatalConditionhandler;
|
||||
size_t m_prevPassed;
|
||||
bool m_shouldReportUnexpected;
|
||||
};
|
||||
|
12
idf_component.yml
Normal file
12
idf_component.yml
Normal file
@ -0,0 +1,12 @@
|
||||
version: "6.20.0"
|
||||
description: >-
|
||||
A simple and efficient JSON library for embedded C++.
|
||||
ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more.
|
||||
It is the most popular Arduino library on GitHub ❤❤❤❤❤.
|
||||
Check out arduinojson.org for a comprehensive documentation.
|
||||
url: https://arduinojson.org/
|
||||
files:
|
||||
exclude:
|
||||
- "**/.vs/**/*"
|
||||
- "examples/**/*"
|
||||
- "extras/**/*"
|
@ -7,7 +7,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "6.19.2",
|
||||
"version": "6.20.1",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "https://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=6.19.2
|
||||
version=6.20.1
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=A simple and efficient JSON library for embedded C++.
|
||||
|
@ -21,19 +21,19 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "ArduinoJson/Array/ArrayRef.hpp"
|
||||
#include "ArduinoJson/Object/ObjectRef.hpp"
|
||||
#include "ArduinoJson/Variant/VariantRef.hpp"
|
||||
#include "ArduinoJson/Array/JsonArray.hpp"
|
||||
#include "ArduinoJson/Object/JsonObject.hpp"
|
||||
#include "ArduinoJson/Variant/JsonVariantConst.hpp"
|
||||
|
||||
#include "ArduinoJson/Document/DynamicJsonDocument.hpp"
|
||||
#include "ArduinoJson/Document/StaticJsonDocument.hpp"
|
||||
|
||||
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||
#include "ArduinoJson/Array/JsonArrayImpl.hpp"
|
||||
#include "ArduinoJson/Array/Utilities.hpp"
|
||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||
#include "ArduinoJson/Object/JsonObjectImpl.hpp"
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||
@ -47,25 +47,25 @@
|
||||
#include "ArduinoJson/compatibility.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
|
||||
typedef ARDUINOJSON_NAMESPACE::Float JsonFloat;
|
||||
typedef ARDUINOJSON_NAMESPACE::Integer JsonInteger;
|
||||
typedef ARDUINOJSON_NAMESPACE::ObjectConstRef JsonObjectConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ObjectRef JsonObject;
|
||||
typedef ARDUINOJSON_NAMESPACE::Pair JsonPair;
|
||||
typedef ARDUINOJSON_NAMESPACE::PairConst JsonPairConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::String JsonString;
|
||||
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
|
||||
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::copyArray;
|
||||
using ARDUINOJSON_NAMESPACE::DeserializationError;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeJson;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
|
||||
using ARDUINOJSON_NAMESPACE::DynamicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::JsonArray;
|
||||
using ARDUINOJSON_NAMESPACE::JsonArrayConst;
|
||||
using ARDUINOJSON_NAMESPACE::JsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::JsonFloat;
|
||||
using ARDUINOJSON_NAMESPACE::JsonInteger;
|
||||
using ARDUINOJSON_NAMESPACE::JsonObject;
|
||||
using ARDUINOJSON_NAMESPACE::JsonObjectConst;
|
||||
using ARDUINOJSON_NAMESPACE::JsonPair;
|
||||
using ARDUINOJSON_NAMESPACE::JsonPairConst;
|
||||
using ARDUINOJSON_NAMESPACE::JsonString;
|
||||
using ARDUINOJSON_NAMESPACE::JsonUInt;
|
||||
using ARDUINOJSON_NAMESPACE::JsonVariant;
|
||||
using ARDUINOJSON_NAMESPACE::JsonVariantConst;
|
||||
using ARDUINOJSON_NAMESPACE::measureJson;
|
||||
using ARDUINOJSON_NAMESPACE::serialized;
|
||||
using ARDUINOJSON_NAMESPACE::serializeJson;
|
||||
|
@ -1,31 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
||||
return arr ? arr->addElement(pool) : 0;
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
inline typename TVisitor::result_type arrayAccept(const CollectionData *arr,
|
||||
TVisitor &visitor) {
|
||||
if (arr)
|
||||
return visitor.visitArray(*arr);
|
||||
else
|
||||
return visitor.visitNull();
|
||||
}
|
||||
|
||||
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||
if (lhs == rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return lhs->equalsArray(*rhs);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,28 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
|
||||
return impl()->addElement().template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
|
||||
return impl()->addElement().template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ElementProxy<TArray> ArrayShortcuts<TArray>::operator[](
|
||||
size_t index) const {
|
||||
return ElementProxy<TArray>(*impl(), index);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,121 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class VariantPtr {
|
||||
public:
|
||||
VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {}
|
||||
|
||||
VariantRef *operator->() {
|
||||
return &_variant;
|
||||
}
|
||||
|
||||
VariantRef &operator*() {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantRef _variant;
|
||||
};
|
||||
|
||||
class ArrayIterator {
|
||||
public:
|
||||
ArrayIterator() : _slot(0) {}
|
||||
explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot)
|
||||
: _pool(pool), _slot(slot) {}
|
||||
|
||||
VariantRef operator*() const {
|
||||
return VariantRef(_pool, _slot->data());
|
||||
}
|
||||
VariantPtr operator->() {
|
||||
return VariantPtr(_pool, _slot->data());
|
||||
}
|
||||
|
||||
bool operator==(const ArrayIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ArrayIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool *_pool;
|
||||
VariantSlot *_slot;
|
||||
};
|
||||
|
||||
class VariantConstPtr {
|
||||
public:
|
||||
VariantConstPtr(const VariantData *data) : _variant(data) {}
|
||||
|
||||
VariantConstRef *operator->() {
|
||||
return &_variant;
|
||||
}
|
||||
|
||||
VariantConstRef &operator*() {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantConstRef _variant;
|
||||
};
|
||||
|
||||
class ArrayConstRefIterator {
|
||||
public:
|
||||
ArrayConstRefIterator() : _slot(0) {}
|
||||
explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||
|
||||
VariantConstRef operator*() const {
|
||||
return VariantConstRef(_slot->data());
|
||||
}
|
||||
VariantConstPtr operator->() {
|
||||
return VariantConstPtr(_slot->data());
|
||||
}
|
||||
|
||||
bool operator==(const ArrayConstRefIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayConstRefIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ArrayConstRefIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayConstRefIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
const VariantSlot *_slot;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,213 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayFunctions.hpp>
|
||||
#include <ArduinoJson/Array/ArrayIterator.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class ObjectRef;
|
||||
template <typename>
|
||||
class ElementProxy;
|
||||
|
||||
template <typename TData>
|
||||
class ArrayRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||
return arrayAccept(_data, visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE operator bool() const {
|
||||
return _data != 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return _data ? _data->memoryUsage() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t nesting() const {
|
||||
return _data ? _data->nesting() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return _data ? _data->size() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
ArrayRefBase(TData* data) : _data(data) {}
|
||||
TData* _data;
|
||||
};
|
||||
|
||||
class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
||||
public Visitable {
|
||||
friend class ArrayRef;
|
||||
typedef ArrayRefBase<const CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ArrayConstRefIterator iterator;
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
FORCE_INLINE ArrayConstRef() : base_type(0) {}
|
||||
FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data ? _data->getElement(index) : 0);
|
||||
}
|
||||
};
|
||||
|
||||
class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||
public ArrayShortcuts<ArrayRef>,
|
||||
public Visitable {
|
||||
typedef ArrayRefBase<CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ArrayIterator iterator;
|
||||
|
||||
FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
|
||||
FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
|
||||
: base_type(data), _pool(pool) {}
|
||||
|
||||
operator VariantRef() {
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ArrayConstRef() const {
|
||||
return ArrayConstRef(_data);
|
||||
}
|
||||
|
||||
VariantRef addElement() const {
|
||||
return VariantRef(_pool, arrayAdd(_data, _pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_pool, _data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// Copy a ArrayRef
|
||||
FORCE_INLINE bool set(ArrayConstRef src) const {
|
||||
if (!_data || !src._data)
|
||||
return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
// Internal use
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getElement(index) : 0);
|
||||
}
|
||||
|
||||
// Removes element at specified position.
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// Removes element at specified index.
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeElement(index);
|
||||
}
|
||||
|
||||
void clear() const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->clear();
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool* _pool;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<ArrayConstRef> {
|
||||
static void toJson(VariantConstRef src, VariantRef dst) {
|
||||
variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
||||
}
|
||||
|
||||
static ArrayConstRef fromJson(VariantConstRef src) {
|
||||
return ArrayConstRef(variantAsArray(getData(src)));
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isArray();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<ArrayRef> {
|
||||
static void toJson(VariantConstRef src, VariantRef dst) {
|
||||
variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
||||
}
|
||||
|
||||
static ArrayRef fromJson(VariantRef src) {
|
||||
VariantData* data = getData(src);
|
||||
MemoryPool* pool = getPool(src);
|
||||
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
|
||||
}
|
||||
|
||||
static InvalidConversion<VariantConstRef, ArrayRef> fromJson(VariantConstRef);
|
||||
|
||||
static bool checkJson(VariantConstRef) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool checkJson(VariantRef src) {
|
||||
VariantData* data = getData(src);
|
||||
return data && data->isArray();
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user