removed zig cpp bash
This commit is contained in:
parent
af89290bbc
commit
62d1558abe
21 changed files with 0 additions and 19219 deletions
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"authors": [],
|
|
||||||
"contributors": [
|
|
||||||
"adelcambre",
|
|
||||||
"bkhl",
|
|
||||||
"budmc29",
|
|
||||||
"coreygo",
|
|
||||||
"glennj",
|
|
||||||
"guygastineau",
|
|
||||||
"IsaacG",
|
|
||||||
"kenden",
|
|
||||||
"kotp",
|
|
||||||
"kytrinyx",
|
|
||||||
"MattLewin",
|
|
||||||
"platinumthinker",
|
|
||||||
"quartzinquartz",
|
|
||||||
"rootulp",
|
|
||||||
"sjwarner-bp",
|
|
||||||
"Smarticles101",
|
|
||||||
"ZapAnton"
|
|
||||||
],
|
|
||||||
"files": {
|
|
||||||
"solution": [
|
|
||||||
"hello_world.sh"
|
|
||||||
],
|
|
||||||
"test": [
|
|
||||||
"hello_world.bats"
|
|
||||||
],
|
|
||||||
"example": [
|
|
||||||
".meta/example.sh"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".",
|
|
||||||
"source": "This is an exercise to introduce users to using Exercism",
|
|
||||||
"source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program"
|
|
||||||
}
|
|
||||||
|
|
@ -1,142 +0,0 @@
|
||||||
# Help
|
|
||||||
|
|
||||||
## Running the tests
|
|
||||||
|
|
||||||
Each exercise contains a test file.
|
|
||||||
Run the tests using the `bats` program.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bats hello_world.bats
|
|
||||||
```
|
|
||||||
|
|
||||||
`bats` will need to be installed.
|
|
||||||
See the [Testing on the Bash track][tests] page for instructions to install `bats` for your system.
|
|
||||||
|
|
||||||
[tests]: https://exercism.org/docs/tracks/bash/tests
|
|
||||||
|
|
||||||
## Help for assert functions
|
|
||||||
|
|
||||||
The tests use functions from the [bats-assert][bats-assert] library.
|
|
||||||
Help for the various `assert*` functions can be found there.
|
|
||||||
|
|
||||||
[bats-assert]: https://github.com/bats-core/bats-assert
|
|
||||||
|
|
||||||
## Debugging output
|
|
||||||
|
|
||||||
```exercism/caution
|
|
||||||
This works locally with `bats`, but **not** in the Exercism online editor.
|
|
||||||
```
|
|
||||||
|
|
||||||
When running tests, `bats` captures both stdout and stderr for comparison with the expected output.
|
|
||||||
If you print debug messages to stdout (`echo`) or stderr (`>&2`), they will be included in the captured output and may cause the test to fail.
|
|
||||||
|
|
||||||
To print debug information without affecting the test results, `bats` provides file descriptor **3** for this purpose.
|
|
||||||
Anything redirected to `>&3` will be shown during the test run but will not be included in the captured output used for assertions.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# This debug message will not interfere with test output comparison
|
|
||||||
echo "debug message" >&3
|
|
||||||
|
|
||||||
# Normal program output (this is what your tests will see and compare)
|
|
||||||
echo "Hello, World!"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example run:
|
|
||||||
|
|
||||||
```none
|
|
||||||
$ bats hello_world.bats
|
|
||||||
hello_world.bats
|
|
||||||
✓ Say Hi!
|
|
||||||
debug message
|
|
||||||
1 test, 0 failures
|
|
||||||
```
|
|
||||||
|
|
||||||
This allows you to see helpful debug output without affecting the tests.
|
|
||||||
|
|
||||||
## Skipped tests
|
|
||||||
|
|
||||||
Solving an exercise means making all its tests pass.
|
|
||||||
By default, only one test (the first one) is executed when you run the tests.
|
|
||||||
This is intentional, as it allows you to focus on just making that one test pass.
|
|
||||||
Once it passes, you can enable the next test by commenting out or removing the next annotation:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
[[ $BATS_RUN_SKIPPED == true ]] || skip
|
|
||||||
```
|
|
||||||
|
|
||||||
## Overriding skips
|
|
||||||
|
|
||||||
To run all tests, including the ones with `skip` annotations, you can run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
BATS_RUN_SKIPPED=true bats exercise_name.bats
|
|
||||||
```
|
|
||||||
|
|
||||||
It can be convenient to use a wrapper function to save on typing:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bats() {
|
|
||||||
BATS_RUN_SKIPPED=true command bats *.bats
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then run tests with just:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bats
|
|
||||||
```
|
|
||||||
|
|
||||||
## Submitting your solution
|
|
||||||
|
|
||||||
You can submit your solution using the `exercism submit hello_world.sh` command.
|
|
||||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
|
||||||
|
|
||||||
It's possible to submit an incomplete solution which allows you to:
|
|
||||||
|
|
||||||
- See how others have completed the exercise
|
|
||||||
- Request help from a mentor
|
|
||||||
|
|
||||||
## Need to get help?
|
|
||||||
|
|
||||||
If you'd like help solving the exercise, check the following pages:
|
|
||||||
|
|
||||||
- The [Bash track's documentation](https://exercism.org/docs/tracks/bash)
|
|
||||||
- The [Bash track's programming category on the forum](https://forum.exercism.org/c/programming/bash)
|
|
||||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
|
||||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
|
||||||
|
|
||||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
|
||||||
|
|
||||||
Check your code for syntax errors: paste your code into
|
|
||||||
[https://shellcheck.net](https://shellcheck.net) (or [install it](https://github.com/koalaman/shellcheck#user-content-installing) on your machine).
|
|
||||||
|
|
||||||
Stack Overflow will be your first stop for bash questions.
|
|
||||||
|
|
||||||
* start with the [`bash` tag](https://stackoverflow.com/questions/tagged/bash) to search for your specific question: it's probably already been asked
|
|
||||||
* under the bash tag on Stackoverflow, the [Learn more...](https://stackoverflow.com/tags/bash/info) link has _tons_ of good information.
|
|
||||||
* the "Books and Resources" section is particularly useful.
|
|
||||||
* the [`bash` tag](https://unix.stackexchange.com/questions/tagged/bash) on Unix & Linux is also active
|
|
||||||
|
|
||||||
## External utilities
|
|
||||||
|
|
||||||
`bash` is a language to write "scripts" -- programs that can call
|
|
||||||
external tools, such as
|
|
||||||
[`sed`](https://www.gnu.org/software/sed/),
|
|
||||||
[`awk`](https://www.gnu.org/software/gawk/),
|
|
||||||
[`date`](https://www.gnu.org/software/coreutils/manual/html_node/date-invocation.html)
|
|
||||||
and even programs written in other programming languages,
|
|
||||||
like [`Python`](https://www.python.org/).
|
|
||||||
This track does not restrict the usage of these utilities, and as long
|
|
||||||
as your solution is portable between systems and does not require
|
|
||||||
installation of third party applications, feel free to use them to solve
|
|
||||||
the exercise.
|
|
||||||
|
|
||||||
For an extra challenge, if you would like to have a better understanding of
|
|
||||||
the language, try to re-implement the solution in pure bash, without using
|
|
||||||
any external tools. There are some types of problems that bash cannot solve,
|
|
||||||
such as floating point arithmetic and manipulating dates: for those, you
|
|
||||||
must call out to an external tool.
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
# Hello World
|
|
||||||
|
|
||||||
Welcome to Hello World on Exercism's Bash Track.
|
|
||||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
|
||||||
|
|
||||||
## Instructions
|
|
||||||
|
|
||||||
The classical introductory exercise.
|
|
||||||
Just say "Hello, World!".
|
|
||||||
|
|
||||||
["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment.
|
|
||||||
|
|
||||||
The objectives are simple:
|
|
||||||
|
|
||||||
- Modify the provided code so that it produces the string "Hello, World!".
|
|
||||||
- Run the test suite and make sure that it succeeds.
|
|
||||||
- Submit your solution and check it at the website.
|
|
||||||
|
|
||||||
If everything goes well, you will be ready to fetch your first real exercise.
|
|
||||||
|
|
||||||
[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
|
||||||
|
|
||||||
## Welcome to Bash!
|
|
||||||
|
|
||||||
Unlike many other languages here, bash is a bit of a special snowflake.
|
|
||||||
If you are on a Mac or other unix-y platform, you almost definitely
|
|
||||||
already have bash. In fact, anything you type into the terminal is
|
|
||||||
likely going through bash.
|
|
||||||
|
|
||||||
The downside to this is that there isn't much of a development
|
|
||||||
ecosystem around bash like there is for other languages, and there are
|
|
||||||
multiple versions of bash that can be frustratingly incompatible. Luckily
|
|
||||||
we shouldn't hit those differences for these basic examples, and if you
|
|
||||||
can get the tests to pass on your machine, we are doing great.
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
Please follow [these instructions](https://exercism.org/docs/tracks/bash/installation) to install `bash` on your system.
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
Please follow [these instructions](https://exercism.org/docs/tracks/bash/tests) to learn more about testing with `bash`.
|
|
||||||
|
|
||||||
## Source
|
|
||||||
|
|
||||||
### Contributed to by
|
|
||||||
|
|
||||||
- @adelcambre
|
|
||||||
- @bkhl
|
|
||||||
- @budmc29
|
|
||||||
- @coreygo
|
|
||||||
- @glennj
|
|
||||||
- @guygastineau
|
|
||||||
- @IsaacG
|
|
||||||
- @kenden
|
|
||||||
- @kotp
|
|
||||||
- @kytrinyx
|
|
||||||
- @MattLewin
|
|
||||||
- @platinumthinker
|
|
||||||
- @quartzinquartz
|
|
||||||
- @rootulp
|
|
||||||
- @sjwarner-bp
|
|
||||||
- @Smarticles101
|
|
||||||
- @ZapAnton
|
|
||||||
|
|
||||||
### Based on
|
|
||||||
|
|
||||||
This is an exercise to introduce users to using Exercism - https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
|
||||||
|
|
@ -1,637 +0,0 @@
|
||||||
# This is the source code for bats-support and bats-assert, concatenated
|
|
||||||
# * https://github.com/bats-core/bats-support
|
|
||||||
# * https://github.com/bats-core/bats-assert
|
|
||||||
#
|
|
||||||
# Comments have been removed to save space. See the git repos for full source code.
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
#
|
|
||||||
# bats-support - Supporting library for Bats test helpers
|
|
||||||
#
|
|
||||||
# Written in 2016 by Zoltan Tombol <zoltan dot tombol at gmail dot com>
|
|
||||||
#
|
|
||||||
# To the extent possible under law, the author(s) have dedicated all
|
|
||||||
# copyright and related and neighboring rights to this software to the
|
|
||||||
# public domain worldwide. This software is distributed without any
|
|
||||||
# warranty.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the CC0 Public Domain Dedication
|
|
||||||
# along with this software. If not, see
|
|
||||||
# <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
fail() {
|
|
||||||
(( $# == 0 )) && batslib_err || batslib_err "$@"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_is_caller() {
|
|
||||||
local -i is_mode_direct=1
|
|
||||||
|
|
||||||
# Handle options.
|
|
||||||
while (( $# > 0 )); do
|
|
||||||
case "$1" in
|
|
||||||
-i|--indirect) is_mode_direct=0; shift ;;
|
|
||||||
--) shift; break ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Arguments.
|
|
||||||
local -r func="$1"
|
|
||||||
|
|
||||||
# Check call stack.
|
|
||||||
if (( is_mode_direct )); then
|
|
||||||
[[ $func == "${FUNCNAME[2]}" ]] && return 0
|
|
||||||
else
|
|
||||||
local -i depth
|
|
||||||
for (( depth=2; depth<${#FUNCNAME[@]}; ++depth )); do
|
|
||||||
[[ $func == "${FUNCNAME[$depth]}" ]] && return 0
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_err() {
|
|
||||||
{ if (( $# > 0 )); then
|
|
||||||
echo "$@"
|
|
||||||
else
|
|
||||||
cat -
|
|
||||||
fi
|
|
||||||
} >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_count_lines() {
|
|
||||||
local -i n_lines=0
|
|
||||||
local line
|
|
||||||
while IFS='' read -r line || [[ -n $line ]]; do
|
|
||||||
(( ++n_lines ))
|
|
||||||
done < <(printf '%s' "$1")
|
|
||||||
echo "$n_lines"
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_is_single_line() {
|
|
||||||
for string in "$@"; do
|
|
||||||
(( $(batslib_count_lines "$string") > 1 )) && return 1
|
|
||||||
done
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_get_max_single_line_key_width() {
|
|
||||||
local -i max_len=-1
|
|
||||||
while (( $# != 0 )); do
|
|
||||||
local -i key_len="${#1}"
|
|
||||||
batslib_is_single_line "$2" && (( key_len > max_len )) && max_len="$key_len"
|
|
||||||
shift 2
|
|
||||||
done
|
|
||||||
echo "$max_len"
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_print_kv_single() {
|
|
||||||
local -ir col_width="$1"; shift
|
|
||||||
while (( $# != 0 )); do
|
|
||||||
printf '%-*s : %s\n' "$col_width" "$1" "$2"
|
|
||||||
shift 2
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_print_kv_multi() {
|
|
||||||
while (( $# != 0 )); do
|
|
||||||
printf '%s (%d lines):\n' "$1" "$( batslib_count_lines "$2" )"
|
|
||||||
printf '%s\n' "$2"
|
|
||||||
shift 2
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_print_kv_single_or_multi() {
|
|
||||||
local -ir width="$1"; shift
|
|
||||||
local -a pairs=( "$@" )
|
|
||||||
|
|
||||||
local -a values=()
|
|
||||||
local -i i
|
|
||||||
for (( i=1; i < ${#pairs[@]}; i+=2 )); do
|
|
||||||
values+=( "${pairs[$i]}" )
|
|
||||||
done
|
|
||||||
|
|
||||||
if batslib_is_single_line "${values[@]}"; then
|
|
||||||
batslib_print_kv_single "$width" "${pairs[@]}"
|
|
||||||
else
|
|
||||||
local -i i
|
|
||||||
for (( i=1; i < ${#pairs[@]}; i+=2 )); do
|
|
||||||
pairs[$i]="$( batslib_prefix < <(printf '%s' "${pairs[$i]}") )"
|
|
||||||
done
|
|
||||||
batslib_print_kv_multi "${pairs[@]}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_prefix() {
|
|
||||||
local -r prefix="${1:- }"
|
|
||||||
local line
|
|
||||||
while IFS='' read -r line || [[ -n $line ]]; do
|
|
||||||
printf '%s%s\n' "$prefix" "$line"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_mark() {
|
|
||||||
local -r symbol="$1"; shift
|
|
||||||
# Sort line numbers.
|
|
||||||
set -- $( sort -nu <<< "$( printf '%d\n' "$@" )" )
|
|
||||||
|
|
||||||
local line
|
|
||||||
local -i idx=0
|
|
||||||
while IFS='' read -r line || [[ -n $line ]]; do
|
|
||||||
if (( ${1:--1} == idx )); then
|
|
||||||
printf '%s\n' "${symbol}${line:${#symbol}}"
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
printf '%s\n' "$line"
|
|
||||||
fi
|
|
||||||
(( ++idx ))
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
batslib_decorate() {
|
|
||||||
echo
|
|
||||||
echo "-- $1 --"
|
|
||||||
cat -
|
|
||||||
echo '--'
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
assert() {
|
|
||||||
if ! "$@"; then
|
|
||||||
batslib_print_kv_single 10 'expression' "$*" \
|
|
||||||
| batslib_decorate 'assertion failed' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_equal() {
|
|
||||||
if [[ $1 != "$2" ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 8 \
|
|
||||||
'expected' "$2" \
|
|
||||||
'actual' "$1" \
|
|
||||||
| batslib_decorate 'values do not equal' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_failure() {
|
|
||||||
: "${output?}"
|
|
||||||
: "${status?}"
|
|
||||||
|
|
||||||
(( $# > 0 )) && local -r expected="$1"
|
|
||||||
if (( status == 0 )); then
|
|
||||||
batslib_print_kv_single_or_multi 6 'output' "$output" \
|
|
||||||
| batslib_decorate 'command succeeded, but it was expected to fail' \
|
|
||||||
| fail
|
|
||||||
elif (( $# > 0 )) && (( status != expected )); then
|
|
||||||
{ local -ir width=8
|
|
||||||
batslib_print_kv_single "$width" \
|
|
||||||
'expected' "$expected" \
|
|
||||||
'actual' "$status"
|
|
||||||
batslib_print_kv_single_or_multi "$width" \
|
|
||||||
'output' "$output"
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'command failed as expected, but status differs' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_line() {
|
|
||||||
local -i is_match_line=0
|
|
||||||
local -i is_mode_partial=0
|
|
||||||
local -i is_mode_regexp=0
|
|
||||||
: "${lines?}"
|
|
||||||
|
|
||||||
# Handle options.
|
|
||||||
while (( $# > 0 )); do
|
|
||||||
case "$1" in
|
|
||||||
-n|--index)
|
|
||||||
if (( $# < 2 )) || ! [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then
|
|
||||||
echo "\`--index' requires an integer argument: \`$2'" \
|
|
||||||
| batslib_decorate 'ERROR: assert_line' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
is_match_line=1
|
|
||||||
local -ri idx="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-p|--partial) is_mode_partial=1; shift ;;
|
|
||||||
-e|--regexp) is_mode_regexp=1; shift ;;
|
|
||||||
--) shift; break ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if (( is_mode_partial )) && (( is_mode_regexp )); then
|
|
||||||
echo "\`--partial' and \`--regexp' are mutually exclusive" \
|
|
||||||
| batslib_decorate 'ERROR: assert_line' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Arguments.
|
|
||||||
local -r expected="$1"
|
|
||||||
|
|
||||||
if (( is_mode_regexp == 1 )) && [[ '' =~ $expected ]] || (( $? == 2 )); then
|
|
||||||
echo "Invalid extended regular expression: \`$expected'" \
|
|
||||||
| batslib_decorate 'ERROR: assert_line' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Matching.
|
|
||||||
if (( is_match_line )); then
|
|
||||||
# Specific line.
|
|
||||||
if (( is_mode_regexp )); then
|
|
||||||
if ! [[ ${lines[$idx]} =~ $expected ]]; then
|
|
||||||
batslib_print_kv_single 6 \
|
|
||||||
'index' "$idx" \
|
|
||||||
'regexp' "$expected" \
|
|
||||||
'line' "${lines[$idx]}" \
|
|
||||||
| batslib_decorate 'regular expression does not match line' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
elif (( is_mode_partial )); then
|
|
||||||
if [[ ${lines[$idx]} != *"$expected"* ]]; then
|
|
||||||
batslib_print_kv_single 9 \
|
|
||||||
'index' "$idx" \
|
|
||||||
'substring' "$expected" \
|
|
||||||
'line' "${lines[$idx]}" \
|
|
||||||
| batslib_decorate 'line does not contain substring' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ ${lines[$idx]} != "$expected" ]]; then
|
|
||||||
batslib_print_kv_single 8 \
|
|
||||||
'index' "$idx" \
|
|
||||||
'expected' "$expected" \
|
|
||||||
'actual' "${lines[$idx]}" \
|
|
||||||
| batslib_decorate 'line differs' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Contained in output.
|
|
||||||
if (( is_mode_regexp )); then
|
|
||||||
local -i idx
|
|
||||||
for (( idx = 0; idx < ${#lines[@]}; ++idx )); do
|
|
||||||
[[ ${lines[$idx]} =~ $expected ]] && return 0
|
|
||||||
done
|
|
||||||
{ local -ar single=( 'regexp' "$expected" )
|
|
||||||
local -ar may_be_multi=( 'output' "$output" )
|
|
||||||
local -ir width="$( batslib_get_max_single_line_key_width "${single[@]}" "${may_be_multi[@]}" )"
|
|
||||||
batslib_print_kv_single "$width" "${single[@]}"
|
|
||||||
batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}"
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'no output line matches regular expression' \
|
|
||||||
| fail
|
|
||||||
elif (( is_mode_partial )); then
|
|
||||||
local -i idx
|
|
||||||
for (( idx = 0; idx < ${#lines[@]}; ++idx )); do
|
|
||||||
[[ ${lines[$idx]} == *"$expected"* ]] && return 0
|
|
||||||
done
|
|
||||||
{ local -ar single=( 'substring' "$expected" )
|
|
||||||
local -ar may_be_multi=( 'output' "$output" )
|
|
||||||
local -ir width="$( batslib_get_max_single_line_key_width "${single[@]}" "${may_be_multi[@]}" )"
|
|
||||||
batslib_print_kv_single "$width" "${single[@]}"
|
|
||||||
batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}"
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'no output line contains substring' \
|
|
||||||
| fail
|
|
||||||
else
|
|
||||||
local -i idx
|
|
||||||
for (( idx = 0; idx < ${#lines[@]}; ++idx )); do
|
|
||||||
[[ ${lines[$idx]} == "$expected" ]] && return 0
|
|
||||||
done
|
|
||||||
{ local -ar single=( 'line' "$expected" )
|
|
||||||
local -ar may_be_multi=( 'output' "$output" )
|
|
||||||
local -ir width="$( batslib_get_max_single_line_key_width "${single[@]}" "${may_be_multi[@]}" )"
|
|
||||||
batslib_print_kv_single "$width" "${single[@]}"
|
|
||||||
batslib_print_kv_single_or_multi "$width" "${may_be_multi[@]}"
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'output does not contain line' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_output() {
|
|
||||||
local -i is_mode_partial=0
|
|
||||||
local -i is_mode_regexp=0
|
|
||||||
local -i is_mode_nonempty=0
|
|
||||||
local -i use_stdin=0
|
|
||||||
: "${output?}"
|
|
||||||
|
|
||||||
# Handle options.
|
|
||||||
if (( $# == 0 )); then
|
|
||||||
is_mode_nonempty=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while (( $# > 0 )); do
|
|
||||||
case "$1" in
|
|
||||||
-p|--partial) is_mode_partial=1; shift ;;
|
|
||||||
-e|--regexp) is_mode_regexp=1; shift ;;
|
|
||||||
-|--stdin) use_stdin=1; shift ;;
|
|
||||||
--) shift; break ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if (( is_mode_partial )) && (( is_mode_regexp )); then
|
|
||||||
echo "\`--partial' and \`--regexp' are mutually exclusive" \
|
|
||||||
| batslib_decorate 'ERROR: assert_output' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Arguments.
|
|
||||||
local expected
|
|
||||||
if (( use_stdin )); then
|
|
||||||
expected="$(cat -)"
|
|
||||||
else
|
|
||||||
expected="${1-}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Matching.
|
|
||||||
if (( is_mode_nonempty )); then
|
|
||||||
if [ -z "$output" ]; then
|
|
||||||
echo 'expected non-empty output, but output was empty' \
|
|
||||||
| batslib_decorate 'no output' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
elif (( is_mode_regexp )); then
|
|
||||||
if [[ '' =~ $expected ]] || (( $? == 2 )); then
|
|
||||||
echo "Invalid extended regular expression: \`$expected'" \
|
|
||||||
| batslib_decorate 'ERROR: assert_output' \
|
|
||||||
| fail
|
|
||||||
elif ! [[ $output =~ $expected ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 6 \
|
|
||||||
'regexp' "$expected" \
|
|
||||||
'output' "$output" \
|
|
||||||
| batslib_decorate 'regular expression does not match output' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
elif (( is_mode_partial )); then
|
|
||||||
if [[ $output != *"$expected"* ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 9 \
|
|
||||||
'substring' "$expected" \
|
|
||||||
'output' "$output" \
|
|
||||||
| batslib_decorate 'output does not contain substring' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ $output != "$expected" ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 8 \
|
|
||||||
'expected' "$expected" \
|
|
||||||
'actual' "$output" \
|
|
||||||
| batslib_decorate 'output differs' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_success() {
|
|
||||||
: "${output?}"
|
|
||||||
: "${status?}"
|
|
||||||
|
|
||||||
if (( status != 0 )); then
|
|
||||||
{ local -ir width=6
|
|
||||||
batslib_print_kv_single "$width" 'status' "$status"
|
|
||||||
batslib_print_kv_single_or_multi "$width" 'output' "$output"
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'command failed' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
refute() {
|
|
||||||
if "$@"; then
|
|
||||||
batslib_print_kv_single 10 'expression' "$*" \
|
|
||||||
| batslib_decorate 'assertion succeeded, but it was expected to fail' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
refute_line() {
|
|
||||||
local -i is_match_line=0
|
|
||||||
local -i is_mode_partial=0
|
|
||||||
local -i is_mode_regexp=0
|
|
||||||
: "${lines?}"
|
|
||||||
|
|
||||||
# Handle options.
|
|
||||||
while (( $# > 0 )); do
|
|
||||||
case "$1" in
|
|
||||||
-n|--index)
|
|
||||||
if (( $# < 2 )) || ! [[ $2 =~ ^([0-9]|[1-9][0-9]+)$ ]]; then
|
|
||||||
echo "\`--index' requires an integer argument: \`$2'" \
|
|
||||||
| batslib_decorate 'ERROR: refute_line' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
is_match_line=1
|
|
||||||
local -ri idx="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-p|--partial) is_mode_partial=1; shift ;;
|
|
||||||
-e|--regexp) is_mode_regexp=1; shift ;;
|
|
||||||
--) shift; break ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if (( is_mode_partial )) && (( is_mode_regexp )); then
|
|
||||||
echo "\`--partial' and \`--regexp' are mutually exclusive" \
|
|
||||||
| batslib_decorate 'ERROR: refute_line' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Arguments.
|
|
||||||
local -r unexpected="$1"
|
|
||||||
|
|
||||||
if (( is_mode_regexp == 1 )) && [[ '' =~ $unexpected ]] || (( $? == 2 )); then
|
|
||||||
echo "Invalid extended regular expression: \`$unexpected'" \
|
|
||||||
| batslib_decorate 'ERROR: refute_line' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Matching.
|
|
||||||
if (( is_match_line )); then
|
|
||||||
# Specific line.
|
|
||||||
if (( is_mode_regexp )); then
|
|
||||||
if [[ ${lines[$idx]} =~ $unexpected ]]; then
|
|
||||||
batslib_print_kv_single 6 \
|
|
||||||
'index' "$idx" \
|
|
||||||
'regexp' "$unexpected" \
|
|
||||||
'line' "${lines[$idx]}" \
|
|
||||||
| batslib_decorate 'regular expression should not match line' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
elif (( is_mode_partial )); then
|
|
||||||
if [[ ${lines[$idx]} == *"$unexpected"* ]]; then
|
|
||||||
batslib_print_kv_single 9 \
|
|
||||||
'index' "$idx" \
|
|
||||||
'substring' "$unexpected" \
|
|
||||||
'line' "${lines[$idx]}" \
|
|
||||||
| batslib_decorate 'line should not contain substring' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ ${lines[$idx]} == "$unexpected" ]]; then
|
|
||||||
batslib_print_kv_single 5 \
|
|
||||||
'index' "$idx" \
|
|
||||||
'line' "${lines[$idx]}" \
|
|
||||||
| batslib_decorate 'line should differ' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Line contained in output.
|
|
||||||
if (( is_mode_regexp )); then
|
|
||||||
local -i idx
|
|
||||||
for (( idx = 0; idx < ${#lines[@]}; ++idx )); do
|
|
||||||
if [[ ${lines[$idx]} =~ $unexpected ]]; then
|
|
||||||
{ local -ar single=( 'regexp' "$unexpected" 'index' "$idx" )
|
|
||||||
local -a may_be_multi=( 'output' "$output" )
|
|
||||||
local -ir width="$( batslib_get_max_single_line_key_width "${single[@]}" "${may_be_multi[@]}" )"
|
|
||||||
batslib_print_kv_single "$width" "${single[@]}"
|
|
||||||
if batslib_is_single_line "${may_be_multi[1]}"; then
|
|
||||||
batslib_print_kv_single "$width" "${may_be_multi[@]}"
|
|
||||||
else
|
|
||||||
may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" | batslib_prefix | batslib_mark '>' "$idx" )"
|
|
||||||
batslib_print_kv_multi "${may_be_multi[@]}"
|
|
||||||
fi
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'no line should match the regular expression' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
elif (( is_mode_partial )); then
|
|
||||||
local -i idx
|
|
||||||
for (( idx = 0; idx < ${#lines[@]}; ++idx )); do
|
|
||||||
if [[ ${lines[$idx]} == *"$unexpected"* ]]; then
|
|
||||||
{ local -ar single=( 'substring' "$unexpected" 'index' "$idx" )
|
|
||||||
local -a may_be_multi=( 'output' "$output" )
|
|
||||||
local -ir width="$( batslib_get_max_single_line_key_width "${single[@]}" "${may_be_multi[@]}" )"
|
|
||||||
batslib_print_kv_single "$width" "${single[@]}"
|
|
||||||
if batslib_is_single_line "${may_be_multi[1]}"; then
|
|
||||||
batslib_print_kv_single "$width" "${may_be_multi[@]}"
|
|
||||||
else
|
|
||||||
may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" | batslib_prefix | batslib_mark '>' "$idx" )"
|
|
||||||
batslib_print_kv_multi "${may_be_multi[@]}"
|
|
||||||
fi
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'no line should contain substring' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
|
||||||
local -i idx
|
|
||||||
for (( idx = 0; idx < ${#lines[@]}; ++idx )); do
|
|
||||||
if [[ ${lines[$idx]} == "$unexpected" ]]; then
|
|
||||||
{ local -ar single=( 'line' "$unexpected" 'index' "$idx" )
|
|
||||||
local -a may_be_multi=( 'output' "$output" )
|
|
||||||
local -ir width="$( batslib_get_max_single_line_key_width "${single[@]}" "${may_be_multi[@]}" )"
|
|
||||||
batslib_print_kv_single "$width" "${single[@]}"
|
|
||||||
if batslib_is_single_line "${may_be_multi[1]}"; then
|
|
||||||
batslib_print_kv_single "$width" "${may_be_multi[@]}"
|
|
||||||
else
|
|
||||||
may_be_multi[1]="$( printf '%s' "${may_be_multi[1]}" | batslib_prefix | batslib_mark '>' "$idx" )"
|
|
||||||
batslib_print_kv_multi "${may_be_multi[@]}"
|
|
||||||
fi
|
|
||||||
} \
|
|
||||||
| batslib_decorate 'line should not be in output' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
refute_output() {
|
|
||||||
local -i is_mode_partial=0
|
|
||||||
local -i is_mode_regexp=0
|
|
||||||
local -i is_mode_empty=0
|
|
||||||
local -i use_stdin=0
|
|
||||||
: "${output?}"
|
|
||||||
|
|
||||||
# Handle options.
|
|
||||||
if (( $# == 0 )); then
|
|
||||||
is_mode_empty=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while (( $# > 0 )); do
|
|
||||||
case "$1" in
|
|
||||||
-p|--partial) is_mode_partial=1; shift ;;
|
|
||||||
-e|--regexp) is_mode_regexp=1; shift ;;
|
|
||||||
-|--stdin) use_stdin=1; shift ;;
|
|
||||||
--) shift; break ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if (( is_mode_partial )) && (( is_mode_regexp )); then
|
|
||||||
echo "\`--partial' and \`--regexp' are mutually exclusive" \
|
|
||||||
| batslib_decorate 'ERROR: refute_output' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Arguments.
|
|
||||||
local unexpected
|
|
||||||
if (( use_stdin )); then
|
|
||||||
unexpected="$(cat -)"
|
|
||||||
else
|
|
||||||
unexpected="${1-}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (( is_mode_regexp == 1 )) && [[ '' =~ $unexpected ]] || (( $? == 2 )); then
|
|
||||||
echo "Invalid extended regular expression: \`$unexpected'" \
|
|
||||||
| batslib_decorate 'ERROR: refute_output' \
|
|
||||||
| fail
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Matching.
|
|
||||||
if (( is_mode_empty )); then
|
|
||||||
if [ -n "$output" ]; then
|
|
||||||
batslib_print_kv_single_or_multi 6 \
|
|
||||||
'output' "$output" \
|
|
||||||
| batslib_decorate 'output non-empty, but expected no output' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
elif (( is_mode_regexp )); then
|
|
||||||
if [[ $output =~ $unexpected ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 6 \
|
|
||||||
'regexp' "$unexpected" \
|
|
||||||
'output' "$output" \
|
|
||||||
| batslib_decorate 'regular expression should not match output' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
elif (( is_mode_partial )); then
|
|
||||||
if [[ $output == *"$unexpected"* ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 9 \
|
|
||||||
'substring' "$unexpected" \
|
|
||||||
'output' "$output" \
|
|
||||||
| batslib_decorate 'output should not contain substring' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [[ $output == "$unexpected" ]]; then
|
|
||||||
batslib_print_kv_single_or_multi 6 \
|
|
||||||
'output' "$output" \
|
|
||||||
| batslib_decorate 'output equals, but it was expected to differ' \
|
|
||||||
| fail
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#!/usr/bin/env bats
|
|
||||||
load bats-extra
|
|
||||||
|
|
||||||
# local version: 1.1.0.0
|
|
||||||
|
|
||||||
@test "Say Hi!" {
|
|
||||||
run bash hello_world.sh
|
|
||||||
|
|
||||||
# the program's exit status should be success (0)
|
|
||||||
assert_success
|
|
||||||
|
|
||||||
# program's output should be the expected text
|
|
||||||
assert_output "Hello, World!"
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
echo "Hello, World!"
|
|
||||||
23
cpp/.gitignore
vendored
23
cpp/.gitignore
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
# Билд-артефакты
|
|
||||||
build/
|
|
||||||
**/*build*/
|
|
||||||
*.sln
|
|
||||||
*.vcxproj*
|
|
||||||
*.cmake
|
|
||||||
CMakeCache.txt
|
|
||||||
CMakeFiles/
|
|
||||||
Makefile
|
|
||||||
|
|
||||||
.cache/
|
|
||||||
|
|
||||||
# Бинарники
|
|
||||||
*.out
|
|
||||||
*.exe
|
|
||||||
*.a
|
|
||||||
*.so
|
|
||||||
*.dll
|
|
||||||
|
|
||||||
# Отладка
|
|
||||||
*.ilk
|
|
||||||
*.pdb
|
|
||||||
*.dSYM/
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
"authors": [
|
|
||||||
"samsondstl"
|
|
||||||
],
|
|
||||||
"contributors": [
|
|
||||||
"elyashiv",
|
|
||||||
"jackhughesweb",
|
|
||||||
"KevinWMatthews",
|
|
||||||
"patricksjackson",
|
|
||||||
"sturzl"
|
|
||||||
],
|
|
||||||
"files": {
|
|
||||||
"solution": [
|
|
||||||
"hello_world.cpp",
|
|
||||||
"hello_world.h"
|
|
||||||
],
|
|
||||||
"test": [
|
|
||||||
"hello_world_test.cpp"
|
|
||||||
],
|
|
||||||
"example": [
|
|
||||||
".meta/example.cpp",
|
|
||||||
".meta/example.h"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".",
|
|
||||||
"source": "This is an exercise to introduce users to using Exercism",
|
|
||||||
"source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program"
|
|
||||||
}
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
# Get the exercise name from the current directory
|
|
||||||
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
|
||||||
|
|
||||||
# Basic CMake project
|
|
||||||
cmake_minimum_required(VERSION 3.5.1)
|
|
||||||
|
|
||||||
# Name the project after the exercise
|
|
||||||
project(${exercise} CXX)
|
|
||||||
|
|
||||||
# Get a source filename from the exercise name by replacing -'s with _'s
|
|
||||||
string(REPLACE "-" "_" file ${exercise})
|
|
||||||
|
|
||||||
# Implementation could be only a header
|
|
||||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
|
|
||||||
set(exercise_cpp ${file}.cpp)
|
|
||||||
else()
|
|
||||||
set(exercise_cpp "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Use the common Catch library?
|
|
||||||
if(EXERCISM_COMMON_CATCH)
|
|
||||||
# For Exercism track development only
|
|
||||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $<TARGET_OBJECTS:catchlib>)
|
|
||||||
elseif(EXERCISM_TEST_SUITE)
|
|
||||||
# The Exercism test suite is being run, the Docker image already
|
|
||||||
# includes a pre-built version of Catch.
|
|
||||||
find_package(Catch2 REQUIRED)
|
|
||||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h)
|
|
||||||
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain)
|
|
||||||
# When Catch is installed system wide we need to include a different
|
|
||||||
# header, we need this define to use the correct one.
|
|
||||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE)
|
|
||||||
else()
|
|
||||||
# Build executable from sources and headers
|
|
||||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(${exercise} PROPERTIES
|
|
||||||
CXX_STANDARD 17
|
|
||||||
CXX_STANDARD_REQUIRED OFF
|
|
||||||
CXX_EXTENSIONS OFF
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
|
||||||
|
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
|
|
||||||
set_target_properties(${exercise} PROPERTIES
|
|
||||||
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Configure to run all the tests?
|
|
||||||
if(${EXERCISM_RUN_ALL_TESTS})
|
|
||||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Tell MSVC not to warn us about unchecked iterators in debug builds
|
|
||||||
# Treat warnings as errors
|
|
||||||
# Treat type conversion warnings C4244 and C4267 as level 4 warnings, i.e. ignore them in level 3
|
|
||||||
if(${MSVC})
|
|
||||||
set_target_properties(${exercise} PROPERTIES
|
|
||||||
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS
|
|
||||||
COMPILE_FLAGS "/WX /w44244 /w44267")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Run the tests on every build
|
|
||||||
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise})
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
# Help
|
|
||||||
|
|
||||||
## Running the tests
|
|
||||||
|
|
||||||
Running the tests involves running `cmake -G` and then using the build command appropriate for your platform.
|
|
||||||
Detailed instructions on how to do this can be found on the [Running the Tests][cpp-tests-instructions] page for C++ on exercism.org.
|
|
||||||
|
|
||||||
## Passing the Tests
|
|
||||||
|
|
||||||
When you start a new exercise locally, the files are configured so that only the first test is performed.
|
|
||||||
Get that first test compiling, linking and passing by following the [three rules of test-driven development][three-laws-of-tdd].
|
|
||||||
Create just enough structure by declaring namespaces, functions, classes, etc., to satisfy any compiler errors and get the test to fail.
|
|
||||||
Then write just enough code to get the test to pass.
|
|
||||||
Once you've done that, uncomment the next test by moving the line `if defined(EXERCISM_RUN_ALL_TESTS)` past the next test.
|
|
||||||
|
|
||||||
See the example below from the Bob exercise (file `bob_test.cpp`, line 15):
|
|
||||||
|
|
||||||
```diff
|
|
||||||
-#if defined(EXERCISM_RUN_ALL_TESTS)
|
|
||||||
TEST_CASE("shouting")
|
|
||||||
{
|
|
||||||
REQUIRE("Whoa, chill out!" == bob::hey("WATCH OUT!"));
|
|
||||||
}
|
|
||||||
+#if defined(EXERCISM_RUN_ALL_TESTS)
|
|
||||||
```
|
|
||||||
|
|
||||||
Moving this line past the next test may result in compile errors as new constructs may be invoked that you haven't yet declared or defined.
|
|
||||||
Again, fix the compile errors minimally to get a failing test, then change the code minimally to pass the test, refactor your implementation for readability and expressiveness and then go on to the next test.
|
|
||||||
|
|
||||||
Try to use standard C++17 facilities in preference to writing your own low-level algorithms or facilities by hand.
|
|
||||||
|
|
||||||
[cpp-tests-instructions]: https://exercism.org/docs/tracks/cpp/tests
|
|
||||||
[three-laws-of-tdd]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
|
||||||
|
|
||||||
## Submitting your solution
|
|
||||||
|
|
||||||
You can submit your solution using the `exercism submit hello_world.cpp hello_world.h` command.
|
|
||||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
|
||||||
|
|
||||||
It's possible to submit an incomplete solution which allows you to:
|
|
||||||
|
|
||||||
- See how others have completed the exercise
|
|
||||||
- Request help from a mentor
|
|
||||||
|
|
||||||
## Need to get help?
|
|
||||||
|
|
||||||
If you'd like help solving the exercise, check the following pages:
|
|
||||||
|
|
||||||
- The [C++ track's documentation](https://exercism.org/docs/tracks/cpp)
|
|
||||||
- The [C++ track's programming category on the forum](https://forum.exercism.org/c/programming/cpp)
|
|
||||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
|
||||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
|
||||||
|
|
||||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
|
||||||
|
|
||||||
To get help if you're having trouble, you can use one of the following resources:
|
|
||||||
|
|
||||||
- [`c++-faq` tag on StackOverflow](https://stackoverflow.com/tags/c%2b%2b-faq/info)
|
|
||||||
- [C++ FAQ from isocpp.com](https://isocpp.org/faq)
|
|
||||||
- [CppReference](http://en.cppreference.com/) is a wiki reference to the C++ language and standard library
|
|
||||||
- [C traps and pitfalls](http://www.slideshare.net/LegalizeAdulthood/c-traps-and-pitfalls-for-c-programmers) is useful if you are new to C++, but have programmed in C
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
# Hello World
|
|
||||||
|
|
||||||
Welcome to Hello World on Exercism's C++ Track.
|
|
||||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
|
||||||
|
|
||||||
## Instructions
|
|
||||||
|
|
||||||
The classical introductory exercise.
|
|
||||||
Just say "Hello, World!".
|
|
||||||
|
|
||||||
["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment.
|
|
||||||
|
|
||||||
The objectives are simple:
|
|
||||||
|
|
||||||
- Modify the provided code so that it produces the string "Hello, World!".
|
|
||||||
- Run the test suite and make sure that it succeeds.
|
|
||||||
- Submit your solution and check it at the website.
|
|
||||||
|
|
||||||
If everything goes well, you will be ready to fetch your first real exercise.
|
|
||||||
|
|
||||||
[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
|
||||||
|
|
||||||
## Source
|
|
||||||
|
|
||||||
### Created by
|
|
||||||
|
|
||||||
- @samsondstl
|
|
||||||
|
|
||||||
### Contributed to by
|
|
||||||
|
|
||||||
- @elyashiv
|
|
||||||
- @jackhughesweb
|
|
||||||
- @KevinWMatthews
|
|
||||||
- @patricksjackson
|
|
||||||
- @sturzl
|
|
||||||
|
|
||||||
### Based on
|
|
||||||
|
|
||||||
This is an exercise to introduce users to using Exercism - https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#include "hello_world.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace hello_world {
|
|
||||||
|
|
||||||
string hello() { return "Hello, World!"; }
|
|
||||||
|
|
||||||
} // namespace hello_world
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
// This is an include guard.
|
|
||||||
// You could alternatively use '#pragma once'
|
|
||||||
// See https://en.wikipedia.org/wiki/Include_guard
|
|
||||||
#if !defined(HELLO_WORLD_H)
|
|
||||||
#define HELLO_WORLD_H
|
|
||||||
|
|
||||||
// Include the string header so that we have access to 'std::string'
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
// Declare a namespace for the function(s) we are exporting.
|
|
||||||
// https://en.cppreference.com/w/cpp/language/namespace
|
|
||||||
namespace hello_world {
|
|
||||||
|
|
||||||
// Declare the 'hello()' function, which takes no arguments and returns a
|
|
||||||
// 'std::string'. The function itself is defined in the hello_world.cpp source
|
|
||||||
// file. Because it is inside of the 'hello_world' namespace, it's full name is
|
|
||||||
// 'hello_world::hello()'.
|
|
||||||
std::string hello();
|
|
||||||
|
|
||||||
} // namespace hello_world
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
// Include the header file with the definitions of the functions you create.
|
|
||||||
#include "hello_world.h"
|
|
||||||
|
|
||||||
// Include the test framework.
|
|
||||||
#ifdef EXERCISM_TEST_SUITE
|
|
||||||
#include <catch2/catch.hpp>
|
|
||||||
#else
|
|
||||||
#include "test/catch.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Declares a single test.
|
|
||||||
TEST_CASE("test_hello") {
|
|
||||||
// Check if your function returns "Hello, World!".
|
|
||||||
REQUIRE(hello_world::hello() == "Hello, World!");
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,2 +0,0 @@
|
||||||
#define CATCH_CONFIG_MAIN
|
|
||||||
#include "catch.hpp"
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"authors": [
|
|
||||||
"massivelivefun"
|
|
||||||
],
|
|
||||||
"files": {
|
|
||||||
"solution": [
|
|
||||||
"hello_world.zig"
|
|
||||||
],
|
|
||||||
"test": [
|
|
||||||
"test_hello_world.zig"
|
|
||||||
],
|
|
||||||
"example": [
|
|
||||||
".meta/example.zig"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".",
|
|
||||||
"source": "This is an exercise to introduce users to using Exercism",
|
|
||||||
"source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program"
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
# Help
|
|
||||||
|
|
||||||
## Running the tests
|
|
||||||
|
|
||||||
Write your code in `<exercise_name>.zig`.
|
|
||||||
|
|
||||||
To run the tests for an exercise, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
zig test test_exercise_name.zig
|
|
||||||
```
|
|
||||||
|
|
||||||
in the exercise's root directory (replacing `exercise_name` with the name of the exercise).
|
|
||||||
|
|
||||||
## Submitting your solution
|
|
||||||
|
|
||||||
You can submit your solution using the `exercism submit hello_world.zig` command.
|
|
||||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
|
||||||
|
|
||||||
It's possible to submit an incomplete solution which allows you to:
|
|
||||||
|
|
||||||
- See how others have completed the exercise
|
|
||||||
- Request help from a mentor
|
|
||||||
|
|
||||||
## Need to get help?
|
|
||||||
|
|
||||||
If you'd like help solving the exercise, check the following pages:
|
|
||||||
|
|
||||||
- The [Zig track's documentation](https://exercism.org/docs/tracks/zig)
|
|
||||||
- The [Zig track's programming category on the forum](https://forum.exercism.org/c/programming/zig)
|
|
||||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
|
||||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
|
||||||
|
|
||||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
|
||||||
|
|
||||||
- [The Zig Programming Language Documentation][documentation] is a great overview of all of the language features that Zig provides to those who use it.
|
|
||||||
- [Zig Guide][zig-guide] is an excellent primer that explains the language features that Zig has to offer.
|
|
||||||
- [Ziglings][ziglings] is highly recommended.
|
|
||||||
Learn Zig by fixing tiny broken programs.
|
|
||||||
- [The Zig Programming Language Discord][discord-zig] is the main [Discord][discord].
|
|
||||||
It provides a great way to get in touch with the Zig community at large, and get some quick, direct help for any Zig related problem.
|
|
||||||
- [#zig][irc] on irc.freenode.net is the main Zig IRC channel.
|
|
||||||
- [/r/Zig][reddit] is the main Zig subreddit.
|
|
||||||
- [Stack Overflow][stack-overflow] can be used to discover code snippets and solutions to problems that may have already asked and maybe solved by others.
|
|
||||||
|
|
||||||
[discord]: https://discordapp.com
|
|
||||||
[discord-zig]: https://discord.com/invite/gxsFFjE
|
|
||||||
[documentation]: https://ziglang.org/documentation/master
|
|
||||||
[irc]: https://webchat.freenode.net/?channels=%23zig
|
|
||||||
[reddit]: https://www.reddit.com/r/Zig
|
|
||||||
[stack-overflow]: https://stackoverflow.com/questions/tagged/zig
|
|
||||||
[zig-guide]: https://zig.guide/
|
|
||||||
[ziglings]: https://codeberg.org/ziglings/exercises
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
# Hello World
|
|
||||||
|
|
||||||
Welcome to Hello World on Exercism's Zig Track.
|
|
||||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
|
||||||
|
|
||||||
## Instructions
|
|
||||||
|
|
||||||
The classical introductory exercise.
|
|
||||||
Just say "Hello, World!".
|
|
||||||
|
|
||||||
["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment.
|
|
||||||
|
|
||||||
The objectives are simple:
|
|
||||||
|
|
||||||
- Modify the provided code so that it produces the string "Hello, World!".
|
|
||||||
- Run the test suite and make sure that it succeeds.
|
|
||||||
- Submit your solution and check it at the website.
|
|
||||||
|
|
||||||
If everything goes well, you will be ready to fetch your first real exercise.
|
|
||||||
|
|
||||||
[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
|
||||||
|
|
||||||
## Source
|
|
||||||
|
|
||||||
### Created by
|
|
||||||
|
|
||||||
- @massivelivefun
|
|
||||||
|
|
||||||
### Based on
|
|
||||||
|
|
||||||
This is an exercise to introduce users to using Exercism - https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
pub fn hello() []const u8 {
|
|
||||||
return "Hello, World!";
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const testing = std.testing;
|
|
||||||
|
|
||||||
const hello_world = @import("hello_world.zig");
|
|
||||||
|
|
||||||
test "say hi!" {
|
|
||||||
const expected = "Hello, World!";
|
|
||||||
const actual = hello_world.hello();
|
|
||||||
try testing.expectEqualStrings(expected, actual);
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue