trackler 2.2.1.53 → 2.2.1.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/nth-prime/canonical-data.json +2 -7
- data/problem-specifications/exercises/zebra-puzzle/canonical-data.json +16 -0
- data/tracks/c/config.json +11 -1
- data/tracks/c/docs/C_STYLE_GUIDE.md +142 -0
- data/tracks/c/exercises/collatz-conjecture/README.md +65 -0
- data/tracks/c/exercises/collatz-conjecture/makefile +15 -0
- data/tracks/c/exercises/collatz-conjecture/src/collatz_conjecture.h +8 -0
- data/tracks/c/exercises/collatz-conjecture/src/example.c +23 -0
- data/tracks/c/exercises/collatz-conjecture/test/test_collatz_conjecture.c +48 -0
- data/tracks/c/exercises/collatz-conjecture/test/vendor/unity.c +1300 -0
- data/tracks/c/exercises/collatz-conjecture/test/vendor/unity.h +274 -0
- data/tracks/c/exercises/collatz-conjecture/test/vendor/unity_internals.h +701 -0
- data/tracks/cfml/tasks/GenerateReadme.cfc +5 -5
- data/tracks/erlang/testgen/src/testgen.erl +99 -17
- data/tracks/erlang/testgen/src/tg_file_tools.erl +3 -3
- data/tracks/erlang/testgen/src/tgen.erl +15 -7
- data/tracks/haskell/config.json +15 -3
- data/tracks/java/scripts/canonical_data_check.sh +1 -1
- data/tracks/javascript/config.json +12 -0
- data/tracks/javascript/exercises/difference-of-squares/README.md +1 -1
- data/tracks/javascript/exercises/sum-of-multiples/README.md +1 -1
- data/tracks/javascript/exercises/zipper/README.md +55 -0
- data/tracks/javascript/exercises/zipper/example.js +100 -0
- data/tracks/javascript/exercises/zipper/zipper.spec.js +77 -0
- data/tracks/julia/config.json +12 -0
- data/tracks/julia/exercises/triangle/README.md +30 -0
- data/tracks/julia/exercises/triangle/example.jl +25 -0
- data/tracks/julia/exercises/triangle/runtests.jl +64 -0
- data/tracks/julia/exercises/triangle/triangle.jl +8 -0
- data/tracks/kotlin/exercises/leap/.meta/version +1 -1
- data/tracks/kotlin/exercises/leap/src/test/kotlin/LeapTest.kt +1 -1
- data/tracks/kotlin/scripts/canonical_data_check.sh +1 -1
- data/tracks/perl6/bin/README.md +1 -4
- data/tracks/perl6/bin/exercise-gen.pl6 +3 -4
- data/tracks/perl6/exercises/accumulate/example.yaml +2 -2
- data/tracks/perl6/exercises/all-your-base/example.yaml +9 -9
- data/tracks/perl6/exercises/allergies/example.yaml +7 -7
- data/tracks/perl6/exercises/anagram/example.yaml +3 -3
- data/tracks/perl6/exercises/atbash-cipher/example.yaml +3 -3
- data/tracks/perl6/exercises/bob/example.yaml +4 -4
- data/tracks/perl6/exercises/clock/example.yaml +6 -6
- data/tracks/perl6/exercises/flatten-array/example.yaml +4 -4
- data/tracks/perl6/exercises/grade-school/example.yaml +6 -6
- data/tracks/perl6/exercises/grains/example.yaml +3 -3
- data/tracks/perl6/exercises/hello-world/example.yaml +5 -5
- data/tracks/perl6/exercises/leap/example.yaml +4 -4
- data/tracks/perl6/exercises/linked-list/example.yaml +14 -14
- data/tracks/perl6/exercises/luhn/example.yaml +3 -3
- data/tracks/perl6/exercises/phone-number/example.yaml +3 -3
- data/tracks/perl6/exercises/raindrops/example.yaml +3 -3
- data/tracks/perl6/exercises/rna-transcription/example.yaml +3 -3
- data/tracks/perl6/exercises/robot-name/example.yaml +8 -8
- data/tracks/perl6/exercises/scrabble-score/example.yaml +3 -3
- data/tracks/perl6/exercises/space-age/example.yaml +8 -8
- data/tracks/perl6/exercises/word-count/example.yaml +3 -3
- data/tracks/perl6/exercises/wordy/example.yaml +3 -3
- data/tracks/python/config.json +14 -0
- data/tracks/python/config/maintainers.json +30 -0
- data/tracks/python/docs/EXERCISE_README_INSERT.md +1 -2
- data/tracks/python/exercises/accumulate/README.md +1 -5
- data/tracks/python/exercises/acronym/README.md +1 -3
- data/tracks/python/exercises/all-your-base/README.md +2 -3
- data/tracks/python/exercises/all-your-base/all_your_base_test.py +13 -13
- data/tracks/python/exercises/allergies/README.md +1 -3
- data/tracks/python/exercises/alphametics/README.md +3 -4
- data/tracks/python/exercises/anagram/README.md +1 -2
- data/tracks/python/exercises/atbash-cipher/README.md +3 -3
- data/tracks/python/exercises/beer-song/README.md +2 -3
- data/tracks/python/exercises/binary-search/README.md +1 -2
- data/tracks/python/exercises/binary/README.md +3 -2
- data/tracks/python/exercises/bob/README.md +1 -2
- data/tracks/python/exercises/book-store/README.md +6 -7
- data/tracks/python/exercises/bracket-push/README.md +1 -2
- data/tracks/python/exercises/change/README.md +2 -3
- data/tracks/python/exercises/circular-buffer/README.md +14 -8
- data/tracks/python/exercises/clock/README.md +1 -2
- data/tracks/python/exercises/clock/clock_test.py +2 -0
- data/tracks/python/exercises/collatz-conjecture/.meta/hints.md +3 -0
- data/tracks/python/exercises/collatz-conjecture/README.md +6 -19
- data/tracks/python/exercises/complex-numbers/README.md +28 -2
- data/tracks/python/exercises/crypto-square/README.md +11 -10
- data/tracks/python/exercises/diamond/README.md +7 -8
- data/tracks/python/exercises/difference-of-squares/README.md +1 -2
- data/tracks/python/exercises/diffie-hellman/.meta/hints.md +1 -1
- data/tracks/python/exercises/diffie-hellman/README.md +3 -2
- data/tracks/python/exercises/error-handling/.meta/hints.md +8 -0
- data/tracks/python/exercises/error-handling/README.md +10 -2
- data/tracks/python/exercises/error-handling/error_handling_test.py +15 -3
- data/tracks/python/exercises/etl/README.md +3 -2
- data/tracks/python/exercises/flatten-array/README.md +2 -4
- data/tracks/python/exercises/food-chain/README.md +3 -4
- data/tracks/python/exercises/forth/README.md +2 -6
- data/tracks/python/exercises/gigasecond/README.md +1 -2
- data/tracks/python/exercises/grade-school/README.md +1 -3
- data/tracks/python/exercises/grains/README.md +1 -3
- data/tracks/python/exercises/grep/README.md +13 -14
- data/tracks/python/exercises/hamming/README.md +1 -2
- data/tracks/python/exercises/hamming/hamming_test.py +6 -6
- data/tracks/python/exercises/hello-world/README.md +1 -2
- data/tracks/python/exercises/hexadecimal/README.md +1 -2
- data/tracks/python/exercises/hexadecimal/example.py +6 -6
- data/tracks/python/exercises/house/README.md +2 -4
- data/tracks/python/exercises/isogram/README.md +3 -3
- data/tracks/python/exercises/kindergarten-garden/README.md +14 -15
- data/tracks/python/exercises/largest-series-product/README.md +1 -2
- data/tracks/python/exercises/leap/README.md +2 -3
- data/tracks/python/exercises/linked-list/README.md +11 -12
- data/tracks/python/exercises/list-ops/README.md +1 -2
- data/tracks/python/exercises/luhn/README.md +8 -9
- data/tracks/python/exercises/markdown/README.md +1 -6
- data/tracks/python/exercises/matrix/README.md +7 -6
- data/tracks/python/exercises/meetup/README.md +2 -4
- data/tracks/python/exercises/minesweeper/README.md +1 -2
- data/tracks/python/exercises/nth-prime/README.md +1 -2
- data/tracks/python/exercises/nucleotide-count/README.md +9 -24
- data/tracks/python/exercises/ocr-numbers/README.md +6 -7
- data/tracks/python/exercises/octal/README.md +7 -4
- data/tracks/python/exercises/palindrome-products/README.md +16 -18
- data/tracks/python/exercises/pangram/README.md +2 -3
- data/tracks/python/exercises/pascals-triangle/README.md +2 -3
- data/tracks/python/exercises/perfect-numbers/README.md +3 -4
- data/tracks/python/exercises/phone-number/README.md +4 -4
- data/tracks/python/exercises/pig-latin/README.md +1 -2
- data/tracks/python/exercises/point-mutations/README.md +1 -2
- data/tracks/python/exercises/poker/README.md +1 -2
- data/tracks/python/exercises/prime-factors/README.md +1 -2
- data/tracks/python/exercises/protein-translation/README.md +5 -7
- data/tracks/python/exercises/proverb/README.md +12 -11
- data/tracks/python/exercises/pythagorean-triplet/README.md +4 -5
- data/tracks/python/exercises/queen-attack/README.md +2 -3
- data/tracks/python/exercises/rail-fence-cipher/README.md +13 -9
- data/tracks/python/exercises/raindrops/README.md +1 -2
- data/tracks/python/exercises/rectangles/README.md +8 -9
- data/tracks/python/exercises/rectangles/example.py +3 -3
- data/tracks/python/exercises/rna-transcription/README.md +1 -2
- data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +4 -3
- data/tracks/python/exercises/robot-name/README.md +1 -2
- data/tracks/python/exercises/robot-simulator/README.md +1 -2
- data/tracks/python/exercises/roman-numerals/README.md +2 -3
- data/tracks/python/exercises/rotational-cipher/README.md +3 -3
- data/tracks/python/exercises/run-length-encoding/README.md +5 -6
- data/tracks/python/exercises/run-length-encoding/example.py +2 -2
- data/tracks/python/exercises/saddle-points/README.md +2 -3
- data/tracks/python/exercises/say/README.md +1 -2
- data/tracks/python/exercises/scale-generator/README.md +1 -3
- data/tracks/python/exercises/scrabble-score/README.md +4 -3
- data/tracks/python/exercises/secret-handshake/README.md +2 -3
- data/tracks/python/exercises/series/README.md +1 -2
- data/tracks/python/exercises/sieve/README.md +1 -2
- data/tracks/python/exercises/simple-cipher/README.md +3 -4
- data/tracks/python/exercises/space-age/README.md +2 -3
- data/tracks/python/exercises/space-age/space_age_test.py +18 -29
- data/tracks/python/exercises/strain/README.md +1 -2
- data/tracks/python/exercises/sublist/README.md +1 -2
- data/tracks/python/exercises/sum-of-multiples/README.md +1 -5
- data/tracks/python/exercises/tournament/README.md +6 -7
- data/tracks/python/exercises/transpose/README.md +8 -9
- data/tracks/python/exercises/tree-building/README.md +25 -0
- data/tracks/python/exercises/tree-building/example.py +46 -0
- data/tracks/python/exercises/tree-building/tree_building.py +50 -0
- data/tracks/python/exercises/tree-building/tree_building_test.py +183 -0
- data/tracks/python/exercises/triangle/README.md +10 -8
- data/tracks/python/exercises/trinary/README.md +2 -3
- data/tracks/python/exercises/twelve-days/README.md +2 -3
- data/tracks/python/exercises/two-bucket/README.md +4 -5
- data/tracks/python/exercises/two-bucket/two_bucket_test.py +2 -0
- data/tracks/python/exercises/two-fer/README.md +4 -5
- data/tracks/python/exercises/two-fer/two_fer_test.py +5 -2
- data/tracks/python/exercises/variable-length-quantity/README.md +7 -9
- data/tracks/python/exercises/word-count/README.md +2 -4
- data/tracks/python/exercises/word-search/README.md +2 -3
- data/tracks/python/exercises/wordy/README.md +1 -7
- data/tracks/python/exercises/wordy/example.py +8 -8
- data/tracks/python/exercises/wordy/wordy_test.py +36 -32
- data/tracks/python/exercises/zebra-puzzle/README.md +1 -2
- data/tracks/python/requirements-travis.txt +1 -1
- data/tracks/ruby/config.json +11 -0
- data/tracks/ruby/docs/TESTS.md +6 -0
- data/tracks/ruby/exercises/pangram/.meta/.version +1 -1
- data/tracks/ruby/exercises/pangram/.meta/solutions/pangram.rb +1 -1
- data/tracks/ruby/exercises/pangram/pangram_test.rb +11 -4
- data/tracks/ruby/exercises/two-fer/.meta/.version +1 -0
- data/tracks/ruby/exercises/two-fer/.meta/generator/two_fer_case.rb +12 -0
- data/tracks/ruby/exercises/two-fer/.meta/solutions/two_fer.rb +9 -0
- data/tracks/ruby/exercises/two-fer/README.md +69 -0
- data/tracks/ruby/exercises/two-fer/two_fer_test.rb +42 -0
- data/tracks/rust/config.json +12 -0
- data/tracks/rust/exercises/binary-search/.meta/hints.md +38 -0
- data/tracks/rust/exercises/binary-search/Cargo.lock +4 -0
- data/tracks/rust/exercises/binary-search/Cargo.toml +6 -0
- data/tracks/rust/exercises/binary-search/README.md +113 -0
- data/tracks/rust/exercises/binary-search/example.rs +29 -0
- data/tracks/rust/exercises/binary-search/src/lib.rs +0 -0
- data/tracks/rust/exercises/binary-search/tests/binary-search.rs +96 -0
- data/tracks/typescript/common/package.json +6 -6
- data/tracks/typescript/common/yarn.lock +929 -610
- data/tracks/typescript/exercises/acronym/package.json +6 -6
- data/tracks/typescript/exercises/acronym/yarn.lock +929 -610
- data/tracks/typescript/exercises/anagram/package.json +6 -6
- data/tracks/typescript/exercises/anagram/yarn.lock +929 -610
- data/tracks/typescript/exercises/beer-song/package.json +6 -6
- data/tracks/typescript/exercises/beer-song/yarn.lock +929 -610
- data/tracks/typescript/exercises/binary-search-tree/package.json +6 -6
- data/tracks/typescript/exercises/binary-search-tree/yarn.lock +929 -610
- data/tracks/typescript/exercises/binary-search/package.json +6 -6
- data/tracks/typescript/exercises/binary-search/yarn.lock +929 -610
- data/tracks/typescript/exercises/bob/package.json +6 -6
- data/tracks/typescript/exercises/bob/yarn.lock +929 -610
- data/tracks/typescript/exercises/circular-buffer/package.json +6 -6
- data/tracks/typescript/exercises/circular-buffer/yarn.lock +929 -610
- data/tracks/typescript/exercises/clock/package.json +6 -6
- data/tracks/typescript/exercises/clock/yarn.lock +929 -610
- data/tracks/typescript/exercises/difference-of-squares/package.json +6 -6
- data/tracks/typescript/exercises/difference-of-squares/yarn.lock +929 -610
- data/tracks/typescript/exercises/etl/package.json +6 -6
- data/tracks/typescript/exercises/etl/yarn.lock +929 -610
- data/tracks/typescript/exercises/food-chain/package.json +6 -6
- data/tracks/typescript/exercises/food-chain/yarn.lock +929 -610
- data/tracks/typescript/exercises/gigasecond/package.json +6 -6
- data/tracks/typescript/exercises/gigasecond/yarn.lock +929 -610
- data/tracks/typescript/exercises/grade-school/package.json +6 -6
- data/tracks/typescript/exercises/grade-school/yarn.lock +929 -610
- data/tracks/typescript/exercises/hamming/package.json +6 -6
- data/tracks/typescript/exercises/hamming/yarn.lock +929 -610
- data/tracks/typescript/exercises/hello-world/README.md +354 -0
- data/tracks/typescript/exercises/hello-world/package.json +6 -6
- data/tracks/typescript/exercises/hello-world/yarn.lock +929 -610
- data/tracks/typescript/exercises/largest-series-product/package.json +6 -6
- data/tracks/typescript/exercises/largest-series-product/yarn.lock +929 -610
- data/tracks/typescript/exercises/leap/package.json +6 -6
- data/tracks/typescript/exercises/leap/yarn.lock +929 -610
- data/tracks/typescript/exercises/linked-list/package.json +6 -6
- data/tracks/typescript/exercises/linked-list/yarn.lock +929 -610
- data/tracks/typescript/exercises/nth-prime/package.json +6 -6
- data/tracks/typescript/exercises/nth-prime/yarn.lock +929 -610
- data/tracks/typescript/exercises/pangram/package.json +6 -6
- data/tracks/typescript/exercises/pangram/yarn.lock +929 -610
- data/tracks/typescript/exercises/pascals-triangle/package.json +6 -6
- data/tracks/typescript/exercises/pascals-triangle/yarn.lock +929 -610
- data/tracks/typescript/exercises/phone-number/package.json +6 -6
- data/tracks/typescript/exercises/phone-number/yarn.lock +929 -610
- data/tracks/typescript/exercises/prime-factors/package.json +6 -6
- data/tracks/typescript/exercises/prime-factors/yarn.lock +929 -610
- data/tracks/typescript/exercises/raindrops/package.json +6 -6
- data/tracks/typescript/exercises/raindrops/yarn.lock +929 -610
- data/tracks/typescript/exercises/rna-transcription/package.json +6 -6
- data/tracks/typescript/exercises/rna-transcription/yarn.lock +929 -610
- data/tracks/typescript/exercises/robot-name/package.json +6 -6
- data/tracks/typescript/exercises/robot-name/yarn.lock +929 -610
- data/tracks/typescript/exercises/robot-simulator/package.json +6 -6
- data/tracks/typescript/exercises/robot-simulator/yarn.lock +929 -610
- data/tracks/typescript/exercises/rotational-cipher/package.json +6 -6
- data/tracks/typescript/exercises/rotational-cipher/yarn.lock +929 -610
- data/tracks/typescript/exercises/say/package.json +6 -6
- data/tracks/typescript/exercises/say/yarn.lock +929 -610
- data/tracks/typescript/exercises/scrabble-score/package.json +6 -6
- data/tracks/typescript/exercises/scrabble-score/yarn.lock +929 -610
- data/tracks/typescript/exercises/series/package.json +6 -6
- data/tracks/typescript/exercises/series/yarn.lock +929 -610
- data/tracks/typescript/exercises/space-age/package.json +6 -6
- data/tracks/typescript/exercises/space-age/yarn.lock +929 -610
- data/tracks/typescript/exercises/strain/package.json +6 -6
- data/tracks/typescript/exercises/strain/yarn.lock +929 -610
- data/tracks/typescript/exercises/sum-of-multiples/package.json +6 -6
- data/tracks/typescript/exercises/sum-of-multiples/yarn.lock +929 -610
- data/tracks/typescript/exercises/triangle/package.json +6 -6
- data/tracks/typescript/exercises/triangle/yarn.lock +929 -610
- data/tracks/typescript/exercises/word-count/package.json +6 -6
- data/tracks/typescript/exercises/word-count/yarn.lock +929 -610
- data/tracks/typescript/exercises/wordy/package.json +6 -6
- data/tracks/typescript/exercises/wordy/yarn.lock +929 -610
- metadata +37 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be3a7560b591e9d0b49742ad5c78952c2784da5e
|
|
4
|
+
data.tar.gz: 43b0106fc44e0dbdce1ca20f724fa0328fd02dab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b9ecd12a8ee1d79412baf3d4391d356fb914308a6319bde49c5a3a7dcb9371aadbc61785ca2ccce9e78acd4e816f0bfad89e3fb48c29be5404dcf3c1e80345d9
|
|
7
|
+
data.tar.gz: 4726e0b3b38c1e65f613096ad04ebefdddede22a515fdaaa84396567527aef221e0c989bfb92f563d09cf100fa0cae765e5a81e23f0be5f107fe6a88a5179d41
|
data/lib/trackler/version.rb
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"exercise": "nth-prime",
|
|
3
|
-
"version": "
|
|
4
|
-
"comments": [
|
|
5
|
-
"The tests that expect 'false' should be implemented to raise",
|
|
6
|
-
"an error, or indicate a failure. Implement this in a way that",
|
|
7
|
-
"makes sense for your language."
|
|
8
|
-
],
|
|
3
|
+
"version": "2.0.0",
|
|
9
4
|
"cases": [
|
|
10
5
|
{
|
|
11
6
|
"description": "first prime",
|
|
@@ -35,7 +30,7 @@
|
|
|
35
30
|
"description": "there is no zeroth prime",
|
|
36
31
|
"property": "prime",
|
|
37
32
|
"input": 0,
|
|
38
|
-
"expected":
|
|
33
|
+
"expected": { "error": "there is no zeroth prime" }
|
|
39
34
|
}
|
|
40
35
|
]
|
|
41
36
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"exercise": "zebra-puzzle",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"cases": [
|
|
5
|
+
{
|
|
6
|
+
"description": "resident who drinks water",
|
|
7
|
+
"property": "drinksWater",
|
|
8
|
+
"expected": "Norwegian"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"description": "resident who owns zebra",
|
|
12
|
+
"property": "ownsZebra",
|
|
13
|
+
"expected": "Japanese"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
data/tracks/c/config.json
CHANGED
|
@@ -442,8 +442,18 @@
|
|
|
442
442
|
],
|
|
443
443
|
"unlocked_by": "atbash-cipher",
|
|
444
444
|
"uuid": "55b87cc2-c3a0-438a-b2b6-116ad6356802"
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"core": false,
|
|
448
|
+
"difficulty": 2,
|
|
449
|
+
"slug": "collatz-conjecture",
|
|
450
|
+
"topics": [
|
|
451
|
+
"functions",
|
|
452
|
+
"mathematics"
|
|
453
|
+
],
|
|
454
|
+
"uuid": "1f68f837-6432-4f9e-afae-0cb17f8e0153"
|
|
445
455
|
}
|
|
446
456
|
],
|
|
447
457
|
"foregone": [],
|
|
448
458
|
"language": "C"
|
|
449
|
-
}
|
|
459
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# C Style Guide
|
|
2
|
+
|
|
3
|
+
This guide describes the style intended for use with the C track exercise example and test files.
|
|
4
|
+
|
|
5
|
+
The rules within this guide are in addition to, or to call out, those in the [Linux kernel coding style guide](https://www.kernel.org/doc/html/latest/process/coding-style.html).
|
|
6
|
+
|
|
7
|
+
## Names
|
|
8
|
+
|
|
9
|
+
In general, the names of types, variables, structures and files should use snake case with all letters in lower case and underscores `_` are used to separate name components.
|
|
10
|
+
|
|
11
|
+
```c
|
|
12
|
+
void some_foo_function(char * input_string, int input_string_length);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Enums
|
|
16
|
+
|
|
17
|
+
Enum names should usually be singular rather than plural.
|
|
18
|
+
|
|
19
|
+
Enum labels should use snake case with all letters in upper case.
|
|
20
|
+
|
|
21
|
+
```c
|
|
22
|
+
enum heading {
|
|
23
|
+
HEADING_NORTH,
|
|
24
|
+
HEADING_EAST,
|
|
25
|
+
HEADING_SOUTH,
|
|
26
|
+
HEADING_WEST
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Macros
|
|
31
|
+
|
|
32
|
+
Macros defining constants are named using snake case with all letters in upper case.
|
|
33
|
+
|
|
34
|
+
```c
|
|
35
|
+
#define CONSTANT 0x4000
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Upper-case snake case for macro names is appreciated, but macros resembling functions may be named in lower-case snake case.
|
|
39
|
+
|
|
40
|
+
### Types
|
|
41
|
+
|
|
42
|
+
Types defined by a program using `typedef` should be named with a `_t` suffix.
|
|
43
|
+
While aware that POSIX reserves the `_t` suffix, the track does not currently utilise POSIX.
|
|
44
|
+
|
|
45
|
+
## Parameters
|
|
46
|
+
|
|
47
|
+
Function parameters should be named in both the declaration and definition of all functions. This applies to both `.c` and `.h` files.
|
|
48
|
+
The names used should match in all instances.
|
|
49
|
+
That is to say that while the following function prototype is valid C, the style is incorrect because the parameter is unnamed: `void foo(int);`.
|
|
50
|
+
The correct prototype, providing that all other declarations and the definition also use the parameter name `bar`, would be `void foo(int bar);`.
|
|
51
|
+
|
|
52
|
+
## Indentation and Format
|
|
53
|
+
|
|
54
|
+
The repository uses GNU `indent`, as outlined in the [README](https://github.com/exercism/c/blob/master/README.md).
|
|
55
|
+
|
|
56
|
+
The options described for use with indent there are `-linux -i3 -nut`. The `-linux` option is a shortcut that is equivelent to a secific fixed group of options. The combined equivalent options are `-nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0 -d0 -di1 -nfc1 -i3 -nut -ip0 -l80 -lp -npcs -nprs -npsl -sai -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -il1`.
|
|
57
|
+
|
|
58
|
+
What these options do is indicated by the [GNU `indent` manual](https://www.gnu.org/software/indent/manual/indent.html#SEC4), but is also described here for easy reference if editing files manually.
|
|
59
|
+
|
|
60
|
+
- `nbad` - Do _not_ force blank lines after every block of declarations
|
|
61
|
+
- `bap` - Force a black line after every function body
|
|
62
|
+
- `nbc` - Do _not_ force a newline after each comma in a declaration
|
|
63
|
+
- `bbo` - Prefer to break long lines before the boolean operators `&&` and `||`
|
|
64
|
+
- `hnl` - Honour newlines in the file by giving them the highest possible priority to break lines at
|
|
65
|
+
- `br` - Place an opening brace on the same line as the `if (condition)`
|
|
66
|
+
- `brs` - Place an opening brace on same line as `struct struct_name`
|
|
67
|
+
- `c33` - Put comments to the right of code in column 33
|
|
68
|
+
- `cd33` - Put comments to the right of the declarations in column 33
|
|
69
|
+
- `ncdb` - Do _not_ put comment delimiters on blank lines
|
|
70
|
+
- `ce` - Place the `else` on the same line as the preceding closing brace, so the it is 'cuddled' like so `} else {`
|
|
71
|
+
- `ci4` - Indent by 4 spaces for hard line-breaks within statements (continuation indentation)
|
|
72
|
+
- `cli0` - Indent case labels by 0 spaces to the right of the containing switch statement
|
|
73
|
+
- `d0` - Set indentation of comments, that are _not_ to the right of code, to 0 spaces.
|
|
74
|
+
- `di1` - Line up identifiers in the first column
|
|
75
|
+
- `nfc1` - Do _not_ format comments that are in the first column
|
|
76
|
+
- `i3` - Set the indentation level to 3 spaces
|
|
77
|
+
- `nut` - Use spaces instead of tabs
|
|
78
|
+
- `ip0` - Use 0 extra offset indentation for breaks between two or more parenthesis pairs `(...)`
|
|
79
|
+
- `l80` - The maximum length of a line of C code is 80, not including possible comments that follow it
|
|
80
|
+
- `lp` - Line up continued lines at parentheses
|
|
81
|
+
- `npcs` - Do _not_ put space between the name of the function being called and the ‘(’, eg `puts("Hi");` not `puts ("Hi");`)
|
|
82
|
+
- `nprs` - Do _not_ put a space after every '(' and before every ')'
|
|
83
|
+
- `npsl` - Put the type of a function on the same line as its name
|
|
84
|
+
- `sai` - Force a space between an `if` and the following parenthesis
|
|
85
|
+
- `saf` - Force a space between a `for` and the following parenthesis
|
|
86
|
+
- `saw` - Force a space between a `while` and the following parenthesis
|
|
87
|
+
- `ncs` - Do _not_ put a space after cast operators
|
|
88
|
+
- `sob` - Swallow (remove) any optional blank lines
|
|
89
|
+
- `nfca` - Do _not_ format any comments
|
|
90
|
+
- `cp33` - Put comments to the right of `#else` and `#endif` statements in column 33
|
|
91
|
+
- `ss` - On one-line `for` and `while` statements, force a blank before the semicolon, like so `while (condition) ;`
|
|
92
|
+
- `il1` - Set the offset for labels to column 1
|
|
93
|
+
|
|
94
|
+
## Test file layout
|
|
95
|
+
|
|
96
|
+
Each exercise's test file follows a particular layout.
|
|
97
|
+
The layout is intended to both help contibutors to identify parts of the file, and to help learners to understand how the tests work.
|
|
98
|
+
|
|
99
|
+
Like most C source files, a test file begins with includes.
|
|
100
|
+
|
|
101
|
+
```c
|
|
102
|
+
#include "vendor/unity.h"
|
|
103
|
+
#include "../src/file_under_test.h"
|
|
104
|
+
// any other includes here
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The includes are then followed by any helper functions that are used by the test functions.
|
|
108
|
+
The names of such helper functions should not use the `test_` prefix.
|
|
109
|
+
|
|
110
|
+
Next, there are the `setUp()` and `tearDown()` functions.
|
|
111
|
+
So far, no exercise uses these (the function bodies are empty) yet they must remain in place to allow the test files to compile correctly across all platforms.
|
|
112
|
+
|
|
113
|
+
```c
|
|
114
|
+
void setUp(void)
|
|
115
|
+
{
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
void tearDown(void)
|
|
119
|
+
{
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Next are the test functions themselves.
|
|
124
|
+
The names of these functions use a `test_` prefix.
|
|
125
|
+
|
|
126
|
+
Last in the file is the `main()` function.
|
|
127
|
+
The function body of main follows a particular layout itself.
|
|
128
|
+
First a call to `UnityBegin()` followed by an empty line, then the tests.
|
|
129
|
+
The last test is followed by another empty line and then a call to `UnityEnd()`, before returning.
|
|
130
|
+
|
|
131
|
+
```c
|
|
132
|
+
int main(void)
|
|
133
|
+
{
|
|
134
|
+
UnityBegin("test/test_file_name.c");
|
|
135
|
+
|
|
136
|
+
RUN_TEST(test_foo);
|
|
137
|
+
RUN_TEST(test_bar);
|
|
138
|
+
|
|
139
|
+
UnityEnd();
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Collatz Conjecture
|
|
2
|
+
|
|
3
|
+
The Collatz Conjecture or 3x+1 problem can be summarized as follows:
|
|
4
|
+
|
|
5
|
+
Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is
|
|
6
|
+
odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely.
|
|
7
|
+
The conjecture states that no matter which number you start with, you will
|
|
8
|
+
always reach 1 eventually.
|
|
9
|
+
|
|
10
|
+
Given a number n, return the number of steps required to reach 1.
|
|
11
|
+
|
|
12
|
+
## Examples
|
|
13
|
+
|
|
14
|
+
Starting with n = 12, the steps would be as follows:
|
|
15
|
+
|
|
16
|
+
0. 12
|
|
17
|
+
1. 6
|
|
18
|
+
2. 3
|
|
19
|
+
3. 10
|
|
20
|
+
4. 5
|
|
21
|
+
5. 16
|
|
22
|
+
6. 8
|
|
23
|
+
7. 4
|
|
24
|
+
8. 2
|
|
25
|
+
9. 1
|
|
26
|
+
|
|
27
|
+
Resulting in 9 steps. So for input n = 12, the return value would be 9.
|
|
28
|
+
|
|
29
|
+
## Getting Started
|
|
30
|
+
|
|
31
|
+
Make sure you have read the
|
|
32
|
+
[C page](http://exercism.io/languages/c) on the Exercism site. This covers
|
|
33
|
+
the basic information on setting up the development environment expected
|
|
34
|
+
by the exercises.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## Passing the Tests
|
|
38
|
+
|
|
39
|
+
Get the first test compiling, linking and passing by following the [three
|
|
40
|
+
rules of test-driven development][3-tdd-rules].
|
|
41
|
+
|
|
42
|
+
The included makefile can be used to create and run the tests using the `test`
|
|
43
|
+
task.
|
|
44
|
+
|
|
45
|
+
make test
|
|
46
|
+
|
|
47
|
+
Create just the functions you need to satisfy any compiler errors and get the
|
|
48
|
+
test to fail. Then write just enough code to get the test to pass. Once you've
|
|
49
|
+
done that, move onto the next test.
|
|
50
|
+
|
|
51
|
+
[3-tdd-rules]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
|
52
|
+
|
|
53
|
+
As you progress through the tests, take the time to refactor your
|
|
54
|
+
implementation for readability and expressiveness and then go on to the next
|
|
55
|
+
test.
|
|
56
|
+
|
|
57
|
+
Try to use standard C99 facilities in preference to writing your own
|
|
58
|
+
low-level algorithms or facilities by hand.
|
|
59
|
+
|
|
60
|
+
## Source
|
|
61
|
+
|
|
62
|
+
Wikipedia [https://en.wikipedia.org/wiki/Collatz_conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture)
|
|
63
|
+
|
|
64
|
+
## Submitting Incomplete Solutions
|
|
65
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
CFLAGS = -std=c99
|
|
2
|
+
CFLAGS += -Wall
|
|
3
|
+
CFLAGS += -Wextra
|
|
4
|
+
CFLAGS += -pedantic
|
|
5
|
+
CFLAGS += -Werror
|
|
6
|
+
|
|
7
|
+
test: tests.out
|
|
8
|
+
@./tests.out
|
|
9
|
+
|
|
10
|
+
clean:
|
|
11
|
+
rm -f *.o *.out
|
|
12
|
+
|
|
13
|
+
tests.out: test/test_collatz_conjecture.c src/collatz_conjecture.c src/collatz_conjecture.h
|
|
14
|
+
@echo Compiling $@
|
|
15
|
+
@cc $(CFLAGS) src/collatz_conjecture.c test/vendor/unity.c test/test_collatz_conjecture.c -o tests.out
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#include "collatz_conjecture.h"
|
|
2
|
+
#include <stdbool.h>
|
|
3
|
+
|
|
4
|
+
int steps(int start)
|
|
5
|
+
{
|
|
6
|
+
int step = 0;
|
|
7
|
+
int number = start;
|
|
8
|
+
|
|
9
|
+
if (start <= 0) {
|
|
10
|
+
return ERROR_VALUE;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
while (number != 1) {
|
|
14
|
+
step++;
|
|
15
|
+
|
|
16
|
+
if (number % 2 == 0) {
|
|
17
|
+
number /= 2;
|
|
18
|
+
} else {
|
|
19
|
+
number = (number * 3) + 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return step;
|
|
23
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#include "../src/collatz_conjecture.h"
|
|
2
|
+
|
|
3
|
+
#include "vendor/unity.h"
|
|
4
|
+
|
|
5
|
+
void test_zero_steps_for_one(void)
|
|
6
|
+
{
|
|
7
|
+
TEST_ASSERT_EQUAL(0, steps(1));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
void test_divide_if_even(void)
|
|
11
|
+
{
|
|
12
|
+
TEST_ASSERT_EQUAL(4, steps(16));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
void test_even_and_odd_steps(void)
|
|
16
|
+
{
|
|
17
|
+
TEST_ASSERT_EQUAL(9, steps(12));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
void test_large_number_of_even_and_odd_steps(void)
|
|
21
|
+
{
|
|
22
|
+
TEST_ASSERT_EQUAL(152, steps(1000000));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void test_zero_is_an_error(void)
|
|
26
|
+
{
|
|
27
|
+
TEST_ASSERT_EQUAL(ERROR_VALUE, steps(0));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void test_negative_value_is_an_error(void)
|
|
31
|
+
{
|
|
32
|
+
TEST_ASSERT_EQUAL(ERROR_VALUE, steps(-15));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
int main(void)
|
|
36
|
+
{
|
|
37
|
+
UnityBegin("collatz_conjecture.c");
|
|
38
|
+
|
|
39
|
+
RUN_TEST(test_zero_steps_for_one);
|
|
40
|
+
RUN_TEST(test_divide_if_even);
|
|
41
|
+
RUN_TEST(test_even_and_odd_steps);
|
|
42
|
+
RUN_TEST(test_large_number_of_even_and_odd_steps);
|
|
43
|
+
RUN_TEST(test_zero_is_an_error);
|
|
44
|
+
RUN_TEST(test_negative_value_is_an_error);
|
|
45
|
+
|
|
46
|
+
UnityEnd();
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
@@ -0,0 +1,1300 @@
|
|
|
1
|
+
/* =========================================================================
|
|
2
|
+
Unity Project - A Test Framework for C
|
|
3
|
+
Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams
|
|
4
|
+
[Released under MIT License. Please refer to license.txt for details]
|
|
5
|
+
============================================================================ */
|
|
6
|
+
|
|
7
|
+
#include "unity.h"
|
|
8
|
+
#include <stddef.h>
|
|
9
|
+
|
|
10
|
+
#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; longjmp(Unity.AbortFrame, 1); }
|
|
11
|
+
#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); }
|
|
12
|
+
/// return prematurely if we are already in failure or ignore state
|
|
13
|
+
#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} }
|
|
14
|
+
#define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\n'); }
|
|
15
|
+
|
|
16
|
+
struct _Unity Unity;
|
|
17
|
+
|
|
18
|
+
const char UnityStrOk[] = "OK";
|
|
19
|
+
const char UnityStrPass[] = "PASS";
|
|
20
|
+
const char UnityStrFail[] = "FAIL";
|
|
21
|
+
const char UnityStrIgnore[] = "IGNORE";
|
|
22
|
+
const char UnityStrNull[] = "NULL";
|
|
23
|
+
const char UnityStrSpacer[] = ". ";
|
|
24
|
+
const char UnityStrExpected[] = " Expected ";
|
|
25
|
+
const char UnityStrWas[] = " Was ";
|
|
26
|
+
const char UnityStrTo[] = " To ";
|
|
27
|
+
const char UnityStrElement[] = " Element ";
|
|
28
|
+
const char UnityStrByte[] = " Byte ";
|
|
29
|
+
const char UnityStrMemory[] = " Memory Mismatch.";
|
|
30
|
+
const char UnityStrDelta[] = " Values Not Within Delta ";
|
|
31
|
+
const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless.";
|
|
32
|
+
const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL";
|
|
33
|
+
const char UnityStrNullPointerForActual[] = " Actual pointer was NULL";
|
|
34
|
+
const char UnityStrNot[] = "Not ";
|
|
35
|
+
const char UnityStrInf[] = "Infinity";
|
|
36
|
+
const char UnityStrNegInf[] = "Negative Infinity";
|
|
37
|
+
const char UnityStrNaN[] = "NaN";
|
|
38
|
+
const char UnityStrDet[] = "Determinate";
|
|
39
|
+
const char UnityStrErrFloat[] = "Unity Floating Point Disabled";
|
|
40
|
+
const char UnityStrErrDouble[] = "Unity Double Precision Disabled";
|
|
41
|
+
const char UnityStrErr64[] = "Unity 64-bit Support Disabled";
|
|
42
|
+
const char UnityStrBreaker[] = "-----------------------";
|
|
43
|
+
const char UnityStrResultsTests[] = " Tests ";
|
|
44
|
+
const char UnityStrResultsFailures[] = " Failures ";
|
|
45
|
+
const char UnityStrResultsIgnored[] = " Ignored ";
|
|
46
|
+
|
|
47
|
+
#ifndef UNITY_EXCLUDE_FLOAT
|
|
48
|
+
// Dividing by these constants produces +/- infinity.
|
|
49
|
+
// The rationale is given in UnityAssertFloatIsInf's body.
|
|
50
|
+
static const _UF f_zero = 0.0f;
|
|
51
|
+
#ifndef UNITY_EXCLUDE_DOUBLE
|
|
52
|
+
static const _UD d_zero = 0.0;
|
|
53
|
+
#endif
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
// compiler-generic print formatting masks
|
|
57
|
+
const _U_UINT UnitySizeMask[] =
|
|
58
|
+
{
|
|
59
|
+
255u, // 0xFF
|
|
60
|
+
65535u, // 0xFFFF
|
|
61
|
+
65535u,
|
|
62
|
+
4294967295u, // 0xFFFFFFFF
|
|
63
|
+
4294967295u,
|
|
64
|
+
4294967295u,
|
|
65
|
+
4294967295u
|
|
66
|
+
#ifdef UNITY_SUPPORT_64
|
|
67
|
+
,0xFFFFFFFFFFFFFFFF
|
|
68
|
+
#endif
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
void UnityPrintFail(void);
|
|
72
|
+
void UnityPrintOk(void);
|
|
73
|
+
|
|
74
|
+
//-----------------------------------------------
|
|
75
|
+
// Pretty Printers & Test Result Output Handlers
|
|
76
|
+
//-----------------------------------------------
|
|
77
|
+
|
|
78
|
+
void UnityPrint(const char* string)
|
|
79
|
+
{
|
|
80
|
+
const char* pch = string;
|
|
81
|
+
|
|
82
|
+
if (pch != NULL)
|
|
83
|
+
{
|
|
84
|
+
while (*pch)
|
|
85
|
+
{
|
|
86
|
+
// printable characters plus CR & LF are printed
|
|
87
|
+
if ((*pch <= 126) && (*pch >= 32))
|
|
88
|
+
{
|
|
89
|
+
UNITY_OUTPUT_CHAR(*pch);
|
|
90
|
+
}
|
|
91
|
+
//write escaped carriage returns
|
|
92
|
+
else if (*pch == 13)
|
|
93
|
+
{
|
|
94
|
+
UNITY_OUTPUT_CHAR('\\');
|
|
95
|
+
UNITY_OUTPUT_CHAR('r');
|
|
96
|
+
}
|
|
97
|
+
//write escaped line feeds
|
|
98
|
+
else if (*pch == 10)
|
|
99
|
+
{
|
|
100
|
+
UNITY_OUTPUT_CHAR('\\');
|
|
101
|
+
UNITY_OUTPUT_CHAR('n');
|
|
102
|
+
}
|
|
103
|
+
// unprintable characters are shown as codes
|
|
104
|
+
else
|
|
105
|
+
{
|
|
106
|
+
UNITY_OUTPUT_CHAR('\\');
|
|
107
|
+
UnityPrintNumberHex((_U_UINT)*pch, 2);
|
|
108
|
+
}
|
|
109
|
+
pch++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
void UnityPrintLen(const char* string, const _UU32 length);
|
|
115
|
+
void UnityPrintLen(const char* string, const _UU32 length)
|
|
116
|
+
{
|
|
117
|
+
const char* pch = string;
|
|
118
|
+
|
|
119
|
+
if (pch != NULL)
|
|
120
|
+
{
|
|
121
|
+
while (*pch && (_UU32)(pch - string) < length)
|
|
122
|
+
{
|
|
123
|
+
// printable characters plus CR & LF are printed
|
|
124
|
+
if ((*pch <= 126) && (*pch >= 32))
|
|
125
|
+
{
|
|
126
|
+
UNITY_OUTPUT_CHAR(*pch);
|
|
127
|
+
}
|
|
128
|
+
//write escaped carriage returns
|
|
129
|
+
else if (*pch == 13)
|
|
130
|
+
{
|
|
131
|
+
UNITY_OUTPUT_CHAR('\\');
|
|
132
|
+
UNITY_OUTPUT_CHAR('r');
|
|
133
|
+
}
|
|
134
|
+
//write escaped line feeds
|
|
135
|
+
else if (*pch == 10)
|
|
136
|
+
{
|
|
137
|
+
UNITY_OUTPUT_CHAR('\\');
|
|
138
|
+
UNITY_OUTPUT_CHAR('n');
|
|
139
|
+
}
|
|
140
|
+
// unprintable characters are shown as codes
|
|
141
|
+
else
|
|
142
|
+
{
|
|
143
|
+
UNITY_OUTPUT_CHAR('\\');
|
|
144
|
+
UnityPrintNumberHex((_U_UINT)*pch, 2);
|
|
145
|
+
}
|
|
146
|
+
pch++;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//-----------------------------------------------
|
|
152
|
+
void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style)
|
|
153
|
+
{
|
|
154
|
+
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
|
|
155
|
+
{
|
|
156
|
+
UnityPrintNumber(number);
|
|
157
|
+
}
|
|
158
|
+
else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT)
|
|
159
|
+
{
|
|
160
|
+
UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] );
|
|
161
|
+
}
|
|
162
|
+
else
|
|
163
|
+
{
|
|
164
|
+
UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//-----------------------------------------------
|
|
169
|
+
/// basically do an itoa using as little ram as possible
|
|
170
|
+
void UnityPrintNumber(const _U_SINT number_to_print)
|
|
171
|
+
{
|
|
172
|
+
_U_SINT divisor = 1;
|
|
173
|
+
_U_SINT next_divisor;
|
|
174
|
+
_U_UINT number;
|
|
175
|
+
|
|
176
|
+
if (number_to_print == (1l << (UNITY_LONG_WIDTH-1)))
|
|
177
|
+
{
|
|
178
|
+
//The largest representable negative number
|
|
179
|
+
UNITY_OUTPUT_CHAR('-');
|
|
180
|
+
number = (1ul << (UNITY_LONG_WIDTH-1));
|
|
181
|
+
}
|
|
182
|
+
else if (number_to_print < 0)
|
|
183
|
+
{
|
|
184
|
+
//Some other negative number
|
|
185
|
+
UNITY_OUTPUT_CHAR('-');
|
|
186
|
+
number = (_U_UINT)(-number_to_print);
|
|
187
|
+
}
|
|
188
|
+
else
|
|
189
|
+
{
|
|
190
|
+
//Positive number
|
|
191
|
+
number = (_U_UINT)number_to_print;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// figure out initial divisor
|
|
195
|
+
while (number / divisor > 9)
|
|
196
|
+
{
|
|
197
|
+
next_divisor = divisor * 10;
|
|
198
|
+
if (next_divisor > divisor)
|
|
199
|
+
divisor = next_divisor;
|
|
200
|
+
else
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// now mod and print, then divide divisor
|
|
205
|
+
do
|
|
206
|
+
{
|
|
207
|
+
UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
|
|
208
|
+
divisor /= 10;
|
|
209
|
+
}
|
|
210
|
+
while (divisor > 0);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
//-----------------------------------------------
|
|
214
|
+
/// basically do an itoa using as little ram as possible
|
|
215
|
+
void UnityPrintNumberUnsigned(const _U_UINT number)
|
|
216
|
+
{
|
|
217
|
+
_U_UINT divisor = 1;
|
|
218
|
+
_U_UINT next_divisor;
|
|
219
|
+
|
|
220
|
+
// figure out initial divisor
|
|
221
|
+
while (number / divisor > 9)
|
|
222
|
+
{
|
|
223
|
+
next_divisor = divisor * 10;
|
|
224
|
+
if (next_divisor > divisor)
|
|
225
|
+
divisor = next_divisor;
|
|
226
|
+
else
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// now mod and print, then divide divisor
|
|
231
|
+
do
|
|
232
|
+
{
|
|
233
|
+
UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
|
|
234
|
+
divisor /= 10;
|
|
235
|
+
}
|
|
236
|
+
while (divisor > 0);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//-----------------------------------------------
|
|
240
|
+
void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print)
|
|
241
|
+
{
|
|
242
|
+
_U_UINT nibble;
|
|
243
|
+
char nibbles = nibbles_to_print;
|
|
244
|
+
UNITY_OUTPUT_CHAR('0');
|
|
245
|
+
UNITY_OUTPUT_CHAR('x');
|
|
246
|
+
|
|
247
|
+
while (nibbles > 0)
|
|
248
|
+
{
|
|
249
|
+
nibble = (number >> (--nibbles << 2)) & 0x0000000F;
|
|
250
|
+
if (nibble <= 9)
|
|
251
|
+
{
|
|
252
|
+
UNITY_OUTPUT_CHAR((char)('0' + nibble));
|
|
253
|
+
}
|
|
254
|
+
else
|
|
255
|
+
{
|
|
256
|
+
UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
//-----------------------------------------------
|
|
262
|
+
void UnityPrintMask(const _U_UINT mask, const _U_UINT number)
|
|
263
|
+
{
|
|
264
|
+
_U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1);
|
|
265
|
+
_US32 i;
|
|
266
|
+
|
|
267
|
+
for (i = 0; i < UNITY_INT_WIDTH; i++)
|
|
268
|
+
{
|
|
269
|
+
if (current_bit & mask)
|
|
270
|
+
{
|
|
271
|
+
if (current_bit & number)
|
|
272
|
+
{
|
|
273
|
+
UNITY_OUTPUT_CHAR('1');
|
|
274
|
+
}
|
|
275
|
+
else
|
|
276
|
+
{
|
|
277
|
+
UNITY_OUTPUT_CHAR('0');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else
|
|
281
|
+
{
|
|
282
|
+
UNITY_OUTPUT_CHAR('X');
|
|
283
|
+
}
|
|
284
|
+
current_bit = current_bit >> 1;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
//-----------------------------------------------
|
|
289
|
+
#ifdef UNITY_FLOAT_VERBOSE
|
|
290
|
+
#include <string.h>
|
|
291
|
+
void UnityPrintFloat(_UF number)
|
|
292
|
+
{
|
|
293
|
+
char TempBuffer[32];
|
|
294
|
+
sprintf(TempBuffer, "%.6f", number);
|
|
295
|
+
UnityPrint(TempBuffer);
|
|
296
|
+
}
|
|
297
|
+
#endif
|
|
298
|
+
|
|
299
|
+
//-----------------------------------------------
|
|
300
|
+
|
|
301
|
+
void UnityPrintFail(void);
|
|
302
|
+
void UnityPrintFail(void)
|
|
303
|
+
{
|
|
304
|
+
UnityPrint(UnityStrFail);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
void UnityPrintOk(void);
|
|
308
|
+
void UnityPrintOk(void)
|
|
309
|
+
{
|
|
310
|
+
UnityPrint(UnityStrOk);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
//-----------------------------------------------
|
|
314
|
+
static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line);
|
|
315
|
+
static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line)
|
|
316
|
+
{
|
|
317
|
+
#ifndef UNITY_FIXTURES
|
|
318
|
+
UnityPrint(file);
|
|
319
|
+
UNITY_OUTPUT_CHAR(':');
|
|
320
|
+
UnityPrintNumber((_U_SINT)line);
|
|
321
|
+
UNITY_OUTPUT_CHAR(':');
|
|
322
|
+
UnityPrint(Unity.CurrentTestName);
|
|
323
|
+
UNITY_OUTPUT_CHAR(':');
|
|
324
|
+
#else
|
|
325
|
+
UNITY_UNUSED(file);
|
|
326
|
+
UNITY_UNUSED(line);
|
|
327
|
+
#endif
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
//-----------------------------------------------
|
|
331
|
+
static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line);
|
|
332
|
+
static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line)
|
|
333
|
+
{
|
|
334
|
+
#ifndef UNITY_FIXTURES
|
|
335
|
+
UnityTestResultsBegin(Unity.TestFile, line);
|
|
336
|
+
#else
|
|
337
|
+
UNITY_UNUSED(line);
|
|
338
|
+
#endif
|
|
339
|
+
UnityPrint(UnityStrFail);
|
|
340
|
+
UNITY_OUTPUT_CHAR(':');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
//-----------------------------------------------
|
|
344
|
+
void UnityConcludeTest(void)
|
|
345
|
+
{
|
|
346
|
+
if (Unity.CurrentTestIgnored)
|
|
347
|
+
{
|
|
348
|
+
Unity.TestIgnores++;
|
|
349
|
+
}
|
|
350
|
+
else if (!Unity.CurrentTestFailed)
|
|
351
|
+
{
|
|
352
|
+
UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
|
|
353
|
+
UnityPrint(UnityStrPass);
|
|
354
|
+
}
|
|
355
|
+
else
|
|
356
|
+
{
|
|
357
|
+
Unity.TestFailures++;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
Unity.CurrentTestFailed = 0;
|
|
361
|
+
Unity.CurrentTestIgnored = 0;
|
|
362
|
+
UNITY_PRINT_EOL;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
//-----------------------------------------------
|
|
366
|
+
static void UnityAddMsgIfSpecified(const char* msg);
|
|
367
|
+
static void UnityAddMsgIfSpecified(const char* msg)
|
|
368
|
+
{
|
|
369
|
+
if (msg)
|
|
370
|
+
{
|
|
371
|
+
UnityPrint(UnityStrSpacer);
|
|
372
|
+
UnityPrint(msg);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//-----------------------------------------------
|
|
377
|
+
static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual);
|
|
378
|
+
static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual)
|
|
379
|
+
{
|
|
380
|
+
UnityPrint(UnityStrExpected);
|
|
381
|
+
if (expected != NULL)
|
|
382
|
+
{
|
|
383
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
384
|
+
UnityPrint(expected);
|
|
385
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
386
|
+
}
|
|
387
|
+
else
|
|
388
|
+
{
|
|
389
|
+
UnityPrint(UnityStrNull);
|
|
390
|
+
}
|
|
391
|
+
UnityPrint(UnityStrWas);
|
|
392
|
+
if (actual != NULL)
|
|
393
|
+
{
|
|
394
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
395
|
+
UnityPrint(actual);
|
|
396
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
397
|
+
}
|
|
398
|
+
else
|
|
399
|
+
{
|
|
400
|
+
UnityPrint(UnityStrNull);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
//-----------------------------------------------
|
|
405
|
+
static void UnityPrintExpectedAndActualStringsLen(const char* expected, const char* actual, const _UU32 length)
|
|
406
|
+
{
|
|
407
|
+
UnityPrint(UnityStrExpected);
|
|
408
|
+
if (expected != NULL)
|
|
409
|
+
{
|
|
410
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
411
|
+
UnityPrintLen(expected, length);
|
|
412
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
413
|
+
}
|
|
414
|
+
else
|
|
415
|
+
{
|
|
416
|
+
UnityPrint(UnityStrNull);
|
|
417
|
+
}
|
|
418
|
+
UnityPrint(UnityStrWas);
|
|
419
|
+
if (actual != NULL)
|
|
420
|
+
{
|
|
421
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
422
|
+
UnityPrintLen(actual, length);
|
|
423
|
+
UNITY_OUTPUT_CHAR('\'');
|
|
424
|
+
}
|
|
425
|
+
else
|
|
426
|
+
{
|
|
427
|
+
UnityPrint(UnityStrNull);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
//-----------------------------------------------
|
|
434
|
+
// Assertion & Control Helpers
|
|
435
|
+
//-----------------------------------------------
|
|
436
|
+
|
|
437
|
+
static int UnityCheckArraysForNull(UNITY_PTR_ATTRIBUTE const void* expected, UNITY_PTR_ATTRIBUTE const void* actual, const UNITY_LINE_TYPE lineNumber, const char* msg)
|
|
438
|
+
{
|
|
439
|
+
//return true if they are both NULL
|
|
440
|
+
if ((expected == NULL) && (actual == NULL))
|
|
441
|
+
return 1;
|
|
442
|
+
|
|
443
|
+
//throw error if just expected is NULL
|
|
444
|
+
if (expected == NULL)
|
|
445
|
+
{
|
|
446
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
447
|
+
UnityPrint(UnityStrNullPointerForExpected);
|
|
448
|
+
UnityAddMsgIfSpecified(msg);
|
|
449
|
+
UNITY_FAIL_AND_BAIL;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
//throw error if just actual is NULL
|
|
453
|
+
if (actual == NULL)
|
|
454
|
+
{
|
|
455
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
456
|
+
UnityPrint(UnityStrNullPointerForActual);
|
|
457
|
+
UnityAddMsgIfSpecified(msg);
|
|
458
|
+
UNITY_FAIL_AND_BAIL;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
//return false if neither is NULL
|
|
462
|
+
return 0;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
//-----------------------------------------------
|
|
466
|
+
// Assertion Functions
|
|
467
|
+
//-----------------------------------------------
|
|
468
|
+
|
|
469
|
+
void UnityAssertBits(const _U_SINT mask,
|
|
470
|
+
const _U_SINT expected,
|
|
471
|
+
const _U_SINT actual,
|
|
472
|
+
const char* msg,
|
|
473
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
474
|
+
{
|
|
475
|
+
UNITY_SKIP_EXECUTION;
|
|
476
|
+
|
|
477
|
+
if ((mask & expected) != (mask & actual))
|
|
478
|
+
{
|
|
479
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
480
|
+
UnityPrint(UnityStrExpected);
|
|
481
|
+
UnityPrintMask((_U_UINT)mask, (_U_UINT)expected);
|
|
482
|
+
UnityPrint(UnityStrWas);
|
|
483
|
+
UnityPrintMask((_U_UINT)mask, (_U_UINT)actual);
|
|
484
|
+
UnityAddMsgIfSpecified(msg);
|
|
485
|
+
UNITY_FAIL_AND_BAIL;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
//-----------------------------------------------
|
|
490
|
+
void UnityAssertEqualNumber(const _U_SINT expected,
|
|
491
|
+
const _U_SINT actual,
|
|
492
|
+
const char* msg,
|
|
493
|
+
const UNITY_LINE_TYPE lineNumber,
|
|
494
|
+
const UNITY_DISPLAY_STYLE_T style)
|
|
495
|
+
{
|
|
496
|
+
UNITY_SKIP_EXECUTION;
|
|
497
|
+
|
|
498
|
+
if (expected != actual)
|
|
499
|
+
{
|
|
500
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
501
|
+
UnityPrint(UnityStrExpected);
|
|
502
|
+
UnityPrintNumberByStyle(expected, style);
|
|
503
|
+
UnityPrint(UnityStrWas);
|
|
504
|
+
UnityPrintNumberByStyle(actual, style);
|
|
505
|
+
UnityAddMsgIfSpecified(msg);
|
|
506
|
+
UNITY_FAIL_AND_BAIL;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
//-----------------------------------------------
|
|
511
|
+
void UnityAssertEqualIntArray(UNITY_PTR_ATTRIBUTE const void* expected,
|
|
512
|
+
UNITY_PTR_ATTRIBUTE const void* actual,
|
|
513
|
+
const _UU32 num_elements,
|
|
514
|
+
const char* msg,
|
|
515
|
+
const UNITY_LINE_TYPE lineNumber,
|
|
516
|
+
const UNITY_DISPLAY_STYLE_T style)
|
|
517
|
+
{
|
|
518
|
+
_UU32 elements = num_elements;
|
|
519
|
+
UNITY_PTR_ATTRIBUTE const void* ptr_exp = (UNITY_PTR_ATTRIBUTE const void*)expected;
|
|
520
|
+
UNITY_PTR_ATTRIBUTE const void* ptr_act = (UNITY_PTR_ATTRIBUTE const void*)actual;
|
|
521
|
+
|
|
522
|
+
UNITY_SKIP_EXECUTION;
|
|
523
|
+
|
|
524
|
+
if (elements == 0)
|
|
525
|
+
{
|
|
526
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
527
|
+
UnityPrint(UnityStrPointless);
|
|
528
|
+
UnityAddMsgIfSpecified(msg);
|
|
529
|
+
UNITY_FAIL_AND_BAIL;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1)
|
|
533
|
+
return;
|
|
534
|
+
|
|
535
|
+
// If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case
|
|
536
|
+
// as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific
|
|
537
|
+
// variants do not. Therefore remove this flag.
|
|
538
|
+
switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO))
|
|
539
|
+
{
|
|
540
|
+
case UNITY_DISPLAY_STYLE_HEX8:
|
|
541
|
+
case UNITY_DISPLAY_STYLE_INT8:
|
|
542
|
+
case UNITY_DISPLAY_STYLE_UINT8:
|
|
543
|
+
while (elements--)
|
|
544
|
+
{
|
|
545
|
+
if (*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act)
|
|
546
|
+
{
|
|
547
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
548
|
+
UnityPrint(UnityStrElement);
|
|
549
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
550
|
+
UnityPrint(UnityStrExpected);
|
|
551
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp, style);
|
|
552
|
+
UnityPrint(UnityStrWas);
|
|
553
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act, style);
|
|
554
|
+
UnityAddMsgIfSpecified(msg);
|
|
555
|
+
UNITY_FAIL_AND_BAIL;
|
|
556
|
+
}
|
|
557
|
+
ptr_exp = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_exp + 1);
|
|
558
|
+
ptr_act = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_act + 1);
|
|
559
|
+
}
|
|
560
|
+
break;
|
|
561
|
+
case UNITY_DISPLAY_STYLE_HEX16:
|
|
562
|
+
case UNITY_DISPLAY_STYLE_INT16:
|
|
563
|
+
case UNITY_DISPLAY_STYLE_UINT16:
|
|
564
|
+
while (elements--)
|
|
565
|
+
{
|
|
566
|
+
if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act)
|
|
567
|
+
{
|
|
568
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
569
|
+
UnityPrint(UnityStrElement);
|
|
570
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
571
|
+
UnityPrint(UnityStrExpected);
|
|
572
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style);
|
|
573
|
+
UnityPrint(UnityStrWas);
|
|
574
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style);
|
|
575
|
+
UnityAddMsgIfSpecified(msg);
|
|
576
|
+
UNITY_FAIL_AND_BAIL;
|
|
577
|
+
}
|
|
578
|
+
ptr_exp = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_exp + 2);
|
|
579
|
+
ptr_act = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_act + 2);
|
|
580
|
+
}
|
|
581
|
+
break;
|
|
582
|
+
#ifdef UNITY_SUPPORT_64
|
|
583
|
+
case UNITY_DISPLAY_STYLE_HEX64:
|
|
584
|
+
case UNITY_DISPLAY_STYLE_INT64:
|
|
585
|
+
case UNITY_DISPLAY_STYLE_UINT64:
|
|
586
|
+
while (elements--)
|
|
587
|
+
{
|
|
588
|
+
if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act)
|
|
589
|
+
{
|
|
590
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
591
|
+
UnityPrint(UnityStrElement);
|
|
592
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
593
|
+
UnityPrint(UnityStrExpected);
|
|
594
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style);
|
|
595
|
+
UnityPrint(UnityStrWas);
|
|
596
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style);
|
|
597
|
+
UnityAddMsgIfSpecified(msg);
|
|
598
|
+
UNITY_FAIL_AND_BAIL;
|
|
599
|
+
}
|
|
600
|
+
ptr_exp = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_exp + 8);
|
|
601
|
+
ptr_act = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_act + 8);
|
|
602
|
+
}
|
|
603
|
+
break;
|
|
604
|
+
#endif
|
|
605
|
+
default:
|
|
606
|
+
while (elements--)
|
|
607
|
+
{
|
|
608
|
+
if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act)
|
|
609
|
+
{
|
|
610
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
611
|
+
UnityPrint(UnityStrElement);
|
|
612
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
613
|
+
UnityPrint(UnityStrExpected);
|
|
614
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style);
|
|
615
|
+
UnityPrint(UnityStrWas);
|
|
616
|
+
UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style);
|
|
617
|
+
UnityAddMsgIfSpecified(msg);
|
|
618
|
+
UNITY_FAIL_AND_BAIL;
|
|
619
|
+
}
|
|
620
|
+
ptr_exp = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_exp + 4);
|
|
621
|
+
ptr_act = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_act + 4);
|
|
622
|
+
}
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
//-----------------------------------------------
|
|
628
|
+
#ifndef UNITY_EXCLUDE_FLOAT
|
|
629
|
+
void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected,
|
|
630
|
+
UNITY_PTR_ATTRIBUTE const _UF* actual,
|
|
631
|
+
const _UU32 num_elements,
|
|
632
|
+
const char* msg,
|
|
633
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
634
|
+
{
|
|
635
|
+
_UU32 elements = num_elements;
|
|
636
|
+
UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected;
|
|
637
|
+
UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual;
|
|
638
|
+
_UF diff, tol;
|
|
639
|
+
|
|
640
|
+
UNITY_SKIP_EXECUTION;
|
|
641
|
+
|
|
642
|
+
if (elements == 0)
|
|
643
|
+
{
|
|
644
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
645
|
+
UnityPrint(UnityStrPointless);
|
|
646
|
+
UnityAddMsgIfSpecified(msg);
|
|
647
|
+
UNITY_FAIL_AND_BAIL;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1)
|
|
651
|
+
return;
|
|
652
|
+
|
|
653
|
+
while (elements--)
|
|
654
|
+
{
|
|
655
|
+
diff = *ptr_expected - *ptr_actual;
|
|
656
|
+
if (diff < 0.0f)
|
|
657
|
+
diff = 0.0f - diff;
|
|
658
|
+
tol = UNITY_FLOAT_PRECISION * *ptr_expected;
|
|
659
|
+
if (tol < 0.0f)
|
|
660
|
+
tol = 0.0f - tol;
|
|
661
|
+
|
|
662
|
+
//This first part of this condition will catch any NaN or Infinite values
|
|
663
|
+
if ((diff * 0.0f != 0.0f) || (diff > tol))
|
|
664
|
+
{
|
|
665
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
666
|
+
UnityPrint(UnityStrElement);
|
|
667
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
668
|
+
#ifdef UNITY_FLOAT_VERBOSE
|
|
669
|
+
UnityPrint(UnityStrExpected);
|
|
670
|
+
UnityPrintFloat(*ptr_expected);
|
|
671
|
+
UnityPrint(UnityStrWas);
|
|
672
|
+
UnityPrintFloat(*ptr_actual);
|
|
673
|
+
#else
|
|
674
|
+
UnityPrint(UnityStrDelta);
|
|
675
|
+
#endif
|
|
676
|
+
UnityAddMsgIfSpecified(msg);
|
|
677
|
+
UNITY_FAIL_AND_BAIL;
|
|
678
|
+
}
|
|
679
|
+
ptr_expected++;
|
|
680
|
+
ptr_actual++;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
//-----------------------------------------------
|
|
685
|
+
void UnityAssertFloatsWithin(const _UF delta,
|
|
686
|
+
const _UF expected,
|
|
687
|
+
const _UF actual,
|
|
688
|
+
const char* msg,
|
|
689
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
690
|
+
{
|
|
691
|
+
_UF diff = actual - expected;
|
|
692
|
+
_UF pos_delta = delta;
|
|
693
|
+
|
|
694
|
+
UNITY_SKIP_EXECUTION;
|
|
695
|
+
|
|
696
|
+
if (diff < 0.0f)
|
|
697
|
+
{
|
|
698
|
+
diff = 0.0f - diff;
|
|
699
|
+
}
|
|
700
|
+
if (pos_delta < 0.0f)
|
|
701
|
+
{
|
|
702
|
+
pos_delta = 0.0f - pos_delta;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
//This first part of this condition will catch any NaN or Infinite values
|
|
706
|
+
if ((diff * 0.0f != 0.0f) || (pos_delta < diff))
|
|
707
|
+
{
|
|
708
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
709
|
+
#ifdef UNITY_FLOAT_VERBOSE
|
|
710
|
+
UnityPrint(UnityStrExpected);
|
|
711
|
+
UnityPrintFloat(expected);
|
|
712
|
+
UnityPrint(UnityStrWas);
|
|
713
|
+
UnityPrintFloat(actual);
|
|
714
|
+
#else
|
|
715
|
+
UnityPrint(UnityStrDelta);
|
|
716
|
+
#endif
|
|
717
|
+
UnityAddMsgIfSpecified(msg);
|
|
718
|
+
UNITY_FAIL_AND_BAIL;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
//-----------------------------------------------
|
|
723
|
+
void UnityAssertFloatSpecial(const _UF actual,
|
|
724
|
+
const char* msg,
|
|
725
|
+
const UNITY_LINE_TYPE lineNumber,
|
|
726
|
+
const UNITY_FLOAT_TRAIT_T style)
|
|
727
|
+
{
|
|
728
|
+
const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet };
|
|
729
|
+
_U_SINT should_be_trait = ((_U_SINT)style & 1);
|
|
730
|
+
_U_SINT is_trait = !should_be_trait;
|
|
731
|
+
_U_SINT trait_index = style >> 1;
|
|
732
|
+
|
|
733
|
+
UNITY_SKIP_EXECUTION;
|
|
734
|
+
|
|
735
|
+
switch(style)
|
|
736
|
+
{
|
|
737
|
+
//To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
|
|
738
|
+
//We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise
|
|
739
|
+
case UNITY_FLOAT_IS_INF:
|
|
740
|
+
case UNITY_FLOAT_IS_NOT_INF:
|
|
741
|
+
is_trait = ((1.0f / f_zero) == actual) ? 1 : 0;
|
|
742
|
+
break;
|
|
743
|
+
case UNITY_FLOAT_IS_NEG_INF:
|
|
744
|
+
case UNITY_FLOAT_IS_NOT_NEG_INF:
|
|
745
|
+
is_trait = ((-1.0f / f_zero) == actual) ? 1 : 0;
|
|
746
|
+
break;
|
|
747
|
+
|
|
748
|
+
//NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN.
|
|
749
|
+
case UNITY_FLOAT_IS_NAN:
|
|
750
|
+
case UNITY_FLOAT_IS_NOT_NAN:
|
|
751
|
+
is_trait = (actual == actual) ? 0 : 1;
|
|
752
|
+
break;
|
|
753
|
+
|
|
754
|
+
//A determinate number is non infinite and not NaN. (therefore the opposite of the two above)
|
|
755
|
+
case UNITY_FLOAT_IS_DET:
|
|
756
|
+
case UNITY_FLOAT_IS_NOT_DET:
|
|
757
|
+
if ( (actual != actual) || ((1.0f / f_zero) == actual) || ((-1.0f / f_zero) == actual) )
|
|
758
|
+
is_trait = 0;
|
|
759
|
+
else
|
|
760
|
+
is_trait = 1;
|
|
761
|
+
break;
|
|
762
|
+
default:
|
|
763
|
+
;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (is_trait != should_be_trait)
|
|
767
|
+
{
|
|
768
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
769
|
+
UnityPrint(UnityStrExpected);
|
|
770
|
+
if (!should_be_trait)
|
|
771
|
+
UnityPrint(UnityStrNot);
|
|
772
|
+
UnityPrint(trait_names[trait_index]);
|
|
773
|
+
UnityPrint(UnityStrWas);
|
|
774
|
+
#ifdef UNITY_FLOAT_VERBOSE
|
|
775
|
+
UnityPrintFloat(actual);
|
|
776
|
+
#else
|
|
777
|
+
if (should_be_trait)
|
|
778
|
+
UnityPrint(UnityStrNot);
|
|
779
|
+
UnityPrint(trait_names[trait_index]);
|
|
780
|
+
#endif
|
|
781
|
+
UnityAddMsgIfSpecified(msg);
|
|
782
|
+
UNITY_FAIL_AND_BAIL;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
#endif //not UNITY_EXCLUDE_FLOAT
|
|
787
|
+
|
|
788
|
+
//-----------------------------------------------
|
|
789
|
+
#ifndef UNITY_EXCLUDE_DOUBLE
|
|
790
|
+
void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected,
|
|
791
|
+
UNITY_PTR_ATTRIBUTE const _UD* actual,
|
|
792
|
+
const _UU32 num_elements,
|
|
793
|
+
const char* msg,
|
|
794
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
795
|
+
{
|
|
796
|
+
_UU32 elements = num_elements;
|
|
797
|
+
UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected;
|
|
798
|
+
UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual;
|
|
799
|
+
_UD diff, tol;
|
|
800
|
+
|
|
801
|
+
UNITY_SKIP_EXECUTION;
|
|
802
|
+
|
|
803
|
+
if (elements == 0)
|
|
804
|
+
{
|
|
805
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
806
|
+
UnityPrint(UnityStrPointless);
|
|
807
|
+
UnityAddMsgIfSpecified(msg);
|
|
808
|
+
UNITY_FAIL_AND_BAIL;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1)
|
|
812
|
+
return;
|
|
813
|
+
|
|
814
|
+
while (elements--)
|
|
815
|
+
{
|
|
816
|
+
diff = *ptr_expected - *ptr_actual;
|
|
817
|
+
if (diff < 0.0)
|
|
818
|
+
diff = 0.0 - diff;
|
|
819
|
+
tol = UNITY_DOUBLE_PRECISION * *ptr_expected;
|
|
820
|
+
if (tol < 0.0)
|
|
821
|
+
tol = 0.0 - tol;
|
|
822
|
+
|
|
823
|
+
//This first part of this condition will catch any NaN or Infinite values
|
|
824
|
+
if ((diff * 0.0 != 0.0) || (diff > tol))
|
|
825
|
+
{
|
|
826
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
827
|
+
UnityPrint(UnityStrElement);
|
|
828
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
829
|
+
#ifdef UNITY_DOUBLE_VERBOSE
|
|
830
|
+
UnityPrint(UnityStrExpected);
|
|
831
|
+
UnityPrintFloat((float)(*ptr_expected));
|
|
832
|
+
UnityPrint(UnityStrWas);
|
|
833
|
+
UnityPrintFloat((float)(*ptr_actual));
|
|
834
|
+
#else
|
|
835
|
+
UnityPrint(UnityStrDelta);
|
|
836
|
+
#endif
|
|
837
|
+
UnityAddMsgIfSpecified(msg);
|
|
838
|
+
UNITY_FAIL_AND_BAIL;
|
|
839
|
+
}
|
|
840
|
+
ptr_expected++;
|
|
841
|
+
ptr_actual++;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
//-----------------------------------------------
|
|
846
|
+
void UnityAssertDoublesWithin(const _UD delta,
|
|
847
|
+
const _UD expected,
|
|
848
|
+
const _UD actual,
|
|
849
|
+
const char* msg,
|
|
850
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
851
|
+
{
|
|
852
|
+
_UD diff = actual - expected;
|
|
853
|
+
_UD pos_delta = delta;
|
|
854
|
+
|
|
855
|
+
UNITY_SKIP_EXECUTION;
|
|
856
|
+
|
|
857
|
+
if (diff < 0.0)
|
|
858
|
+
{
|
|
859
|
+
diff = 0.0 - diff;
|
|
860
|
+
}
|
|
861
|
+
if (pos_delta < 0.0)
|
|
862
|
+
{
|
|
863
|
+
pos_delta = 0.0 - pos_delta;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
//This first part of this condition will catch any NaN or Infinite values
|
|
867
|
+
if ((diff * 0.0 != 0.0) || (pos_delta < diff))
|
|
868
|
+
{
|
|
869
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
870
|
+
#ifdef UNITY_DOUBLE_VERBOSE
|
|
871
|
+
UnityPrint(UnityStrExpected);
|
|
872
|
+
UnityPrintFloat((float)expected);
|
|
873
|
+
UnityPrint(UnityStrWas);
|
|
874
|
+
UnityPrintFloat((float)actual);
|
|
875
|
+
#else
|
|
876
|
+
UnityPrint(UnityStrDelta);
|
|
877
|
+
#endif
|
|
878
|
+
UnityAddMsgIfSpecified(msg);
|
|
879
|
+
UNITY_FAIL_AND_BAIL;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
//-----------------------------------------------
|
|
884
|
+
|
|
885
|
+
void UnityAssertDoubleSpecial(const _UD actual,
|
|
886
|
+
const char* msg,
|
|
887
|
+
const UNITY_LINE_TYPE lineNumber,
|
|
888
|
+
const UNITY_FLOAT_TRAIT_T style)
|
|
889
|
+
{
|
|
890
|
+
const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet };
|
|
891
|
+
_U_SINT should_be_trait = ((_U_SINT)style & 1);
|
|
892
|
+
_U_SINT is_trait = !should_be_trait;
|
|
893
|
+
_U_SINT trait_index = style >> 1;
|
|
894
|
+
|
|
895
|
+
UNITY_SKIP_EXECUTION;
|
|
896
|
+
|
|
897
|
+
switch(style)
|
|
898
|
+
{
|
|
899
|
+
//To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly
|
|
900
|
+
//We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise
|
|
901
|
+
case UNITY_FLOAT_IS_INF:
|
|
902
|
+
case UNITY_FLOAT_IS_NOT_INF:
|
|
903
|
+
is_trait = ((1.0 / d_zero) == actual) ? 1 : 0;
|
|
904
|
+
break;
|
|
905
|
+
case UNITY_FLOAT_IS_NEG_INF:
|
|
906
|
+
case UNITY_FLOAT_IS_NOT_NEG_INF:
|
|
907
|
+
is_trait = ((-1.0 / d_zero) == actual) ? 1 : 0;
|
|
908
|
+
break;
|
|
909
|
+
|
|
910
|
+
//NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN.
|
|
911
|
+
case UNITY_FLOAT_IS_NAN:
|
|
912
|
+
case UNITY_FLOAT_IS_NOT_NAN:
|
|
913
|
+
is_trait = (actual == actual) ? 0 : 1;
|
|
914
|
+
break;
|
|
915
|
+
|
|
916
|
+
//A determinate number is non infinite and not NaN. (therefore the opposite of the two above)
|
|
917
|
+
case UNITY_FLOAT_IS_DET:
|
|
918
|
+
case UNITY_FLOAT_IS_NOT_DET:
|
|
919
|
+
if ( (actual != actual) || ((1.0 / d_zero) == actual) || ((-1.0 / d_zero) == actual) )
|
|
920
|
+
is_trait = 0;
|
|
921
|
+
else
|
|
922
|
+
is_trait = 1;
|
|
923
|
+
break;
|
|
924
|
+
default:
|
|
925
|
+
;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
if (is_trait != should_be_trait)
|
|
929
|
+
{
|
|
930
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
931
|
+
UnityPrint(UnityStrExpected);
|
|
932
|
+
if (!should_be_trait)
|
|
933
|
+
UnityPrint(UnityStrNot);
|
|
934
|
+
UnityPrint(trait_names[trait_index]);
|
|
935
|
+
UnityPrint(UnityStrWas);
|
|
936
|
+
#ifdef UNITY_DOUBLE_VERBOSE
|
|
937
|
+
UnityPrintFloat(actual);
|
|
938
|
+
#else
|
|
939
|
+
if (should_be_trait)
|
|
940
|
+
UnityPrint(UnityStrNot);
|
|
941
|
+
UnityPrint(trait_names[trait_index]);
|
|
942
|
+
#endif
|
|
943
|
+
UnityAddMsgIfSpecified(msg);
|
|
944
|
+
UNITY_FAIL_AND_BAIL;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
#endif // not UNITY_EXCLUDE_DOUBLE
|
|
950
|
+
|
|
951
|
+
//-----------------------------------------------
|
|
952
|
+
void UnityAssertNumbersWithin( const _U_SINT delta,
|
|
953
|
+
const _U_SINT expected,
|
|
954
|
+
const _U_SINT actual,
|
|
955
|
+
const char* msg,
|
|
956
|
+
const UNITY_LINE_TYPE lineNumber,
|
|
957
|
+
const UNITY_DISPLAY_STYLE_T style)
|
|
958
|
+
{
|
|
959
|
+
UNITY_SKIP_EXECUTION;
|
|
960
|
+
|
|
961
|
+
if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT)
|
|
962
|
+
{
|
|
963
|
+
if (actual > expected)
|
|
964
|
+
Unity.CurrentTestFailed = ((actual - expected) > delta);
|
|
965
|
+
else
|
|
966
|
+
Unity.CurrentTestFailed = ((expected - actual) > delta);
|
|
967
|
+
}
|
|
968
|
+
else
|
|
969
|
+
{
|
|
970
|
+
if ((_U_UINT)actual > (_U_UINT)expected)
|
|
971
|
+
Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > (_U_UINT)delta);
|
|
972
|
+
else
|
|
973
|
+
Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > (_U_UINT)delta);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
if (Unity.CurrentTestFailed)
|
|
977
|
+
{
|
|
978
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
979
|
+
UnityPrint(UnityStrDelta);
|
|
980
|
+
UnityPrintNumberByStyle(delta, style);
|
|
981
|
+
UnityPrint(UnityStrExpected);
|
|
982
|
+
UnityPrintNumberByStyle(expected, style);
|
|
983
|
+
UnityPrint(UnityStrWas);
|
|
984
|
+
UnityPrintNumberByStyle(actual, style);
|
|
985
|
+
UnityAddMsgIfSpecified(msg);
|
|
986
|
+
UNITY_FAIL_AND_BAIL;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
//-----------------------------------------------
|
|
991
|
+
void UnityAssertEqualString(const char* expected,
|
|
992
|
+
const char* actual,
|
|
993
|
+
const char* msg,
|
|
994
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
995
|
+
{
|
|
996
|
+
_UU32 i;
|
|
997
|
+
|
|
998
|
+
UNITY_SKIP_EXECUTION;
|
|
999
|
+
|
|
1000
|
+
// if both pointers not null compare the strings
|
|
1001
|
+
if (expected && actual)
|
|
1002
|
+
{
|
|
1003
|
+
for (i = 0; expected[i] || actual[i]; i++)
|
|
1004
|
+
{
|
|
1005
|
+
if (expected[i] != actual[i])
|
|
1006
|
+
{
|
|
1007
|
+
Unity.CurrentTestFailed = 1;
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
else
|
|
1013
|
+
{ // handle case of one pointers being null (if both null, test should pass)
|
|
1014
|
+
if (expected != actual)
|
|
1015
|
+
{
|
|
1016
|
+
Unity.CurrentTestFailed = 1;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
if (Unity.CurrentTestFailed)
|
|
1021
|
+
{
|
|
1022
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
1023
|
+
UnityPrintExpectedAndActualStrings(expected, actual);
|
|
1024
|
+
UnityAddMsgIfSpecified(msg);
|
|
1025
|
+
UNITY_FAIL_AND_BAIL;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
//-----------------------------------------------
|
|
1030
|
+
void UnityAssertEqualStringLen(const char* expected,
|
|
1031
|
+
const char* actual,
|
|
1032
|
+
const _UU32 length,
|
|
1033
|
+
const char* msg,
|
|
1034
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
1035
|
+
{
|
|
1036
|
+
_UU32 i;
|
|
1037
|
+
|
|
1038
|
+
UNITY_SKIP_EXECUTION;
|
|
1039
|
+
|
|
1040
|
+
// if both pointers not null compare the strings
|
|
1041
|
+
if (expected && actual)
|
|
1042
|
+
{
|
|
1043
|
+
for (i = 0; (expected[i] || actual[i]) && i < length; i++)
|
|
1044
|
+
{
|
|
1045
|
+
if (expected[i] != actual[i])
|
|
1046
|
+
{
|
|
1047
|
+
Unity.CurrentTestFailed = 1;
|
|
1048
|
+
break;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
else
|
|
1053
|
+
{ // handle case of one pointers being null (if both null, test should pass)
|
|
1054
|
+
if (expected != actual)
|
|
1055
|
+
{
|
|
1056
|
+
Unity.CurrentTestFailed = 1;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
if (Unity.CurrentTestFailed)
|
|
1061
|
+
{
|
|
1062
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
1063
|
+
UnityPrintExpectedAndActualStringsLen(expected, actual, length);
|
|
1064
|
+
UnityAddMsgIfSpecified(msg);
|
|
1065
|
+
UNITY_FAIL_AND_BAIL;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
//-----------------------------------------------
|
|
1071
|
+
void UnityAssertEqualStringArray( const char** expected,
|
|
1072
|
+
const char** actual,
|
|
1073
|
+
const _UU32 num_elements,
|
|
1074
|
+
const char* msg,
|
|
1075
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
1076
|
+
{
|
|
1077
|
+
_UU32 i, j = 0;
|
|
1078
|
+
|
|
1079
|
+
UNITY_SKIP_EXECUTION;
|
|
1080
|
+
|
|
1081
|
+
// if no elements, it's an error
|
|
1082
|
+
if (num_elements == 0)
|
|
1083
|
+
{
|
|
1084
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
1085
|
+
UnityPrint(UnityStrPointless);
|
|
1086
|
+
UnityAddMsgIfSpecified(msg);
|
|
1087
|
+
UNITY_FAIL_AND_BAIL;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE void*)expected, (UNITY_PTR_ATTRIBUTE void*)actual, lineNumber, msg) == 1)
|
|
1091
|
+
return;
|
|
1092
|
+
|
|
1093
|
+
do
|
|
1094
|
+
{
|
|
1095
|
+
// if both pointers not null compare the strings
|
|
1096
|
+
if (expected[j] && actual[j])
|
|
1097
|
+
{
|
|
1098
|
+
for (i = 0; expected[j][i] || actual[j][i]; i++)
|
|
1099
|
+
{
|
|
1100
|
+
if (expected[j][i] != actual[j][i])
|
|
1101
|
+
{
|
|
1102
|
+
Unity.CurrentTestFailed = 1;
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
else
|
|
1108
|
+
{ // handle case of one pointers being null (if both null, test should pass)
|
|
1109
|
+
if (expected[j] != actual[j])
|
|
1110
|
+
{
|
|
1111
|
+
Unity.CurrentTestFailed = 1;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
if (Unity.CurrentTestFailed)
|
|
1116
|
+
{
|
|
1117
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
1118
|
+
if (num_elements > 1)
|
|
1119
|
+
{
|
|
1120
|
+
UnityPrint(UnityStrElement);
|
|
1121
|
+
UnityPrintNumberByStyle((j), UNITY_DISPLAY_STYLE_UINT);
|
|
1122
|
+
}
|
|
1123
|
+
UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j]));
|
|
1124
|
+
UnityAddMsgIfSpecified(msg);
|
|
1125
|
+
UNITY_FAIL_AND_BAIL;
|
|
1126
|
+
}
|
|
1127
|
+
} while (++j < num_elements);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
//-----------------------------------------------
|
|
1131
|
+
void UnityAssertEqualMemory( UNITY_PTR_ATTRIBUTE const void* expected,
|
|
1132
|
+
UNITY_PTR_ATTRIBUTE const void* actual,
|
|
1133
|
+
const _UU32 length,
|
|
1134
|
+
const _UU32 num_elements,
|
|
1135
|
+
const char* msg,
|
|
1136
|
+
const UNITY_LINE_TYPE lineNumber)
|
|
1137
|
+
{
|
|
1138
|
+
UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected;
|
|
1139
|
+
UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual;
|
|
1140
|
+
_UU32 elements = num_elements;
|
|
1141
|
+
_UU32 bytes;
|
|
1142
|
+
|
|
1143
|
+
UNITY_SKIP_EXECUTION;
|
|
1144
|
+
|
|
1145
|
+
if ((elements == 0) || (length == 0))
|
|
1146
|
+
{
|
|
1147
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
1148
|
+
UnityPrint(UnityStrPointless);
|
|
1149
|
+
UnityAddMsgIfSpecified(msg);
|
|
1150
|
+
UNITY_FAIL_AND_BAIL;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
if (UnityCheckArraysForNull((UNITY_PTR_ATTRIBUTE const void*)expected, (UNITY_PTR_ATTRIBUTE const void*)actual, lineNumber, msg) == 1)
|
|
1154
|
+
return;
|
|
1155
|
+
|
|
1156
|
+
while (elements--)
|
|
1157
|
+
{
|
|
1158
|
+
/////////////////////////////////////
|
|
1159
|
+
bytes = length;
|
|
1160
|
+
while (bytes--)
|
|
1161
|
+
{
|
|
1162
|
+
if (*ptr_exp != *ptr_act)
|
|
1163
|
+
{
|
|
1164
|
+
UnityTestResultsFailBegin(lineNumber);
|
|
1165
|
+
UnityPrint(UnityStrMemory);
|
|
1166
|
+
if (num_elements > 1)
|
|
1167
|
+
{
|
|
1168
|
+
UnityPrint(UnityStrElement);
|
|
1169
|
+
UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
1170
|
+
}
|
|
1171
|
+
UnityPrint(UnityStrByte);
|
|
1172
|
+
UnityPrintNumberByStyle((length - bytes - 1), UNITY_DISPLAY_STYLE_UINT);
|
|
1173
|
+
UnityPrint(UnityStrExpected);
|
|
1174
|
+
UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8);
|
|
1175
|
+
UnityPrint(UnityStrWas);
|
|
1176
|
+
UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8);
|
|
1177
|
+
UnityAddMsgIfSpecified(msg);
|
|
1178
|
+
UNITY_FAIL_AND_BAIL;
|
|
1179
|
+
}
|
|
1180
|
+
ptr_exp = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_exp + 1);
|
|
1181
|
+
ptr_act = (UNITY_PTR_ATTRIBUTE const void*)((_UP)ptr_act + 1);
|
|
1182
|
+
}
|
|
1183
|
+
/////////////////////////////////////
|
|
1184
|
+
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
//-----------------------------------------------
|
|
1189
|
+
// Control Functions
|
|
1190
|
+
//-----------------------------------------------
|
|
1191
|
+
|
|
1192
|
+
void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
|
|
1193
|
+
{
|
|
1194
|
+
UNITY_SKIP_EXECUTION;
|
|
1195
|
+
|
|
1196
|
+
UnityTestResultsBegin(Unity.TestFile, line);
|
|
1197
|
+
UnityPrintFail();
|
|
1198
|
+
if (msg != NULL)
|
|
1199
|
+
{
|
|
1200
|
+
UNITY_OUTPUT_CHAR(':');
|
|
1201
|
+
if (msg[0] != ' ')
|
|
1202
|
+
{
|
|
1203
|
+
UNITY_OUTPUT_CHAR(' ');
|
|
1204
|
+
}
|
|
1205
|
+
UnityPrint(msg);
|
|
1206
|
+
}
|
|
1207
|
+
UNITY_FAIL_AND_BAIL;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
//-----------------------------------------------
|
|
1211
|
+
void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line)
|
|
1212
|
+
{
|
|
1213
|
+
UNITY_SKIP_EXECUTION;
|
|
1214
|
+
|
|
1215
|
+
UnityTestResultsBegin(Unity.TestFile, line);
|
|
1216
|
+
UnityPrint(UnityStrIgnore);
|
|
1217
|
+
if (msg != NULL)
|
|
1218
|
+
{
|
|
1219
|
+
UNITY_OUTPUT_CHAR(':');
|
|
1220
|
+
UNITY_OUTPUT_CHAR(' ');
|
|
1221
|
+
UnityPrint(msg);
|
|
1222
|
+
}
|
|
1223
|
+
UNITY_IGNORE_AND_BAIL;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
//-----------------------------------------------
|
|
1227
|
+
#if defined(UNITY_WEAK_ATTRIBUTE)
|
|
1228
|
+
void setUp(void);
|
|
1229
|
+
void tearDown(void);
|
|
1230
|
+
UNITY_WEAK_ATTRIBUTE void setUp(void) { }
|
|
1231
|
+
UNITY_WEAK_ATTRIBUTE void tearDown(void) { }
|
|
1232
|
+
#elif defined(UNITY_WEAK_PRAGMA)
|
|
1233
|
+
# pragma weak setUp
|
|
1234
|
+
void setUp(void);
|
|
1235
|
+
# pragma weak tearDown
|
|
1236
|
+
void tearDown(void);
|
|
1237
|
+
#else
|
|
1238
|
+
void setUp(void);
|
|
1239
|
+
void tearDown(void);
|
|
1240
|
+
#endif
|
|
1241
|
+
//-----------------------------------------------
|
|
1242
|
+
void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum)
|
|
1243
|
+
{
|
|
1244
|
+
Unity.CurrentTestName = FuncName;
|
|
1245
|
+
Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
|
|
1246
|
+
Unity.NumberOfTests++;
|
|
1247
|
+
if (TEST_PROTECT())
|
|
1248
|
+
{
|
|
1249
|
+
setUp();
|
|
1250
|
+
Func();
|
|
1251
|
+
}
|
|
1252
|
+
if (TEST_PROTECT() && !(Unity.CurrentTestIgnored))
|
|
1253
|
+
{
|
|
1254
|
+
tearDown();
|
|
1255
|
+
}
|
|
1256
|
+
UnityConcludeTest();
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
//-----------------------------------------------
|
|
1260
|
+
void UnityBegin(const char* filename)
|
|
1261
|
+
{
|
|
1262
|
+
Unity.TestFile = filename;
|
|
1263
|
+
Unity.CurrentTestName = NULL;
|
|
1264
|
+
Unity.CurrentTestLineNumber = 0;
|
|
1265
|
+
Unity.NumberOfTests = 0;
|
|
1266
|
+
Unity.TestFailures = 0;
|
|
1267
|
+
Unity.TestIgnores = 0;
|
|
1268
|
+
Unity.CurrentTestFailed = 0;
|
|
1269
|
+
Unity.CurrentTestIgnored = 0;
|
|
1270
|
+
|
|
1271
|
+
UNITY_OUTPUT_START();
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
//-----------------------------------------------
|
|
1275
|
+
int UnityEnd(void)
|
|
1276
|
+
{
|
|
1277
|
+
UNITY_PRINT_EOL;
|
|
1278
|
+
UnityPrint(UnityStrBreaker);
|
|
1279
|
+
UNITY_PRINT_EOL;
|
|
1280
|
+
UnityPrintNumber((_U_SINT)(Unity.NumberOfTests));
|
|
1281
|
+
UnityPrint(UnityStrResultsTests);
|
|
1282
|
+
UnityPrintNumber((_U_SINT)(Unity.TestFailures));
|
|
1283
|
+
UnityPrint(UnityStrResultsFailures);
|
|
1284
|
+
UnityPrintNumber((_U_SINT)(Unity.TestIgnores));
|
|
1285
|
+
UnityPrint(UnityStrResultsIgnored);
|
|
1286
|
+
UNITY_PRINT_EOL;
|
|
1287
|
+
if (Unity.TestFailures == 0U)
|
|
1288
|
+
{
|
|
1289
|
+
UnityPrintOk();
|
|
1290
|
+
}
|
|
1291
|
+
else
|
|
1292
|
+
{
|
|
1293
|
+
UnityPrintFail();
|
|
1294
|
+
}
|
|
1295
|
+
UNITY_PRINT_EOL;
|
|
1296
|
+
UNITY_OUTPUT_COMPLETE();
|
|
1297
|
+
return (int)(Unity.TestFailures);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
//-----------------------------------------------
|