Merge remote-tracking branch 'origin/main' into worktree

This commit is contained in:
Edward Thomson
2024-03-05 09:44:16 +00:00
2634 changed files with 94749 additions and 35546 deletions

View File

@@ -1,70 +1,6 @@
FIND_PACKAGE(PythonInterp)
# The main libgit2 tests tree: this CMakeLists.txt includes the
# subprojects that make up core libgit2 support.
IF(NOT PYTHONINTERP_FOUND)
MESSAGE(FATAL_ERROR "Could not find a python interpeter, which is needed to build the tests. "
"Make sure python is available, or pass -DBUILD_CLAR=OFF to skip building the tests")
ENDIF()
SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/")
SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\")
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
# Ensure that we do not use deprecated functions internally
ADD_DEFINITIONS(-DGIT_DEPRECATE_HARD)
INCLUDE_DIRECTORIES(${CLAR_PATH} ${libgit2_BINARY_DIR}/src)
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h)
SET(SRC_CLAR "main.c" "clar_libgit2.c" "clar_libgit2_trace.c" "clar_libgit2_timer.c" "clar.c")
IF(MSVC_IDE)
LIST(APPEND SRC_CLAR "precompiled.c")
ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite
COMMAND ${PYTHON_EXECUTABLE} generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf .
DEPENDS ${SRC_TEST}
WORKING_DIRECTORY ${CLAR_PATH}
)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
SET_SOURCE_FILES_PROPERTIES(
${CLAR_PATH}/clar.c
PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite)
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
INCLUDE_DIRECTORIES(SYSTEM ${LIBGIT2_SYSTEM_INCLUDES})
ADD_EXECUTABLE(libgit2_clar ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS})
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES C_STANDARD 90)
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${libgit2_BINARY_DIR})
TARGET_INCLUDE_DIRECTORIES(libgit2_clar PRIVATE ../src PUBLIC ../include)
TARGET_LINK_LIBRARIES(libgit2_clar ${LIBGIT2_LIBS})
IDE_SPLIT_SOURCES(libgit2_clar)
IF (MSVC_IDE)
# Precompiled headers
SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
SET_SOURCE_FILES_PROPERTIES("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h")
ENDIF ()
FUNCTION(ADD_CLAR_TEST name)
IF (NOT USE_LEAK_CHECKER STREQUAL "OFF")
ADD_TEST(${name} "${libgit2_SOURCE_DIR}/script/${USE_LEAK_CHECKER}.sh" "${libgit2_BINARY_DIR}/libgit2_clar" ${ARGN})
ELSE()
ADD_TEST(${name} "${libgit2_BINARY_DIR}/libgit2_clar" ${ARGN})
ENDIF()
ENDFUNCTION(ADD_CLAR_TEST)
ADD_CLAR_TEST(offline -v -xonline)
ADD_CLAR_TEST(invasive -v -score::ftruncate -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root)
ADD_CLAR_TEST(online -v -sonline)
ADD_CLAR_TEST(gitdaemon -v -sonline::push)
ADD_CLAR_TEST(ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh)
ADD_CLAR_TEST(proxy -v -sonline::clone::proxy)
ADD_CLAR_TEST(auth_clone -v -sonline::clone::cred)
ADD_CLAR_TEST(auth_clone_and_push -v -sonline::clone::push -sonline::push)
add_subdirectory(headertest)
add_subdirectory(libgit2)
add_subdirectory(util)

View File

@@ -1,48 +1,83 @@
Writing Clar tests for libgit2
==============================
# libgit2 tests
For information on the Clar testing framework and a detailed introduction
please visit:
These are the unit and integration tests for the libgit2 projects.
https://github.com/vmg/clar
* `benchmarks`
These are benchmark tests that excercise the CLI.
* `clar`
This is [clar](https://github.com/clar-test/clar) the common test framework.
* `headertest`
This is a simple project that ensures that our public headers are
compatible with extremely strict compilation options.
* `libgit2`
These tests exercise the core git functionality in libgit2 itself.
* `resources`
These are the resources for the tests, including files and git
repositories.
* `util`
These are tests of the common utility library.
## Writing tests for libgit2
* Write your modules and tests. Use good, meaningful names.
libgit2 uses the [clar test framework](http://github.com/clar-test/clar), a
C testing framework.
* Make sure you actually build the tests by setting:
The best resources for learning clar are [clar itself](https://github.com/clar-test/clar)
and the existing tests within libgit2. In general:
cmake -DBUILD_CLAR=ON build/
* If you place a `.c` file into a test directory, it is eligible to contain
test cases.
* The function name for your test is important; test function names begin
with `test_`, followed by the folder path (underscore separated), two
underscores as a delimiter, then the test name. For example, a file
`merge/analysis.c` may contain a test `uptodate`:
* Test:
```
void test_merge_analysis__uptodate(void)
{
...
}
```
./build/libgit2_clar
* You can run an individual test by passing `-s` to the test runner. Tests
are referred to by their function names; for example, the function
`test_merge_analysis__uptodate` is referred to as `merge::analysis::uptodate`.
To run only that function you can use the `-s` option on the test runner:
* Make sure everything is fine.
```
libgit2_tests -smerge::analysis::uptodate
```
* Send your pull request. That's it.
Memory leak checks
------------------
## Memory leak checking
These are automatically run as part of CI, but if you want to check locally:
#### Linux
### Linux
Uses [`valgrind`](http://www.valgrind.org/):
```console
$ cmake -DBUILD_CLAR=ON -DVALGRIND=ON ..
$ cmake -DBUILD_TESTS=ON -DVALGRIND=ON ..
$ cmake --build .
$ valgrind --leak-check=full --show-reachable=yes --num-callers=50 --suppressions=../libgit2_clar.supp \
./libgit2_clar
$ valgrind --leak-check=full --show-reachable=yes --num-callers=50 --suppressions=../libgit2_tests.supp \
./libgit2_tests
```
#### macOS
### macOS
Uses [`leaks`](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/FindingLeaks.html), which requires XCode installed:
```console
$ MallocStackLogging=1 MallocScribble=1 MallocLogFile=/dev/null CLAR_AT_EXIT="leaks -quiet \$PPID" \
./libgit2_clar
./libgit2_tests
```
### Windows
Build with the `WIN32_LEAKCHECK` option:
```console
$ cmake -DBUILD_TESTS=ON -DWIN32_LEAKCHECK=ON ..
$ cmake --build .
$ ./libgit2_tests
```

121
tests/benchmarks/README.md Normal file
View File

@@ -0,0 +1,121 @@
# libgit2 benchmarks
This folder contains the individual benchmark tests for libgit2,
meant for understanding the performance characteristics of libgit2,
comparing your development code to the existing libgit2 code, or
comparing libgit2 to the git reference implementation.
## Running benchmark tests
Benchmark tests can be run in several different ways: running all
benchmarks, running one (or more) suite of benchmarks, or running a
single individual benchmark. You can target either an individual
version of a CLI, or you can A/B test a baseline CLI against a test
CLI.
### Specifying the command-line interface to test
By default, the `git` in your path is benchmarked. Use the
`-c` (or `--cli`) option to specify the command-line interface
to test.
Example: `libgit2_bench --cli git2_cli` will run the tests against
`git2_cli`.
### Running tests to compare two different implementations
You can compare a baseline command-line interface against a test
command-line interface using the `-b (or `--baseline-cli`) option.
Example: `libgit2_bench --baseline-cli git --cli git2_cli` will
run the tests against both `git` and `git2_cli`.
### Running individual benchmark tests
Similar to how a test suite or individual test is specified in
[clar](https://github.com/clar-test/clar), the `-s` (or `--suite`)
option may be used to specify the suite or individual test to run.
Like clar, the suite and test name are separated by `::`, and like
clar, this is a prefix match.
Examples:
* `libgit2_bench -shash_object` will run the tests in the
`hash_object` suite.
* `libgit2_bench -shash_object::random_1kb` will run the
`hash_object::random_1kb` test.
* `libgit2_bench -shash_object::random` will run all the tests that
begin with `hash_object::random`.
## Writing benchmark tests
Benchmark tests are meant to be easy to write. Each individual
benchmark is a shell script that allows it to do set up (eg, creating
or cloning a repository, creating temporary files, etc), then running
benchmarks, then teardown.
The `benchmark_helpers.sh` script provides many helpful utility
functions to allow for cross-platform benchmarking, as well as a
wrapper for `hyperfine` that is suited to testing libgit2.
Note that the helper script must be included first, at the beginning
of the benchmark test.
### Benchmark example
This simplistic example compares the speed of running the `git help`
command in the baseline CLI to the test CLI.
```bash
#!/bin/bash -e
# include the benchmark library
. "$(dirname "$0")/benchmark_helpers.sh"
# run the "help" command; this will benchmark `git2_cli help`
gitbench help
```
### Naming
The filename of the benchmark itself is important. A benchmark's
filename should be the name of the benchmark suite, followed by two
underscores, followed by the name of the benchmark. For example,
`hash-object__random_1kb` is the `random_1kb` test in the `hash-object`
suite.
### Options
The `gitbench` function accepts several options.
* `--sandbox <path>`
The name of a test resource (in the `tests/resources` directory).
This will be copied as-is to the sandbox location before test
execution. This is copied _before_ the `prepare` script is run.
This option may be specified multiple times.
* `--repository <path>`
The name of a test resource repository (in the `tests/resources`
directory). This repository will be copied into a sandbox location
before test execution, and your test will run in this directory.
This is copied _before_ the `prepare` script is run.
* `--prepare <script>`
A script to run before each invocation of the test is run. This can
set up data for the test that will _not_ be timed. This script is run
in bash on all platforms.
Several helper functions are available within the context of a prepare
script:
* `flush_disk_cache`
Calling this will flush the disk cache before each test run.
This should probably be run at the end of the `prepare` script.
* `create_random_file <path> [<size>]`
Calling this will populate a file at the given `path` with `size`
bytes of random data.
* `create_text_file <path> [<size>]`
Calling this will populate a file at the given `path` with `size`
bytes of predictable text, with the platform line endings. This
is preferred over random data as it's reproducible.
* `--warmup <n>`
Specifies that the test should run `n` times before actually measuring
the timing; useful for "warming up" a cache.

306
tests/benchmarks/benchmark.sh Executable file
View File

@@ -0,0 +1,306 @@
#!/bin/bash
set -eo pipefail
#
# parse the command line
#
usage() { echo "usage: $(basename "$0") [--cli <path>] [--name <cli-name>] [--baseline-cli <path>] [--suite <suite>] [--json <path>] [--zip <path>] [--verbose] [--debug]"; }
TEST_CLI="git"
TEST_CLI_NAME=
BASELINE_CLI=
SUITE=
JSON_RESULT=
ZIP_RESULT=
OUTPUT_DIR=
VERBOSE=
DEBUG=
NEXT=
for a in "$@"; do
if [ "${NEXT}" = "cli" ]; then
TEST_CLI="${a}"
NEXT=
elif [ "${NEXT}" = "name" ]; then
TEST_CLI_NAME="${a}"
NEXT=
elif [ "${NEXT}" = "baseline-cli" ]; then
BASELINE_CLI="${a}"
NEXT=
elif [ "${NEXT}" = "suite" ]; then
SUITE="${a}"
NEXT=
elif [ "${NEXT}" = "json" ]; then
JSON_RESULT="${a}"
NEXT=
elif [ "${NEXT}" = "zip" ]; then
ZIP_RESULT="${a}"
NEXT=
elif [ "${NEXT}" = "output-dir" ]; then
OUTPUT_DIR="${a}"
NEXT=
elif [ "${a}" = "c" ] || [ "${a}" = "--cli" ]; then
NEXT="cli"
elif [[ "${a}" == "-c"* ]]; then
TEST_CLI="${a/-c/}"
elif [ "${a}" = "n" ] || [ "${a}" = "--name" ]; then
NEXT="name"
elif [[ "${a}" == "-n"* ]]; then
TEST_CLI_NAME="${a/-n/}"
elif [ "${a}" = "b" ] || [ "${a}" = "--baseline-cli" ]; then
NEXT="baseline-cli"
elif [[ "${a}" == "-b"* ]]; then
BASELINE_CLI="${a/-b/}"
elif [ "${a}" = "-s" ] || [ "${a}" = "--suite" ]; then
NEXT="suite"
elif [[ "${a}" == "-s"* ]]; then
SUITE="${a/-s/}"
elif [ "${a}" = "-v" ] || [ "${a}" == "--verbose" ]; then
VERBOSE=1
elif [ "${a}" == "--debug" ]; then
VERBOSE=1
DEBUG=1
elif [ "${a}" = "-j" ] || [ "${a}" == "--json" ]; then
NEXT="json"
elif [[ "${a}" == "-j"* ]]; then
JSON_RESULT="${a/-j/}"
elif [ "${a}" = "-z" ] || [ "${a}" == "--zip" ]; then
NEXT="zip"
elif [[ "${a}" == "-z"* ]]; then
ZIP_RESULT="${a/-z/}"
elif [ "${a}" = "--output-dir" ]; then
NEXT="output-dir"
else
echo "$(basename "$0"): unknown option: ${a}" 1>&2
usage 1>&2
exit 1
fi
done
if [ "${NEXT}" != "" ]; then
usage 1>&2
exit 1
fi
if [ "${OUTPUT_DIR}" = "" ]; then
OUTPUT_DIR=${OUTPUT_DIR:="$(mktemp -d)"}
CLEANUP_DIR=1
fi
#
# collect some information about the test environment
#
SYSTEM_OS=$(uname -s)
if [ "${SYSTEM_OS}" = "Darwin" ]; then SYSTEM_OS="macOS"; fi
SYSTEM_KERNEL=$(uname -v)
fullpath() {
if [[ "$(uname -s)" == "MINGW"* && $(cygpath -u "${TEST_CLI}") == "/"* ]]; then
echo "${TEST_CLI}"
elif [[ "${TEST_CLI}" == "/"* ]]; then
echo "${TEST_CLI}"
else
which "${TEST_CLI}"
fi
}
cli_version() {
if [[ "$(uname -s)" == "MINGW"* ]]; then
$(cygpath -u "$1") --version
else
"$1" --version
fi
}
TEST_CLI_NAME=$(basename "${TEST_CLI}")
TEST_CLI_PATH=$(fullpath "${TEST_CLI}")
TEST_CLI_VERSION=$(cli_version "${TEST_CLI}")
if [ "${BASELINE_CLI}" != "" ]; then
if [[ "${BASELINE_CLI}" == "/"* ]]; then
BASELINE_CLI_PATH="${BASELINE_CLI}"
else
BASELINE_CLI_PATH=$(which "${BASELINE_CLI}")
fi
BASELINE_CLI_NAME=$(basename "${BASELINE_CLI}")
BASELINE_CLI_PATH=$(fullpath "${BASELINE_CLI}")
BASELINE_CLI_VERSION=$(cli_version "${BASELINE_CLI}")
fi
#
# run the benchmarks
#
echo "##############################################################################"
if [ "${SUITE}" != "" ]; then
SUITE_PREFIX="${SUITE/::/__}"
echo "## Running ${SUITE} benchmarks"
else
echo "## Running all benchmarks"
fi
echo "##############################################################################"
echo ""
if [ "${BASELINE_CLI}" != "" ]; then
echo "# Baseline CLI: ${BASELINE_CLI} (${BASELINE_CLI_VERSION})"
fi
echo "# Test CLI: ${TEST_CLI} (${TEST_CLI_VERSION})"
echo ""
BENCHMARK_DIR=${BENCHMARK_DIR:=$(dirname "$0")}
ANY_FOUND=
ANY_FAILED=
indent() { sed "s/^/ /"; }
time_in_ms() { if [ "$(uname -s)" = "Darwin" ]; then date "+%s000"; else date "+%s%N" ; fi; }
humanize_secs() {
units=('s' 'ms' 'us' 'ns')
unit=0
time="${1}"
if [ "${time}" = "" ]; then
echo ""
return
fi
# bash doesn't do floating point arithmetic. ick.
while [[ "${time}" == "0."* ]] && [ "$((unit+1))" != "${#units[*]}" ]; do
time="$(echo | awk "{ print ${time} * 1000 }")"
unit=$((unit+1))
done
echo "${time} ${units[$unit]}"
}
TIME_START=$(time_in_ms)
for TEST_PATH in "${BENCHMARK_DIR}"/*; do
TEST_FILE=$(basename "${TEST_PATH}")
if [ ! -f "${TEST_PATH}" ] || [ ! -x "${TEST_PATH}" ]; then
continue
fi
if [[ "${TEST_FILE}" != *"__"* ]]; then
continue
fi
if [[ "${TEST_FILE}" != "${SUITE_PREFIX}"* ]]; then
continue
fi
ANY_FOUND=1
TEST_NAME="${TEST_FILE/__/::}"
echo -n "${TEST_NAME}:"
if [ "${VERBOSE}" = "1" ]; then
echo ""
else
echo -n " "
fi
if [ "${DEBUG}" = "1" ]; then
SHOW_OUTPUT="--show-output"
fi
OUTPUT_FILE="${OUTPUT_DIR}/${TEST_FILE}.out"
JSON_FILE="${OUTPUT_DIR}/${TEST_FILE}.json"
ERROR_FILE="${OUTPUT_DIR}/${TEST_FILE}.err"
FAILED=
${TEST_PATH} --cli "${TEST_CLI}" --baseline-cli "${BASELINE_CLI}" --json "${JSON_FILE}" ${SHOW_OUTPUT} >"${OUTPUT_FILE}" 2>"${ERROR_FILE}" || FAILED=1
if [ "${FAILED}" = "1" ]; then
if [ "${VERBOSE}" != "1" ]; then
echo "failed!"
fi
indent < "${ERROR_FILE}"
ANY_FAILED=1
continue
fi
# in verbose mode, just print the hyperfine results; otherwise,
# pull the useful information out of its json and summarize it
if [ "${VERBOSE}" = "1" ]; then
indent < "${OUTPUT_FILE}"
else
jq -r '[ .results[0].mean, .results[0].stddev, .results[1].mean, .results[1].stddev ] | @tsv' < "${JSON_FILE}" | while IFS=$'\t' read -r one_mean one_stddev two_mean two_stddev; do
one_mean=$(humanize_secs "${one_mean}")
one_stddev=$(humanize_secs "${one_stddev}")
if [ "${two_mean}" != "" ]; then
two_mean=$(humanize_secs "${two_mean}")
two_stddev=$(humanize_secs "${two_stddev}")
echo "${one_mean} ± ${one_stddev} vs ${two_mean} ± ${two_stddev}"
else
echo "${one_mean} ± ${one_stddev}"
fi
done
fi
# add our metadata to the hyperfine json result
jq ". |= { \"name\": \"${TEST_NAME}\" } + ." < "${JSON_FILE}" > "${JSON_FILE}.new" && mv "${JSON_FILE}.new" "${JSON_FILE}"
done
TIME_END=$(time_in_ms)
if [ "$ANY_FOUND" != "1" ]; then
echo ""
echo "error: no benchmark suite \"${SUITE}\"."
echo ""
exit 1
fi
escape() {
echo "${1//\\/\\\\}"
}
# combine all the individual benchmark results into a single json file
if [ "${JSON_RESULT}" != "" ]; then
if [ "${VERBOSE}" = "1" ]; then
echo ""
echo "# Writing JSON results: ${JSON_RESULT}"
fi
SYSTEM_JSON="{ \"os\": \"${SYSTEM_OS}\", \"kernel\": \"${SYSTEM_KERNEL}\" }"
TIME_JSON="{ \"start\": ${TIME_START}, \"end\": ${TIME_END} }"
TEST_CLI_JSON="{ \"name\": \"${TEST_CLI_NAME}\", \"path\": \"$(escape "${TEST_CLI_PATH}")\", \"version\": \"${TEST_CLI_VERSION}\" }"
BASELINE_CLI_JSON="{ \"name\": \"${BASELINE_CLI_NAME}\", \"path\": \"$(escape "${BASELINE_CLI_PATH}")\", \"version\": \"${BASELINE_CLI_VERSION}\" }"
if [ "${BASELINE_CLI}" != "" ]; then
EXECUTOR_JSON="{ \"baseline\": ${BASELINE_CLI_JSON}, \"cli\": ${TEST_CLI_JSON} }"
else
EXECUTOR_JSON="{ \"cli\": ${TEST_CLI_JSON} }"
fi
# add our metadata to all the test results
jq -n "{ \"system\": ${SYSTEM_JSON}, \"time\": ${TIME_JSON}, \"executor\": ${EXECUTOR_JSON}, \"tests\": [inputs] }" "${OUTPUT_DIR}"/*.json > "${JSON_RESULT}"
fi
# combine all the data into a zip if requested
if [ "${ZIP_RESULT}" != "" ]; then
if [ "${VERBOSE}" = "1" ]; then
if [ "${JSON_RESULT}" = "" ]; then echo ""; fi
echo "# Writing ZIP results: ${ZIP_RESULT}"
fi
zip -jr "${ZIP_RESULT}" "${OUTPUT_DIR}" >/dev/null
fi
if [ "$CLEANUP_DIR" = "1" ]; then
rm -f "${OUTPUT_DIR}"/*.out
rm -f "${OUTPUT_DIR}"/*.err
rm -f "${OUTPUT_DIR}"/*.json
rmdir "${OUTPUT_DIR}"
fi
if [ "$ANY_FAILED" = "1" ]; then
exit 1
fi

View File

@@ -0,0 +1,363 @@
# variables that benchmark tests can set
#
set -eo pipefail
#
# command-line parsing
#
usage() { echo "usage: $(basename "$0") [--cli <path>] [--baseline-cli <path>] [--output-style <style>] [--json <path>]"; }
NEXT=
BASELINE_CLI=
TEST_CLI="git"
JSON=
SHOW_OUTPUT=
if [ "$CI" != "" ]; then
OUTPUT_STYLE="color"
else
OUTPUT_STYLE="auto"
fi
#
# parse the arguments to the outer script that's including us; these are arguments that
# the `benchmark.sh` passes (or that a user could specify when running an individual test)
#
for a in "$@"; do
if [ "${NEXT}" = "cli" ]; then
TEST_CLI="${a}"
NEXT=
elif [ "${NEXT}" = "baseline-cli" ]; then
BASELINE_CLI="${a}"
NEXT=
elif [ "${NEXT}" = "output-style" ]; then
OUTPUT_STYLE="${a}"
NEXT=
elif [ "${NEXT}" = "json" ]; then
JSON="${a}"
NEXT=
elif [ "${a}" = "-c" ] || [ "${a}" = "--cli" ]; then
NEXT="cli"
elif [[ "${a}" == "-c"* ]]; then
TEST_CLI="${a/-c/}"
elif [ "${a}" = "-b" ] || [ "${a}" = "--baseline-cli" ]; then
NEXT="baseline-cli"
elif [[ "${a}" == "-b"* ]]; then
BASELINE_CLI="${a/-b/}"
elif [ "${a}" == "--output-style" ]; then
NEXT="output-style"
elif [ "${a}" = "-j" ] || [ "${a}" = "--json" ]; then
NEXT="json"
elif [[ "${a}" == "-j"* ]]; then
JSON="${a}"
elif [ "${a}" = "--show-output" ]; then
SHOW_OUTPUT=1
OUTPUT_STYLE=
else
echo "$(basename "$0"): unknown option: ${a}" 1>&2
usage 1>&2
exit 1
fi
done
if [ "${NEXT}" != "" ]; then
echo "$(basename "$0"): option requires a value: --${NEXT}" 1>&2
usage 1>&2
exit 1
fi
fullpath() {
FULLPATH="${1}"
if [[ "$(uname -s)" == "MINGW"* ]]; then FULLPATH="$(cygpath -u "${1}")"; fi
if [[ "${FULLPATH}" != *"/"* ]]; then
FULLPATH="$(which "${FULLPATH}")"
if [ "$?" != "0" ]; then exit 1; fi
else
FULLPATH="$(cd "$(dirname "${FULLPATH}")" && pwd)/$(basename "${FULLPATH}")"
fi
if [[ "$(uname -s)" == "MINGW"* ]]; then FULLPATH="$(cygpath -w "${FULLPATH}")"; fi
echo "${FULLPATH}"
}
resources_dir() {
cd "$(dirname "$0")/../resources" && pwd
}
temp_dir() {
if [ "$(uname -s)" == "Darwin" ]; then
mktemp -dt libgit2_bench
else
mktemp -dt libgit2_bench.XXXXXXX
fi
}
create_preparescript() {
# add some functions for users to use in preparation
cat >> "${SANDBOX_DIR}/prepare.sh" << EOF
set -e
SANDBOX_DIR="${SANDBOX_DIR}"
RESOURCES_DIR="$(resources_dir)"
create_text_file() {
FILENAME="\${1}"
SIZE="\${2}"
if [ "\${FILENAME}" = "" ]; then
echo "usage: create_text_file <name> [size]" 1>&2
exit 1
fi
if [ "\${SIZE}" = "" ]; then
SIZE="1024"
fi
if [[ "\$(uname -s)" == "MINGW"* ]]; then
EOL="\r\n"
EOL_LEN="2"
CONTENTS="This is a reproducible text file. (With Unix line endings.)\n"
CONTENTS_LEN="60"
else
EOL="\n"
EOL_LEN="1"
CONTENTS="This is a reproducible text file. (With DOS line endings.)\r\n"
CONTENTS_LEN="60"
fi
rm -f "\${FILENAME:?}"
touch "\${FILENAME}"
if [ "\${SIZE}" -ge "\$((\${CONTENTS_LEN} + \${EOL_LEN}))" ]; then
SIZE="\$((\${SIZE} - \${CONTENTS_LEN}))"
COUNT="\$(((\${SIZE} - \${EOL_LEN}) / \${CONTENTS_LEN}))"
if [ "\${SIZE}" -gt "\${EOL_LEN}" ]; then
dd if="\${FILENAME}" of="\${FILENAME}" bs="\${CONTENTS_LEN}" seek=1 count="\${COUNT}" 2>/dev/null
fi
SIZE="\$((\${SIZE} - (\${COUNT} * \${CONTENTS_LEN})))"
fi
while [ "\${SIZE}" -gt "\${EOL_LEN}" ]; do
echo -ne "." >> "\${FILENAME}"
SIZE="\$((\${SIZE} - 1))"
done
if [ "\${SIZE}" = "\${EOL_LEN}" ]; then
echo -ne "\${EOL}" >> "\${FILENAME}"
SIZE="\$((\${SIZE} - \${EOL_LEN}))"
else
while [ "\${SIZE}" -gt "0" ]; do
echo -ne "." >> "\${FILENAME}"
SIZE="\$((\${SIZE} - 1))"
done
fi
}
create_random_file() {
FILENAME="\${1}"
SIZE="\${2}"
if [ "\${FILENAME}" = "" ]; then
echo "usage: create_random_file <name> [size]" 1>&2
exit 1
fi
if [ "\${SIZE}" = "" ]; then
SIZE="1024"
fi
dd if="/dev/urandom" of="\${FILENAME}" bs="\${SIZE}" count=1 2>/dev/null
}
flush_disk_cache() {
if [ "\$(uname -s)" = "Darwin" ]; then
sync && sudo purge
elif [ "\$(uname -s)" = "Linux" ]; then
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null
elif [[ "\$(uname -s)" == "MINGW"* ]]; then
PurgeStandbyList
fi
}
sandbox() {
RESOURCE="\${1}"
if [ "\${RESOURCE}" = "" ]; then
echo "usage: sandbox <path>" 1>&2
exit 1
fi
if [ ! -d "\${RESOURCES_DIR}/\${RESOURCE}" ]; then
echo "sandbox: the resource \"\${RESOURCE}\" does not exist"
exit 1
fi
rm -rf "\${SANDBOX_DIR:?}/\${RESOURCE}"
cp -R "\${RESOURCES_DIR}/\${RESOURCE}" "\${SANDBOX_DIR}/"
}
sandbox_repo() {
RESOURCE="\${1}"
sandbox "\${RESOURCE}"
if [ -d "\${SANDBOX_DIR}/\${RESOURCE}/.gitted" ]; then
mv "\${SANDBOX_DIR}/\${RESOURCE}/.gitted" "\${SANDBOX_DIR}/\${RESOURCE}/.git";
fi
if [ -f "\${SANDBOX_DIR}/\${RESOURCE}/gitattributes" ]; then
mv "\${SANDBOX_DIR}/\${RESOURCE}/gitattributes" "\${SANDBOX_DIR}/\${RESOURCE}/.gitattributes";
fi
if [ -f "\${SANDBOX_DIR}/\${RESOURCE}/gitignore" ]; then
mv "\${SANDBOX_DIR}/\${RESOURCE}/gitignore" "\${SANDBOX_DIR}/\${RESOURCE}/.gitignore";
fi
}
cd "\${SANDBOX_DIR}"
EOF
if [ "${PREPARE}" != "" ]; then
echo "" >> "${SANDBOX_DIR}/prepare.sh"
echo "${PREPARE}" >> "${SANDBOX_DIR}/prepare.sh"
fi
echo "${SANDBOX_DIR}/prepare.sh"
}
create_runscript() {
SCRIPT_NAME="${1}"; shift
CLI_PATH="${1}"; shift
if [[ "${CHDIR}" = "/"* ]]; then
START_DIR="${CHDIR}"
elif [ "${CHDIR}" != "" ]; then
START_DIR="${SANDBOX_DIR}/${CHDIR}"
else
START_DIR="${SANDBOX_DIR}"
fi
# our run script starts by chdir'ing to the sandbox or repository directory
echo -n "cd \"${START_DIR}\" && \"${CLI_PATH}\"" >> "${SANDBOX_DIR}/${SCRIPT_NAME}.sh"
for a in "$@"; do
echo -n " \"${a}\"" >> "${SANDBOX_DIR}/${SCRIPT_NAME}.sh"
done
echo "${SANDBOX_DIR}/${SCRIPT_NAME}.sh"
}
gitbench_usage() { echo "usage: gitbench command..."; }
#
# this is the function that the outer script calls to actually do the sandboxing and
# invocation of hyperfine.
#
gitbench() {
NEXT=
# this test should run the given command in preparation of the tests
# this preparation script will be run _after_ repository creation and
# _before_ flushing the disk cache
PREPARE=
# this test should run within the given directory; this is a
# relative path beneath the sandbox directory.
CHDIR=
# this test should run `n` warmups
WARMUP=0
if [ "$*" = "" ]; then
gitbench_usage 1>&2
exit 1
fi
for a in "$@"; do
if [ "${NEXT}" = "warmup" ]; then
WARMUP="${a}"
NEXT=
elif [ "${NEXT}" = "prepare" ]; then
PREPARE="${a}"
NEXT=
elif [ "${NEXT}" = "chdir" ]; then
CHDIR="${a}"
NEXT=
elif [ "${a}" = "--warmup" ]; then
NEXT="warmup"
elif [ "${a}" = "--prepare" ]; then
NEXT="prepare"
elif [ "${a}" = "--chdir" ]; then
NEXT="chdir"
elif [[ "${a}" == "--"* ]]; then
echo "unknown argument: \"${a}\"" 1>&2
gitbench_usage 1>&2
exit 1
else
break
fi
shift
done
if [ "${NEXT}" != "" ]; then
echo "$(basename "$0"): option requires a value: --${NEXT}" 1>&2
gitbench_usage 1>&2
exit 1
fi
# sanity check
for a in "${SANDBOX[@]}"; do
if [ ! -d "$(resources_dir)/${a}" ]; then
echo "$0: no resource '${a}' found" 1>&2
exit 1
fi
done
if [ "$REPOSITORY" != "" ]; then
if [ ! -d "$(resources_dir)/${REPOSITORY}" ]; then
echo "$0: no repository resource '${REPOSITORY}' found" 1>&2
exit 1
fi
fi
# set up our sandboxing
SANDBOX_DIR="$(temp_dir)"
if [ "${BASELINE_CLI}" != "" ]; then
BASELINE_CLI_PATH=$(fullpath "${BASELINE_CLI}")
BASELINE_RUN_SCRIPT=$(create_runscript "baseline" "${BASELINE_CLI_PATH}" "$@")
fi
TEST_CLI_PATH=$(fullpath "${TEST_CLI}")
TEST_RUN_SCRIPT=$(create_runscript "test" "${TEST_CLI_PATH}" "$@")
PREPARE_SCRIPT="$(create_preparescript)"
ARGUMENTS=("--prepare" "bash ${PREPARE_SCRIPT}" "--warmup" "${WARMUP}")
if [ "${OUTPUT_STYLE}" != "" ]; then
ARGUMENTS+=("--style" "${OUTPUT_STYLE}")
fi
if [ "${SHOW_OUTPUT}" != "" ]; then
ARGUMENTS+=("--show-output")
fi
if [ "$JSON" != "" ]; then
ARGUMENTS+=("--export-json" "${JSON}")
fi
if [ "${BASELINE_CLI}" != "" ]; then
ARGUMENTS+=("-n" "${BASELINE_CLI} $*" "bash ${BASELINE_RUN_SCRIPT}")
fi
ARGUMENTS+=("-n" "${TEST_CLI} $*" "bash ${TEST_RUN_SCRIPT}")
hyperfine "${ARGUMENTS[@]}"
rm -rf "${SANDBOX_DIR:?}"
}

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "create_text_file text_100kb 102400 &&
flush_disk_cache" \
hash-object "text_100kb"

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "create_text_file text_10mb 10485760 &&
flush_disk_cache" \
hash-object "text_10mb"

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "create_text_file text_1kb 1024 &&
flush_disk_cache" \
hash-object "text_1kb"

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "create_text_file text_100kb 102400" \
--warmup 5 \
hash-object "text_100kb"

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "create_text_file text_10mb 10485760" \
--warmup 5 \
hash-object "text_10mb"

View File

@@ -0,0 +1,7 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "create_text_file text_1kb 1024" \
--warmup 5 \
hash-object "text_1kb"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "sandbox_repo empty_standard_repo &&
create_text_file text_100kb 102400 &&
flush_disk_cache" \
--chdir "empty_standard_repo" \
hash-object -w "../text_100kb"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "sandbox_repo empty_standard_repo &&
create_text_file text_10mb 10485760 &&
flush_disk_cache" \
--chdir "empty_standard_repo" \
hash-object "../text_10mb"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "sandbox_repo empty_standard_repo &&
create_text_file text_1kb 1024 &&
flush_disk_cache" \
--chdir "empty_standard_repo" \
hash-object "../text_1kb"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "sandbox_repo empty_standard_repo &&
create_text_file text_100kb 102400" \
--warmup 5 \
--chdir "empty_standard_repo" \
hash-object "../text_100kb"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "sandbox_repo empty_standard_repo &&
create_text_file text_10mb 10485760" \
--warmup 5 \
--chdir "empty_standard_repo" \
hash-object "../text_10mb"

View File

@@ -0,0 +1,9 @@
#!/bin/bash -e
. "$(dirname "$0")/benchmark_helpers.sh"
gitbench --prepare "sandbox_repo empty_standard_repo &&
create_text_file text_1kb 1024" \
--warmup 5 \
--chdir "empty_standard_repo" \
hash-object "../text_1kb"

View File

@@ -1,166 +0,0 @@
#include "blame_helpers.h"
static git_repository *g_repo;
static git_blame *g_fileblame, *g_bufferblame;
void test_blame_buffer__initialize(void)
{
cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
cl_git_pass(git_blame_file(&g_fileblame, g_repo, "b.txt", NULL));
g_bufferblame = NULL;
}
void test_blame_buffer__cleanup(void)
{
git_blame_free(g_fileblame);
git_blame_free(g_bufferblame);
git_repository_free(g_repo);
}
void test_blame_buffer__added_line(void)
{
const git_blame_hunk *hunk;
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
abcdefg\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "000000", "b.txt");
hunk = git_blame_get_hunk_byline(g_bufferblame, 16);
cl_assert(hunk);
cl_assert_equal_s("Ben Straub", hunk->final_signature->name);
}
void test_blame_buffer__deleted_line(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 3, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 9, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 10, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__add_splits_hunk(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
abc\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 2, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 8, 1, 0, "00000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 9, 3, 0, "63d671eb", "b.txt");
}
void test_blame_buffer__delete_crosses_hunk_boundary(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 2, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__replace_line(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
abc\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 1, 0, "00000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 8, 3, 0, "63d671eb", "b.txt");
}
void test_blame_buffer__add_lines_at_end(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
\n\
abc\n\
def\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 4, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 5, 1, 1, "b99f7ac0", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 5, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 11, 5, 0, "aa06ecca", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 16, 2, 0, "00000000", "b.txt");
}

View File

@@ -1,51 +0,0 @@
#include "clar_libgit2.h"
#include "buffer.h"
static const char *test_string = "Have you seen that? Have you seeeen that??";
void test_buf_basic__resize(void)
{
git_buf buf1 = GIT_BUF_INIT;
git_buf_puts(&buf1, test_string);
cl_assert(git_buf_oom(&buf1) == 0);
cl_assert_equal_s(git_buf_cstr(&buf1), test_string);
git_buf_puts(&buf1, test_string);
cl_assert(strlen(git_buf_cstr(&buf1)) == strlen(test_string) * 2);
git_buf_dispose(&buf1);
}
void test_buf_basic__resize_incremental(void)
{
git_buf buf1 = GIT_BUF_INIT;
/* Presently, asking for 6 bytes will round up to 8. */
cl_git_pass(git_buf_puts(&buf1, "Hello"));
cl_assert_equal_i(5, buf1.size);
cl_assert_equal_i(8, buf1.asize);
/* Ensure an additional byte does not realloc. */
cl_git_pass(git_buf_grow_by(&buf1, 1));
cl_assert_equal_i(5, buf1.size);
cl_assert_equal_i(8, buf1.asize);
/* But requesting many does. */
cl_git_pass(git_buf_grow_by(&buf1, 16));
cl_assert_equal_i(5, buf1.size);
cl_assert(buf1.asize > 8);
git_buf_dispose(&buf1);
}
void test_buf_basic__printf(void)
{
git_buf buf2 = GIT_BUF_INIT;
git_buf_printf(&buf2, "%s %s %d ", "shoop", "da", 23);
cl_assert(git_buf_oom(&buf2) == 0);
cl_assert_equal_s(git_buf_cstr(&buf2), "shoop da 23 ");
git_buf_printf(&buf2, "%s %d", "woop", 42);
cl_assert(git_buf_oom(&buf2) == 0);
cl_assert_equal_s(git_buf_cstr(&buf2), "shoop da 23 woop 42");
git_buf_dispose(&buf2);
}

View File

@@ -1,59 +0,0 @@
#include "clar_libgit2.h"
#include "buffer.h"
/* Override default allocators with ones that will fail predictably. */
static git_allocator std_alloc;
static git_allocator oom_alloc;
static void *oom_malloc(size_t n, const char *file, int line)
{
/* Reject any allocation of more than 100 bytes */
return (n > 100) ? NULL : std_alloc.gmalloc(n, file, line);
}
static void *oom_realloc(void *p, size_t n, const char *file, int line)
{
/* Reject any allocation of more than 100 bytes */
return (n > 100) ? NULL : std_alloc.grealloc(p, n, file, line);
}
void test_buf_oom__initialize(void)
{
git_stdalloc_init_allocator(&std_alloc);
git_stdalloc_init_allocator(&oom_alloc);
oom_alloc.gmalloc = oom_malloc;
oom_alloc.grealloc = oom_realloc;
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, &oom_alloc));
}
void test_buf_oom__cleanup(void)
{
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_ALLOCATOR, NULL));
}
void test_buf_oom__grow(void)
{
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git_buf_grow(&buf, 42));
cl_assert(!git_buf_oom(&buf));
cl_assert(git_buf_grow(&buf, 101) == -1);
cl_assert(git_buf_oom(&buf));
git_buf_dispose(&buf);
}
void test_buf_oom__grow_by(void)
{
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git_buf_grow_by(&buf, 42));
cl_assert(!git_buf_oom(&buf));
cl_assert(git_buf_grow_by(&buf, 101) == -1);
cl_assert(git_buf_oom(&buf));
}

View File

@@ -1,93 +0,0 @@
#include "clar_libgit2.h"
#include "buffer.h"
static git_buf _buf;
void test_buf_splice__initialize(void) {
git_buf_init(&_buf, 16);
}
void test_buf_splice__cleanup(void) {
git_buf_dispose(&_buf);
}
void test_buf_splice__preprend(void)
{
git_buf_sets(&_buf, "world!");
cl_git_pass(git_buf_splice(&_buf, 0, 0, "Hello Dolly", strlen("Hello ")));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__append(void)
{
git_buf_sets(&_buf, "Hello");
cl_git_pass(git_buf_splice(&_buf, git_buf_len(&_buf), 0, " world!", strlen(" world!")));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__insert_at(void)
{
git_buf_sets(&_buf, "Hell world!");
cl_git_pass(git_buf_splice(&_buf, strlen("Hell"), 0, "o", strlen("o")));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__remove_at(void)
{
git_buf_sets(&_buf, "Hello world of warcraft!");
cl_git_pass(git_buf_splice(&_buf, strlen("Hello world"), strlen(" of warcraft"), "", 0));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__replace(void)
{
git_buf_sets(&_buf, "Hell0 w0rld!");
cl_git_pass(git_buf_splice(&_buf, strlen("Hell"), strlen("0 w0"), "o wo", strlen("o wo")));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__replace_with_longer(void)
{
git_buf_sets(&_buf, "Hello you!");
cl_git_pass(git_buf_splice(&_buf, strlen("Hello "), strlen("you"), "world", strlen("world")));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__replace_with_shorter(void)
{
git_buf_sets(&_buf, "Brave new world!");
cl_git_pass(git_buf_splice(&_buf, 0, strlen("Brave new"), "Hello", strlen("Hello")));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__truncate(void)
{
git_buf_sets(&_buf, "Hello world!!");
cl_git_pass(git_buf_splice(&_buf, strlen("Hello world!"), strlen("!"), "", 0));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}
void test_buf_splice__dont_do_anything(void)
{
git_buf_sets(&_buf, "Hello world!");
cl_git_pass(git_buf_splice(&_buf, 3, 0, "Hello", 0));
cl_assert_equal_s("Hello world!", git_buf_cstr(&_buf));
}

View File

@@ -12,6 +12,7 @@
#include <math.h>
#include <stdarg.h>
#include <wchar.h>
#include <time.h>
/* required for sandboxing */
#include <sys/types.h>
@@ -40,9 +41,6 @@
# ifndef strdup
# define strdup(str) _strdup(str)
# endif
# ifndef strcasecmp
# define strcasecmp(a,b) _stricmp(a,b)
# endif
# ifndef __MINGW32__
# pragma comment(lib, "shell32")
@@ -86,16 +84,21 @@
typedef struct stat STAT_T;
#endif
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#include "clar.h"
static void fs_rm(const char *_source);
static void fs_copy(const char *_source, const char *dest);
#ifdef CLAR_FIXTURE_PATH
static const char *
fixture_path(const char *base, const char *fixture_name);
#endif
struct clar_error {
const char *file;
const char *function;
size_t line_number;
const char *error_msg;
char *description;
@@ -116,6 +119,8 @@ struct clar_report {
const char *suite;
enum cl_test_status status;
time_t start;
double elapsed;
struct clar_error *errors;
struct clar_error *last_error;
@@ -140,9 +145,11 @@ static struct {
int tests_ran;
int suites_ran;
enum cl_output_format output_format;
int report_errors_only;
int exit_on_error;
int report_suite_names;
int verbosity;
int write_summary;
char *summary_filename;
@@ -183,7 +190,7 @@ struct clar_suite {
static void clar_print_init(int test_count, int suite_count, const char *suite_names);
static void clar_print_shutdown(int test_count, int suite_count, int error_count);
static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error);
static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status failed);
static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed);
static void clar_print_onsuite(const char *suite_name, int suite_index);
static void clar_print_onabort(const char *msg, ...);
@@ -242,16 +249,53 @@ clar_report_all(void)
}
}
#ifdef WIN32
# define clar_time DWORD
static void clar_time_now(clar_time *out)
{
*out = GetTickCount();
}
static double clar_time_diff(clar_time *start, clar_time *end)
{
return ((double)*end - (double)*start) / 1000;
}
#else
# include <sys/time.h>
# define clar_time struct timeval
static void clar_time_now(clar_time *out)
{
struct timezone tz;
gettimeofday(out, &tz);
}
static double clar_time_diff(clar_time *start, clar_time *end)
{
return ((double)end->tv_sec + (double)end->tv_usec / 1.0E6) -
((double)start->tv_sec + (double)start->tv_usec / 1.0E6);
}
#endif
static void
clar_run_test(
const struct clar_suite *suite,
const struct clar_func *test,
const struct clar_func *initialize,
const struct clar_func *cleanup)
{
clar_time start, end;
_clar.trampoline_enabled = 1;
CL_TRACE(CL_TRACE__TEST__BEGIN);
_clar.last_report->start = time(NULL);
clar_time_now(&start);
if (setjmp(_clar.trampoline) == 0) {
if (initialize->ptr != NULL)
initialize->ptr();
@@ -261,11 +305,15 @@ clar_run_test(
CL_TRACE(CL_TRACE__TEST__RUN_END);
}
clar_time_now(&end);
_clar.trampoline_enabled = 0;
if (_clar.last_report->status == CL_TEST_NOTRUN)
_clar.last_report->status = CL_TEST_OK;
_clar.last_report->elapsed = clar_time_diff(&start, &end);
if (_clar.local_cleanup != NULL)
_clar.local_cleanup(_clar.local_cleanup_payload);
@@ -283,7 +331,7 @@ clar_run_test(
if (_clar.report_errors_only) {
clar_report_errors(_clar.last_report);
} else {
clar_print_ontest(test->name, _clar.tests_ran, _clar.last_report->status);
clar_print_ontest(suite->name, test->name, _clar.tests_ran, _clar.last_report->status);
}
}
@@ -293,6 +341,7 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
const struct clar_func *test = suite->tests;
size_t i, matchlen;
struct clar_report *report;
int exact = 0;
if (!suite->enabled)
return;
@@ -317,6 +366,11 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
while (*filter == ':')
++filter;
matchlen = strlen(filter);
if (matchlen && filter[matchlen - 1] == '$') {
exact = 1;
matchlen--;
}
}
}
@@ -324,6 +378,9 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
if (filter && strncmp(test[i].name, filter, matchlen))
continue;
if (exact && strlen(test[i].name) != matchlen)
continue;
_clar.active_test = test[i].name;
report = calloc(1, sizeof(struct clar_report));
@@ -340,7 +397,7 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
_clar.last_report = report;
clar_run_test(&test[i], &suite->initialize, &suite->cleanup);
clar_run_test(suite, &test[i], &suite->initialize, &suite->cleanup);
if (_clar.exit_on_error && _clar.total_errors)
return;
@@ -361,6 +418,7 @@ clar_usage(const char *arg)
printf(" -v Increase verbosity (show suite names)\n");
printf(" -q Only report tests that had an error\n");
printf(" -Q Quit as soon as a test fails\n");
printf(" -t Display results in tap format\n");
printf(" -l Print suite names\n");
printf(" -r[filename] Write summary file (to the optional filename)\n");
exit(-1);
@@ -376,7 +434,7 @@ clar_parse_args(int argc, char **argv)
char *argument = argv[i];
if (argument[0] != '-' || argument[1] == '\0'
|| strchr("sixvqQlr", argument[1]) == NULL) {
|| strchr("sixvqQtlr", argument[1]) == NULL) {
clar_usage(argv[0]);
}
}
@@ -414,7 +472,7 @@ clar_parse_args(int argc, char **argv)
++found;
if (!exact)
_clar.report_suite_names = 1;
_clar.verbosity = MAX(_clar.verbosity, 1);
switch (action) {
case 's': {
@@ -459,6 +517,10 @@ clar_parse_args(int argc, char **argv)
_clar.exit_on_error = 1;
break;
case 't':
_clar.output_format = CL_OUTPUT_TAP;
break;
case 'l': {
size_t j;
printf("Test suites (use -s<name> to run just one):\n");
@@ -469,13 +531,13 @@ clar_parse_args(int argc, char **argv)
}
case 'v':
_clar.report_suite_names = 1;
_clar.verbosity++;
break;
case 'r':
_clar.write_summary = 1;
free(_clar.summary_filename);
_clar.summary_filename = strdup(*(argument + 2) ? (argument + 2) : "summary.xml");
_clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL;
break;
default:
@@ -487,19 +549,25 @@ clar_parse_args(int argc, char **argv)
void
clar_test_init(int argc, char **argv)
{
const char *summary_env;
if (argc > 1)
clar_parse_args(argc, argv);
clar_print_init(
(int)_clar_callback_count,
(int)_clar_suite_count,
""
);
if ((_clar.summary_filename = getenv("CLAR_SUMMARY")) != NULL) {
if (!_clar.summary_filename &&
(summary_env = getenv("CLAR_SUMMARY")) != NULL) {
_clar.write_summary = 1;
_clar.summary_filename = strdup(_clar.summary_filename);
_clar.summary_filename = strdup(summary_env);
}
if (argc > 1)
clar_parse_args(argc, argv);
if (_clar.write_summary && !_clar.summary_filename)
_clar.summary_filename = strdup("summary.xml");
if (_clar.write_summary &&
!(_clar.summary = clar_summary_init(_clar.summary_filename))) {
@@ -596,6 +664,7 @@ void clar__skip(void)
void clar__fail(
const char *file,
const char *function,
size_t line,
const char *error_msg,
const char *description,
@@ -612,6 +681,7 @@ void clar__fail(
_clar.last_report->last_error = error;
error->file = file;
error->function = function;
error->line_number = line;
error->error_msg = error_msg;
@@ -628,6 +698,7 @@ void clar__fail(
void clar__assert(
int condition,
const char *file,
const char *function,
size_t line,
const char *error_msg,
const char *description,
@@ -636,11 +707,12 @@ void clar__assert(
if (condition)
return;
clar__fail(file, line, error_msg, description, should_abort);
clar__fail(file, function, line, error_msg, description, should_abort);
}
void clar__assert_equal(
const char *file,
const char *function,
size_t line,
const char *err,
int should_abort,
@@ -751,7 +823,7 @@ void clar__assert_equal(
va_end(args);
if (!is_equal)
clar__fail(file, line, err, buf, should_abort);
clar__fail(file, function, line, err, buf, should_abort);
}
void cl_set_cleanup(void (*cleanup)(void *), void *opaque)

View File

@@ -16,6 +16,11 @@ enum cl_test_status {
CL_TEST_NOTRUN,
};
enum cl_output_format {
CL_OUTPUT_CLAP,
CL_OUTPUT_TAP,
};
/** Setup clar environment */
void clar_test_init(int argc, char *argv[]);
int clar_test_run(void);
@@ -81,16 +86,16 @@ const char *cl_fixture_basename(const char *fixture_name);
/**
* Assertion macros with explicit error message
*/
#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 1)
#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 1)
#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 1)
#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 1)
#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 1)
#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 1)
/**
* Check macros with explicit error message
*/
#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 0)
#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 0)
#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 0)
#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 0)
#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 0)
#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 0)
/**
* Assertion macros with no error message
@@ -109,38 +114,39 @@ const char *cl_fixture_basename(const char *fixture_name);
/**
* Forced failure/warning
*/
#define cl_fail(desc) clar__fail(__FILE__, __LINE__, "Test failed.", desc, 1)
#define cl_warning(desc) clar__fail(__FILE__, __LINE__, "Warning during test execution:", desc, 0)
#define cl_fail(desc) clar__fail(__FILE__, __func__, __LINE__, "Test failed.", desc, 1)
#define cl_warning(desc) clar__fail(__FILE__, __func__, __LINE__, "Warning during test execution:", desc, 0)
#define cl_skip() clar__skip()
/**
* Typed assertion macros
*/
#define cl_assert_equal_s(s1,s2) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2))
#define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2))
#define cl_assert_equal_s(s1,s2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2))
#define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2))
#define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2))
#define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2))
#define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2))
#define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2))
#define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len))
#define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len))
#define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len))
#define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len))
#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(__FILE__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))
#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))
#define cl_assert_equal_i(i1,i2) clar__assert_equal(__FILE__,__LINE__,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(__FILE__,__LINE__,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(__FILE__,__LINE__,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
#define cl_assert_equal_i(i1,i2) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
#define cl_assert_equal_b(b1,b2) clar__assert_equal(__FILE__,__LINE__,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))
#define cl_assert_equal_b(b1,b2) clar__assert_equal(__FILE__,__func__,__LINE__,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))
#define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
#define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__func__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
void clar__skip(void);
void clar__fail(
const char *file,
const char *func,
size_t line,
const char *error,
const char *description,
@@ -149,6 +155,7 @@ void clar__fail(
void clar__assert(
int condition,
const char *file,
const char *func,
size_t line,
const char *error,
const char *description,
@@ -156,6 +163,7 @@ void clar__assert(
void clar__assert_equal(
const char *file,
const char *func,
size_t line,
const char *err,
int should_abort,

View File

@@ -1,3 +1,4 @@
#ifdef CLAR_FIXTURE_PATH
static const char *
fixture_path(const char *base, const char *fixture_name)
{
@@ -20,7 +21,6 @@ fixture_path(const char *base, const char *fixture_name)
return _path;
}
#ifdef CLAR_FIXTURE_PATH
const char *cl_fixture(const char *fixture_name)
{
return fixture_path(CLAR_FIXTURE_PATH, fixture_name);

522
tests/clar/clar/fs.h Normal file
View File

@@ -0,0 +1,522 @@
/*
* By default, use a read/write loop to copy files on POSIX systems.
* On Linux, use sendfile by default as it's slightly faster. On
* macOS, we avoid fcopyfile by default because it's slightly slower.
*/
#undef USE_FCOPYFILE
#define USE_SENDFILE 1
#ifdef _WIN32
#ifdef CLAR_WIN32_LONGPATHS
# define CLAR_MAX_PATH 4096
#else
# define CLAR_MAX_PATH MAX_PATH
#endif
#define RM_RETRY_COUNT 5
#define RM_RETRY_DELAY 10
#ifdef __MINGW32__
/* These security-enhanced functions are not available
* in MinGW, so just use the vanilla ones */
#define wcscpy_s(a, b, c) wcscpy((a), (c))
#define wcscat_s(a, b, c) wcscat((a), (c))
#endif /* __MINGW32__ */
static int
fs__dotordotdot(WCHAR *_tocheck)
{
return _tocheck[0] == '.' &&
(_tocheck[1] == '\0' ||
(_tocheck[1] == '.' && _tocheck[2] == '\0'));
}
static int
fs_rmdir_rmdir(WCHAR *_wpath)
{
unsigned retries = 1;
while (!RemoveDirectoryW(_wpath)) {
/* Only retry when we have retries remaining, and the
* error was ERROR_DIR_NOT_EMPTY. */
if (retries++ > RM_RETRY_COUNT ||
ERROR_DIR_NOT_EMPTY != GetLastError())
return -1;
/* Give whatever has a handle to a child item some time
* to release it before trying again */
Sleep(RM_RETRY_DELAY * retries * retries);
}
return 0;
}
static void translate_path(WCHAR *path, size_t path_size)
{
size_t path_len, i;
if (wcsncmp(path, L"\\\\?\\", 4) == 0)
return;
path_len = wcslen(path);
cl_assert(path_size > path_len + 4);
for (i = path_len; i > 0; i--) {
WCHAR c = path[i - 1];
if (c == L'/')
path[i + 3] = L'\\';
else
path[i + 3] = path[i - 1];
}
path[0] = L'\\';
path[1] = L'\\';
path[2] = L'?';
path[3] = L'\\';
path[path_len + 4] = L'\0';
}
static void
fs_rmdir_helper(WCHAR *_wsource)
{
WCHAR buffer[CLAR_MAX_PATH];
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
size_t buffer_prefix_len;
/* Set up the buffer and capture the length */
wcscpy_s(buffer, CLAR_MAX_PATH, _wsource);
translate_path(buffer, CLAR_MAX_PATH);
wcscat_s(buffer, CLAR_MAX_PATH, L"\\");
buffer_prefix_len = wcslen(buffer);
/* FindFirstFile needs a wildcard to match multiple items */
wcscat_s(buffer, CLAR_MAX_PATH, L"*");
find_handle = FindFirstFileW(buffer, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
do {
/* FindFirstFile/FindNextFile gives back . and ..
* entries at the beginning */
if (fs__dotordotdot(find_data.cFileName))
continue;
wcscpy_s(buffer + buffer_prefix_len, CLAR_MAX_PATH - buffer_prefix_len, find_data.cFileName);
if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
fs_rmdir_helper(buffer);
else {
/* If set, the +R bit must be cleared before deleting */
if (FILE_ATTRIBUTE_READONLY & find_data.dwFileAttributes)
cl_assert(SetFileAttributesW(buffer, find_data.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY));
cl_assert(DeleteFileW(buffer));
}
}
while (FindNextFileW(find_handle, &find_data));
/* Ensure that we successfully completed the enumeration */
cl_assert(ERROR_NO_MORE_FILES == GetLastError());
/* Close the find handle */
FindClose(find_handle);
/* Now that the directory is empty, remove it */
cl_assert(0 == fs_rmdir_rmdir(_wsource));
}
static int
fs_rm_wait(WCHAR *_wpath)
{
unsigned retries = 1;
DWORD last_error;
do {
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(_wpath))
last_error = GetLastError();
else
last_error = ERROR_SUCCESS;
/* Is the item gone? */
if (ERROR_FILE_NOT_FOUND == last_error ||
ERROR_PATH_NOT_FOUND == last_error)
return 0;
Sleep(RM_RETRY_DELAY * retries * retries);
}
while (retries++ <= RM_RETRY_COUNT);
return -1;
}
static void
fs_rm(const char *_source)
{
WCHAR wsource[CLAR_MAX_PATH];
DWORD attrs;
/* The input path is UTF-8. Convert it to wide characters
* for use with the Windows API */
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_source,
-1, /* Indicates NULL termination */
wsource,
CLAR_MAX_PATH));
translate_path(wsource, CLAR_MAX_PATH);
/* Does the item exist? If not, we have no work to do */
attrs = GetFileAttributesW(wsource);
if (INVALID_FILE_ATTRIBUTES == attrs)
return;
if (FILE_ATTRIBUTE_DIRECTORY & attrs)
fs_rmdir_helper(wsource);
else {
/* The item is a file. Strip the +R bit */
if (FILE_ATTRIBUTE_READONLY & attrs)
cl_assert(SetFileAttributesW(wsource, attrs & ~FILE_ATTRIBUTE_READONLY));
cl_assert(DeleteFileW(wsource));
}
/* Wait for the DeleteFile or RemoveDirectory call to complete */
cl_assert(0 == fs_rm_wait(wsource));
}
static void
fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest)
{
WCHAR buf_source[CLAR_MAX_PATH], buf_dest[CLAR_MAX_PATH];
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
size_t buf_source_prefix_len, buf_dest_prefix_len;
wcscpy_s(buf_source, CLAR_MAX_PATH, _wsource);
wcscat_s(buf_source, CLAR_MAX_PATH, L"\\");
translate_path(buf_source, CLAR_MAX_PATH);
buf_source_prefix_len = wcslen(buf_source);
wcscpy_s(buf_dest, CLAR_MAX_PATH, _wdest);
wcscat_s(buf_dest, CLAR_MAX_PATH, L"\\");
translate_path(buf_dest, CLAR_MAX_PATH);
buf_dest_prefix_len = wcslen(buf_dest);
/* Get an enumerator for the items in the source. */
wcscat_s(buf_source, CLAR_MAX_PATH, L"*");
find_handle = FindFirstFileW(buf_source, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
/* Create the target directory. */
cl_assert(CreateDirectoryW(_wdest, NULL));
do {
/* FindFirstFile/FindNextFile gives back . and ..
* entries at the beginning */
if (fs__dotordotdot(find_data.cFileName))
continue;
wcscpy_s(buf_source + buf_source_prefix_len, CLAR_MAX_PATH - buf_source_prefix_len, find_data.cFileName);
wcscpy_s(buf_dest + buf_dest_prefix_len, CLAR_MAX_PATH - buf_dest_prefix_len, find_data.cFileName);
if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
fs_copydir_helper(buf_source, buf_dest);
else
cl_assert(CopyFileW(buf_source, buf_dest, TRUE));
}
while (FindNextFileW(find_handle, &find_data));
/* Ensure that we successfully completed the enumeration */
cl_assert(ERROR_NO_MORE_FILES == GetLastError());
/* Close the find handle */
FindClose(find_handle);
}
static void
fs_copy(const char *_source, const char *_dest)
{
WCHAR wsource[CLAR_MAX_PATH], wdest[CLAR_MAX_PATH];
DWORD source_attrs, dest_attrs;
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
/* The input paths are UTF-8. Convert them to wide characters
* for use with the Windows API. */
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_source,
-1,
wsource,
CLAR_MAX_PATH));
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_dest,
-1,
wdest,
CLAR_MAX_PATH));
translate_path(wsource, CLAR_MAX_PATH);
translate_path(wdest, CLAR_MAX_PATH);
/* Check the source for existence */
source_attrs = GetFileAttributesW(wsource);
cl_assert(INVALID_FILE_ATTRIBUTES != source_attrs);
/* Check the target for existence */
dest_attrs = GetFileAttributesW(wdest);
if (INVALID_FILE_ATTRIBUTES != dest_attrs) {
/* Target exists; append last path part of source to target.
* Use FindFirstFile to parse the path */
find_handle = FindFirstFileW(wsource, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
wcscat_s(wdest, CLAR_MAX_PATH, L"\\");
wcscat_s(wdest, CLAR_MAX_PATH, find_data.cFileName);
FindClose(find_handle);
/* Check the new target for existence */
cl_assert(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(wdest));
}
if (FILE_ATTRIBUTE_DIRECTORY & source_attrs)
fs_copydir_helper(wsource, wdest);
else
cl_assert(CopyFileW(wsource, wdest, TRUE));
}
void
cl_fs_cleanup(void)
{
#ifdef CLAR_FIXTURE_PATH
fs_rm(fixture_path(_clar_path, "*"));
#endif
}
#else
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__linux__)
# include <sys/sendfile.h>
#endif
#if defined(__APPLE__)
# include <copyfile.h>
#endif
static void basename_r(const char **out, int *out_len, const char *in)
{
size_t in_len = strlen(in), start_pos;
for (in_len = strlen(in); in_len; in_len--) {
if (in[in_len - 1] != '/')
break;
}
for (start_pos = in_len; start_pos; start_pos--) {
if (in[start_pos - 1] == '/')
break;
}
cl_assert(in_len - start_pos < INT_MAX);
if (in_len - start_pos > 0) {
*out = &in[start_pos];
*out_len = (in_len - start_pos);
} else {
*out = "/";
*out_len = 1;
}
}
static char *joinpath(const char *dir, const char *base, int base_len)
{
char *out;
int len;
if (base_len == -1) {
size_t bl = strlen(base);
cl_assert(bl < INT_MAX);
base_len = (int)bl;
}
len = strlen(dir) + base_len + 2;
cl_assert(len > 0);
cl_assert(out = malloc(len));
cl_assert(snprintf(out, len, "%s/%.*s", dir, base_len, base) < len);
return out;
}
static void
fs_copydir_helper(const char *source, const char *dest, int dest_mode)
{
DIR *source_dir;
struct dirent *d;
mkdir(dest, dest_mode);
cl_assert_(source_dir = opendir(source), "Could not open source dir");
while ((d = (errno = 0, readdir(source_dir))) != NULL) {
char *child;
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
child = joinpath(source, d->d_name, -1);
fs_copy(child, dest);
free(child);
}
cl_assert_(errno == 0, "Failed to iterate source dir");
closedir(source_dir);
}
static void
fs_copyfile_helper(const char *source, size_t source_len, const char *dest, int dest_mode)
{
int in, out;
cl_must_pass((in = open(source, O_RDONLY)));
cl_must_pass((out = open(dest, O_WRONLY|O_CREAT|O_TRUNC, dest_mode)));
#if USE_FCOPYFILE && defined(__APPLE__)
((void)(source_len)); /* unused */
cl_must_pass(fcopyfile(in, out, 0, COPYFILE_DATA));
#elif USE_SENDFILE && defined(__linux__)
{
ssize_t ret = 0;
while (source_len && (ret = sendfile(out, in, NULL, source_len)) > 0) {
source_len -= (size_t)ret;
}
cl_assert(ret >= 0);
}
#else
{
char buf[131072];
ssize_t ret;
((void)(source_len)); /* unused */
while ((ret = read(in, buf, sizeof(buf))) > 0) {
size_t len = (size_t)ret;
while (len && (ret = write(out, buf, len)) > 0) {
cl_assert(ret <= (ssize_t)len);
len -= ret;
}
cl_assert(ret >= 0);
}
cl_assert(ret == 0);
}
#endif
close(in);
close(out);
}
static void
fs_copy(const char *source, const char *_dest)
{
char *dbuf = NULL;
const char *dest = NULL;
struct stat source_st, dest_st;
cl_must_pass_(lstat(source, &source_st), "Failed to stat copy source");
if (lstat(_dest, &dest_st) == 0) {
const char *base;
int base_len;
/* Target exists and is directory; append basename */
cl_assert(S_ISDIR(dest_st.st_mode));
basename_r(&base, &base_len, source);
cl_assert(base_len < INT_MAX);
dbuf = joinpath(_dest, base, base_len);
dest = dbuf;
} else if (errno != ENOENT) {
cl_fail("Cannot copy; cannot stat destination");
} else {
dest = _dest;
}
if (S_ISDIR(source_st.st_mode)) {
fs_copydir_helper(source, dest, source_st.st_mode);
} else {
fs_copyfile_helper(source, source_st.st_size, dest, source_st.st_mode);
}
free(dbuf);
}
static void
fs_rmdir_helper(const char *path)
{
DIR *dir;
struct dirent *d;
cl_assert_(dir = opendir(path), "Could not open dir");
while ((d = (errno = 0, readdir(dir))) != NULL) {
char *child;
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
continue;
child = joinpath(path, d->d_name, -1);
fs_rm(child);
free(child);
}
cl_assert_(errno == 0, "Failed to iterate source dir");
closedir(dir);
cl_must_pass_(rmdir(path), "Could not remove directory");
}
static void
fs_rm(const char *path)
{
struct stat st;
if (lstat(path, &st)) {
if (errno == ENOENT)
return;
cl_fail("Cannot copy; cannot stat destination");
}
if (S_ISDIR(st.st_mode)) {
fs_rmdir_helper(path);
} else {
cl_must_pass(unlink(path));
}
}
void
cl_fs_cleanup(void)
{
clar_unsandbox();
clar_sandbox();
}
#endif

211
tests/clar/clar/print.h Normal file
View File

@@ -0,0 +1,211 @@
/* clap: clar protocol, the traditional clar output format */
static void clar_print_clap_init(int test_count, int suite_count, const char *suite_names)
{
(void)test_count;
printf("Loaded %d suites: %s\n", (int)suite_count, suite_names);
printf("Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')\n");
}
static void clar_print_clap_shutdown(int test_count, int suite_count, int error_count)
{
(void)test_count;
(void)suite_count;
(void)error_count;
printf("\n\n");
clar_report_all();
}
static void clar_print_clap_error(int num, const struct clar_report *report, const struct clar_error *error)
{
printf(" %d) Failure:\n", num);
printf("%s::%s [%s:%"PRIuZ"]\n",
report->suite,
report->test,
error->file,
error->line_number);
printf(" %s\n", error->error_msg);
if (error->description != NULL)
printf(" %s\n", error->description);
printf("\n");
fflush(stdout);
}
static void clar_print_clap_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status)
{
(void)test_name;
(void)test_number;
if (_clar.verbosity > 1) {
printf("%s::%s: ", suite_name, test_name);
switch (status) {
case CL_TEST_OK: printf("ok\n"); break;
case CL_TEST_FAILURE: printf("fail\n"); break;
case CL_TEST_SKIP: printf("skipped"); break;
case CL_TEST_NOTRUN: printf("notrun"); break;
}
} else {
switch (status) {
case CL_TEST_OK: printf("."); break;
case CL_TEST_FAILURE: printf("F"); break;
case CL_TEST_SKIP: printf("S"); break;
case CL_TEST_NOTRUN: printf("N"); break;
}
fflush(stdout);
}
}
static void clar_print_clap_onsuite(const char *suite_name, int suite_index)
{
if (_clar.verbosity == 1)
printf("\n%s", suite_name);
(void)suite_index;
}
static void clar_print_clap_onabort(const char *fmt, va_list arg)
{
vfprintf(stderr, fmt, arg);
}
/* tap: test anywhere protocol format */
static void clar_print_tap_init(int test_count, int suite_count, const char *suite_names)
{
(void)test_count;
(void)suite_count;
(void)suite_names;
printf("TAP version 13\n");
}
static void clar_print_tap_shutdown(int test_count, int suite_count, int error_count)
{
(void)suite_count;
(void)error_count;
printf("1..%d\n", test_count);
}
static void clar_print_tap_error(int num, const struct clar_report *report, const struct clar_error *error)
{
(void)num;
(void)report;
(void)error;
}
static void print_escaped(const char *str)
{
char *c;
while ((c = strchr(str, '\'')) != NULL) {
printf("%.*s", (int)(c - str), str);
printf("''");
str = c + 1;
}
printf("%s", str);
}
static void clar_print_tap_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status)
{
const struct clar_error *error = _clar.last_report->errors;
(void)test_name;
(void)test_number;
switch(status) {
case CL_TEST_OK:
printf("ok %d - %s::%s\n", test_number, suite_name, test_name);
break;
case CL_TEST_FAILURE:
printf("not ok %d - %s::%s\n", test_number, suite_name, test_name);
printf(" ---\n");
printf(" reason: |\n");
printf(" %s\n", error->error_msg);
if (error->description)
printf(" %s\n", error->description);
printf(" at:\n");
printf(" file: '"); print_escaped(error->file); printf("'\n");
printf(" line: %" PRIuZ "\n", error->line_number);
printf(" function: '%s'\n", error->function);
printf(" ---\n");
break;
case CL_TEST_SKIP:
case CL_TEST_NOTRUN:
printf("ok %d - # SKIP %s::%s\n", test_number, suite_name, test_name);
break;
}
fflush(stdout);
}
static void clar_print_tap_onsuite(const char *suite_name, int suite_index)
{
printf("# start of suite %d: %s\n", suite_index, suite_name);
}
static void clar_print_tap_onabort(const char *fmt, va_list arg)
{
printf("Bail out! ");
vprintf(fmt, arg);
fflush(stdout);
}
/* indirection between protocol output selection */
#define PRINT(FN, ...) do { \
switch (_clar.output_format) { \
case CL_OUTPUT_CLAP: \
clar_print_clap_##FN (__VA_ARGS__); \
break; \
case CL_OUTPUT_TAP: \
clar_print_tap_##FN (__VA_ARGS__); \
break; \
default: \
abort(); \
} \
} while (0)
static void clar_print_init(int test_count, int suite_count, const char *suite_names)
{
PRINT(init, test_count, suite_count, suite_names);
}
static void clar_print_shutdown(int test_count, int suite_count, int error_count)
{
PRINT(shutdown, test_count, suite_count, error_count);
}
static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error)
{
PRINT(error, num, report, error);
}
static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status)
{
PRINT(ontest, suite_name, test_name, test_number, status);
}
static void clar_print_onsuite(const char *suite_name, int suite_index)
{
PRINT(onsuite, suite_name, suite_index);
}
static void clar_print_onabort(const char *msg, ...)
{
va_list argp;
va_start(argp, msg);
PRINT(onabort, msg, argp);
va_end(argp);
}

View File

@@ -2,7 +2,8 @@
#include <sys/syslimits.h>
#endif
static char _clar_path[4096];
#define CLAR_PATH_MAX 4096
static char _clar_path[CLAR_PATH_MAX];
static int
is_valid_tmp_path(const char *path)
@@ -35,22 +36,19 @@ find_tmp_path(char *buffer, size_t length)
continue;
if (is_valid_tmp_path(env)) {
#ifdef __APPLE__
if (length >= PATH_MAX && realpath(env, buffer) != NULL)
return 0;
#endif
strncpy(buffer, env, length);
if (strlen(env) + 1 > CLAR_PATH_MAX)
return -1;
strncpy(buffer, env, length - 1);
buffer[length - 1] = '\0';
return 0;
}
}
/* If the environment doesn't say anything, try to use /tmp */
if (is_valid_tmp_path("/tmp")) {
#ifdef __APPLE__
if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL)
return 0;
#endif
strncpy(buffer, "/tmp", length);
strncpy(buffer, "/tmp", length - 1);
buffer[length - 1] = '\0';
return 0;
}
@@ -65,13 +63,42 @@ find_tmp_path(char *buffer, size_t length)
/* This system doesn't like us, try to use the current directory */
if (is_valid_tmp_path(".")) {
strncpy(buffer, ".", length);
strncpy(buffer, ".", length - 1);
buffer[length - 1] = '\0';
return 0;
}
return -1;
}
static int canonicalize_tmp_path(char *buffer)
{
#ifdef _WIN32
char tmp[CLAR_PATH_MAX];
DWORD ret;
ret = GetFullPathName(buffer, CLAR_PATH_MAX, tmp, NULL);
if (ret == 0 || ret > CLAR_PATH_MAX)
return -1;
ret = GetLongPathName(tmp, buffer, CLAR_PATH_MAX);
if (ret == 0 || ret > CLAR_PATH_MAX)
return -1;
return 0;
#else
char tmp[CLAR_PATH_MAX];
if (realpath(buffer, tmp) == NULL)
return -1;
strcpy(buffer, tmp);
return 0;
#endif
}
static void clar_unsandbox(void)
{
if (_clar_path[0] == '\0')
@@ -92,7 +119,8 @@ static int build_sandbox_path(void)
size_t len;
if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0)
if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0 ||
canonicalize_tmp_path(_clar_path) < 0)
return -1;
len = strlen(_clar_path);

View File

@@ -2,7 +2,7 @@
#include <stdio.h>
#include <time.h>
int clar_summary_close_tag(
static int clar_summary_close_tag(
struct clar_summary *summary, const char *tag, int indent)
{
const char *indt;
@@ -14,14 +14,14 @@ int clar_summary_close_tag(
return fprintf(summary->fp, "%s</%s>\n", indt, tag);
}
int clar_summary_testsuites(struct clar_summary *summary)
static int clar_summary_testsuites(struct clar_summary *summary)
{
return fprintf(summary->fp, "<testsuites>\n");
}
int clar_summary_testsuite(struct clar_summary *summary,
int idn, const char *name, const char *pkg, time_t timestamp,
double elapsed, int test_count, int fail_count, int error_count)
static int clar_summary_testsuite(struct clar_summary *summary,
int idn, const char *name, time_t timestamp,
int test_count, int fail_count, int error_count)
{
struct tm *tm = localtime(&timestamp);
char iso_dt[20];
@@ -29,20 +29,18 @@ int clar_summary_testsuite(struct clar_summary *summary,
if (strftime(iso_dt, sizeof(iso_dt), "%Y-%m-%dT%H:%M:%S", tm) == 0)
return -1;
return fprintf(summary->fp, "\t<testsuite "
return fprintf(summary->fp, "\t<testsuite"
" id=\"%d\""
" name=\"%s\""
" package=\"%s\""
" hostname=\"localhost\""
" timestamp=\"%s\""
" time=\"%.2f\""
" tests=\"%d\""
" failures=\"%d\""
" errors=\"%d\">\n",
idn, name, pkg, iso_dt, elapsed, test_count, fail_count, error_count);
idn, name, iso_dt, test_count, fail_count, error_count);
}
int clar_summary_testcase(struct clar_summary *summary,
static int clar_summary_testcase(struct clar_summary *summary,
const char *name, const char *classname, double elapsed)
{
return fprintf(summary->fp,
@@ -50,7 +48,7 @@ int clar_summary_testcase(struct clar_summary *summary,
name, classname, elapsed);
}
int clar_summary_failure(struct clar_summary *summary,
static int clar_summary_failure(struct clar_summary *summary,
const char *type, const char *message, const char *desc)
{
return fprintf(summary->fp,
@@ -58,15 +56,23 @@ int clar_summary_failure(struct clar_summary *summary,
type, message, desc);
}
static int clar_summary_skipped(struct clar_summary *summary)
{
return fprintf(summary->fp, "\t\t\t<skipped />\n");
}
struct clar_summary *clar_summary_init(const char *filename)
{
struct clar_summary *summary;
FILE *fp;
if ((fp = fopen(filename, "w")) == NULL)
if ((fp = fopen(filename, "w")) == NULL) {
perror("fopen");
return NULL;
}
if ((summary = malloc(sizeof(struct clar_summary))) == NULL) {
perror("malloc");
fclose(fp);
return NULL;
}
@@ -90,14 +96,14 @@ int clar_summary_shutdown(struct clar_summary *summary)
struct clar_error *error = report->errors;
if (last_suite == NULL || strcmp(last_suite, report->suite) != 0) {
if (clar_summary_testsuite(summary, 0, report->suite, "",
time(NULL), 0, _clar.tests_ran, _clar.total_errors, 0) < 0)
if (clar_summary_testsuite(summary, 0, report->suite,
report->start, _clar.tests_ran, _clar.total_errors, 0) < 0)
goto on_error;
}
last_suite = report->suite;
clar_summary_testcase(summary, report->test, "what", 0);
clar_summary_testcase(summary, report->test, report->suite, report->elapsed);
while (error != NULL) {
if (clar_summary_failure(summary, "assert",
@@ -107,6 +113,9 @@ int clar_summary_shutdown(struct clar_summary *summary)
error = error->next;
}
if (report->status == CL_TEST_SKIP)
clar_summary_skipped(summary);
if (clar_summary_close_tag(summary, "testcase", 2) < 0)
goto on_error;

View File

@@ -1,10 +1,11 @@
#include "clar_libgit2.h"
#include "posix.h"
#include "path.h"
#include "fs_path.h"
#include "futils.h"
#include "git2/sys/repository.h"
void cl_git_report_failure(
int error, int expected, const char *file, int line, const char *fncall)
int error, int expected, const char *file, const char *func, int line, const char *fncall)
{
char msg[4096];
const git_error *last = git_error_last();
@@ -18,7 +19,7 @@ void cl_git_report_failure(
else
p_snprintf(msg, 4096, "no error, expected non-zero return");
clar__assert(0, file, line, fncall, msg, 1);
clar__assert(0, file, func, line, fncall, msg, 1);
}
void cl_git_mkfile(const char *filename, const char *content)
@@ -68,7 +69,7 @@ void cl_git_rmfile(const char *filename)
char *cl_getenv(const char *name)
{
git_buf out = GIT_BUF_INIT;
git_str out = GIT_STR_INIT;
int error = git__getenv(&out, name);
cl_assert(error >= 0 || error == GIT_ENOTFOUND);
@@ -83,7 +84,7 @@ char *cl_getenv(const char *name)
return dup;
}
return git_buf_detach(&out);
return git_str_detach(&out);
}
bool cl_is_env_set(const char *name)
@@ -102,10 +103,10 @@ int cl_setenv(const char *name, const char *value)
{
wchar_t *wide_name, *wide_value = NULL;
cl_assert(git__utf8_to_16_alloc(&wide_name, name) >= 0);
cl_assert(git_utf8_to_16_alloc(&wide_name, name) >= 0);
if (value) {
cl_assert(git__utf8_to_16_alloc(&wide_value, value) >= 0);
cl_assert(git_utf8_to_16_alloc(&wide_value, value) >= 0);
cl_assert(SetEnvironmentVariableW(wide_name, wide_value));
} else {
/* Windows XP returns 0 (failed) when passing NULL for lpValue when
@@ -275,14 +276,14 @@ const char* cl_git_fixture_url(const char *fixturename)
const char* cl_git_path_url(const char *path)
{
static char url[4096];
static char url[4096 + 1];
const char *in_buf;
git_buf path_buf = GIT_BUF_INIT;
git_buf url_buf = GIT_BUF_INIT;
git_str path_buf = GIT_STR_INIT;
git_str url_buf = GIT_STR_INIT;
cl_git_pass(git_path_prettify_dir(&path_buf, path, NULL));
cl_git_pass(git_buf_puts(&url_buf, "file://"));
cl_git_pass(git_fs_path_prettify_dir(&path_buf, path, NULL));
cl_git_pass(git_str_puts(&url_buf, "file://"));
#ifdef GIT_WIN32
/*
@@ -294,28 +295,29 @@ const char* cl_git_path_url(const char *path)
* *nix: file:///usr/home/...
* Windows: file:///C:/Users/...
*/
cl_git_pass(git_buf_putc(&url_buf, '/'));
cl_git_pass(git_str_putc(&url_buf, '/'));
#endif
in_buf = git_buf_cstr(&path_buf);
in_buf = git_str_cstr(&path_buf);
/*
* A very hacky Url encoding that only takes care of escaping the spaces
*/
while (*in_buf) {
if (*in_buf == ' ')
cl_git_pass(git_buf_puts(&url_buf, "%20"));
cl_git_pass(git_str_puts(&url_buf, "%20"));
else
cl_git_pass(git_buf_putc(&url_buf, *in_buf));
cl_git_pass(git_str_putc(&url_buf, *in_buf));
in_buf++;
}
cl_assert(url_buf.size < 4096);
cl_assert(url_buf.size < sizeof(url) - 1);
strncpy(url, git_buf_cstr(&url_buf), 4096);
git_buf_dispose(&url_buf);
git_buf_dispose(&path_buf);
strncpy(url, git_str_cstr(&url_buf), sizeof(url) - 1);
url[sizeof(url) - 1] = '\0';
git_str_dispose(&url_buf);
git_str_dispose(&path_buf);
return url;
}
@@ -323,27 +325,27 @@ const char *cl_git_sandbox_path(int is_dir, ...)
{
const char *path = NULL;
static char _temp[GIT_PATH_MAX];
git_buf buf = GIT_BUF_INIT;
git_str buf = GIT_STR_INIT;
va_list arg;
cl_git_pass(git_buf_sets(&buf, clar_sandbox_path()));
cl_git_pass(git_str_sets(&buf, clar_sandbox_path()));
va_start(arg, is_dir);
while ((path = va_arg(arg, const char *)) != NULL) {
cl_git_pass(git_buf_joinpath(&buf, buf.ptr, path));
cl_git_pass(git_str_joinpath(&buf, buf.ptr, path));
}
va_end(arg);
cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL));
cl_git_pass(git_fs_path_prettify(&buf, buf.ptr, NULL));
if (is_dir)
git_path_to_dir(&buf);
git_fs_path_to_dir(&buf);
/* make sure we won't truncate */
cl_assert(git_buf_len(&buf) < sizeof(_temp));
git_buf_copy_cstr(_temp, sizeof(_temp), &buf);
cl_assert(git_str_len(&buf) < sizeof(_temp));
git_str_copy_cstr(_temp, sizeof(_temp), &buf);
git_buf_dispose(&buf);
git_str_dispose(&buf);
return _temp;
}
@@ -353,13 +355,13 @@ typedef struct {
size_t filename_len;
} remove_data;
static int remove_placeholders_recurs(void *_data, git_buf *path)
static int remove_placeholders_recurs(void *_data, git_str *path)
{
remove_data *data = (remove_data *)_data;
size_t pathlen;
if (git_path_isdir(path->ptr) == true)
return git_path_direach(path, 0, remove_placeholders_recurs, data);
if (git_fs_path_isdir(path->ptr) == true)
return git_fs_path_direach(path, 0, remove_placeholders_recurs, data);
pathlen = path->size;
@@ -379,12 +381,12 @@ int cl_git_remove_placeholders(const char *directory_path, const char *filename)
{
int error;
remove_data data;
git_buf buffer = GIT_BUF_INIT;
git_str buffer = GIT_STR_INIT;
if (git_path_isdir(directory_path) == false)
if (git_fs_path_isdir(directory_path) == false)
return -1;
if (git_buf_sets(&buffer, directory_path) < 0)
if (git_str_sets(&buffer, directory_path) < 0)
return -1;
data.filename = filename;
@@ -392,7 +394,7 @@ int cl_git_remove_placeholders(const char *directory_path, const char *filename)
error = remove_placeholders_recurs(&data, &buffer);
git_buf_dispose(&buffer);
git_str_dispose(&buffer);
return error;
}
@@ -475,6 +477,25 @@ int cl_repo_get_bool(git_repository *repo, const char *cfg)
return val;
}
void cl_repo_set_int(git_repository *repo, const char *cfg, int value)
{
git_config *config;
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_int32(config, cfg, value));
git_config_free(config);
}
int cl_repo_get_int(git_repository *repo, const char *cfg)
{
int val = 0;
git_config *config;
cl_git_pass(git_repository_config(&config, repo));
if (git_config_get_int32(&val, config, cfg) < 0)
git_error_clear();
git_config_free(config);
return val;
}
void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value)
{
git_config *config;
@@ -507,6 +528,7 @@ void clar__assert_equal_file(
int ignore_cr,
const char *path,
const char *file,
const char *func,
int line)
{
char buf[4000];
@@ -519,7 +541,7 @@ void clar__assert_equal_file(
while ((bytes = p_read(fd, buf, sizeof(buf))) != 0) {
clar__assert(
bytes > 0, file, line, "error reading from file", path, 1);
bytes > 0, file, func, line, "error reading from file", path, 1);
if (ignore_cr)
bytes = strip_cr_from_buf(buf, bytes);
@@ -532,7 +554,7 @@ void clar__assert_equal_file(
buf, sizeof(buf), "file content mismatch at byte %"PRIdZ,
(ssize_t)(total_bytes + pos));
p_close(fd);
clar__fail(file, line, path, buf, 1);
clar__fail(file, func, line, path, buf, 1);
}
expected_data += bytes;
@@ -541,52 +563,110 @@ void clar__assert_equal_file(
p_close(fd);
clar__assert(!bytes, file, line, "error reading from file", path, 1);
clar__assert_equal(file, line, "mismatched file length", 1, "%"PRIuZ,
clar__assert(!bytes, file, func, line, "error reading from file", path, 1);
clar__assert_equal(file, func, line, "mismatched file length", 1, "%"PRIuZ,
(size_t)expected_bytes, (size_t)total_bytes);
}
static char *_cl_restore_home = NULL;
#define FAKE_HOMEDIR_NAME "cl_fake_home"
void cl_fake_home_cleanup(void *payload)
static git_buf _cl_restore_homedir = GIT_BUF_INIT;
void cl_fake_homedir_cleanup(void *payload)
{
char *restore = _cl_restore_home;
_cl_restore_home = NULL;
GIT_UNUSED(payload);
if (restore) {
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, restore));
git__free(restore);
if (_cl_restore_homedir.ptr) {
cl_git_pass(git_futils_rmdir_r(FAKE_HOMEDIR_NAME, NULL, GIT_RMDIR_REMOVE_FILES));
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_HOMEDIR, _cl_restore_homedir.ptr));
git_buf_dispose(&_cl_restore_homedir);
}
}
void cl_fake_home(void)
void cl_fake_homedir(git_str *out)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
cl_git_pass(git_libgit2_opts(
GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &path));
GIT_OPT_GET_HOMEDIR, &_cl_restore_homedir));
_cl_restore_home = git_buf_detach(&path);
cl_set_cleanup(cl_fake_home_cleanup, NULL);
cl_set_cleanup(cl_fake_homedir_cleanup, NULL);
/* TOC/TOU but merely attempts to prevent accidental cleanup. */
cl_assert(!git_fs_path_exists(FAKE_HOMEDIR_NAME));
cl_must_pass(p_mkdir(FAKE_HOMEDIR_NAME, 0777));
cl_git_pass(git_fs_path_prettify(&path, FAKE_HOMEDIR_NAME, NULL));
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_HOMEDIR, path.ptr));
if (out)
git_str_swap(out, &path);
git_str_dispose(&path);
}
#define FAKE_GLOBALCONFIG_NAME "cl_fake_global"
static git_buf _cl_restore_globalconfig = GIT_BUF_INIT;
void cl_fake_globalconfig_cleanup(void *payload)
{
GIT_UNUSED(payload);
if (_cl_restore_globalconfig.ptr) {
cl_git_pass(git_futils_rmdir_r(FAKE_GLOBALCONFIG_NAME, NULL, GIT_RMDIR_REMOVE_FILES));
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_HOMEDIR, _cl_restore_globalconfig.ptr));
git_buf_dispose(&_cl_restore_globalconfig);
}
}
void cl_fake_globalconfig(git_str *out)
{
git_str path = GIT_STR_INIT;
if (!git_path_exists("home"))
cl_must_pass(p_mkdir("home", 0777));
cl_git_pass(git_path_prettify(&path, "home", NULL));
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
git_buf_dispose(&path);
GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &_cl_restore_globalconfig));
cl_set_cleanup(cl_fake_globalconfig_cleanup, NULL);
/* TOC/TOU but merely attempts to prevent accidental cleanup. */
cl_assert(!git_fs_path_exists(FAKE_GLOBALCONFIG_NAME));
cl_must_pass(p_mkdir(FAKE_GLOBALCONFIG_NAME, 0777));
cl_git_pass(git_fs_path_prettify(&path, FAKE_GLOBALCONFIG_NAME, NULL));
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
if (out)
git_str_swap(out, &path);
git_str_dispose(&path);
}
void cl_sandbox_set_homedir(const char *home)
{
git_str path = GIT_STR_INIT;
if (home) {
git_libgit2_opts(GIT_OPT_SET_HOMEDIR, home);
} else {
git_str_joinpath(&path, clar_sandbox_path(), "__home");
if (!git_fs_path_exists(path.ptr))
cl_must_pass(p_mkdir(path.ptr, 0777));
git_libgit2_opts(GIT_OPT_SET_HOMEDIR, path.ptr);
}
git_str_dispose(&path);
}
void cl_sandbox_set_search_path_defaults(void)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
git_buf_joinpath(&path, clar_sandbox_path(), "__config");
git_str_joinpath(&path, clar_sandbox_path(), "__config");
if (!git_path_exists(path.ptr))
if (!git_fs_path_exists(path.ptr))
cl_must_pass(p_mkdir(path.ptr, 0777));
git_libgit2_opts(
@@ -598,18 +678,23 @@ void cl_sandbox_set_search_path_defaults(void)
git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_PROGRAMDATA, path.ptr);
git_buf_dispose(&path);
git_str_dispose(&path);
}
void cl_sandbox_disable_ownership_validation(void)
{
git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
}
#ifdef GIT_WIN32
bool cl_sandbox_supports_8dot3(void)
{
git_buf longpath = GIT_BUF_INIT;
git_str longpath = GIT_STR_INIT;
char *shortname;
bool supported;
cl_git_pass(
git_buf_joinpath(&longpath, clar_sandbox_path(), "longer_than_8dot3"));
git_str_joinpath(&longpath, clar_sandbox_path(), "longer_than_8dot3"));
cl_git_write2file(longpath.ptr, "", 0, O_RDWR|O_CREAT, 0666);
shortname = git_win32_path_8dot3_name(longpath.ptr);
@@ -617,7 +702,7 @@ bool cl_sandbox_supports_8dot3(void)
supported = (shortname != NULL);
git__free(shortname);
git_buf_dispose(&longpath);
git_str_dispose(&longpath);
return supported;
}

View File

@@ -5,6 +5,7 @@
#include <git2.h>
#include "common.h"
#include "posix.h"
#include "oid.h"
/**
* Replace for `clar_must_pass` that passes the last library error as the
@@ -12,15 +13,15 @@
*
* Use this wrapper around all `git_` library calls that return error codes!
*/
#define cl_git_pass(expr) cl_git_expect((expr), 0, __FILE__, __LINE__)
#define cl_git_pass(expr) cl_git_expect((expr), 0, __FILE__, __func__, __LINE__)
#define cl_git_fail_with(error, expr) cl_git_expect((expr), error, __FILE__, __LINE__)
#define cl_git_fail_with(error, expr) cl_git_expect((expr), error, __FILE__, __func__, __LINE__)
#define cl_git_expect(expr, expected, file, line) do { \
#define cl_git_expect(expr, expected, file, func, line) do { \
int _lg2_error; \
git_error_clear(); \
if ((_lg2_error = (expr)) != expected) \
cl_git_report_failure(_lg2_error, expected, file, line, "Function call failed: " #expr); \
cl_git_report_failure(_lg2_error, expected, file, func, line, "Function call failed: " #expr); \
} while (0)
/**
@@ -31,7 +32,7 @@
#define cl_git_fail(expr) do { \
if ((expr) == 0) \
git_error_clear(), \
cl_git_report_failure(0, 0, __FILE__, __LINE__, "Function call succeeded: " #expr); \
cl_git_report_failure(0, 0, __FILE__, __func__, __LINE__, "Function call succeeded: " #expr); \
} while (0)
/**
@@ -41,7 +42,7 @@
int _win32_res; \
if ((_win32_res = (expr)) == 0) { \
git_error_set(GIT_ERROR_OS, "Returned: %d, system error code: %lu", _win32_res, GetLastError()); \
cl_git_report_failure(_win32_res, 0, __FILE__, __LINE__, "System call failed: " #expr); \
cl_git_report_failure(_win32_res, 0, __FILE__, __func__, __LINE__, "System call failed: " #expr); \
} \
} while(0)
@@ -58,22 +59,24 @@
typedef struct {
int error;
const char *file;
const char *func;
int line;
const char *expr;
char error_msg[4096];
} cl_git_thread_err;
#ifdef GIT_THREADS
# define cl_git_thread_pass(threaderr, expr) cl_git_thread_pass_(threaderr, (expr), __FILE__, __LINE__)
# define cl_git_thread_pass(threaderr, expr) cl_git_thread_pass_(threaderr, (expr), __FILE__, __func__, __LINE__)
#else
# define cl_git_thread_pass(threaderr, expr) cl_git_pass(expr)
#endif
#define cl_git_thread_pass_(__threaderr, __expr, __file, __line) do { \
#define cl_git_thread_pass_(__threaderr, __expr, __file, __func, __line) do { \
git_error_clear(); \
if ((((cl_git_thread_err *)__threaderr)->error = (__expr)) != 0) { \
const git_error *_last = git_error_last(); \
((cl_git_thread_err *)__threaderr)->file = __file; \
((cl_git_thread_err *)__threaderr)->func = __func; \
((cl_git_thread_err *)__threaderr)->line = __line; \
((cl_git_thread_err *)__threaderr)->expr = "Function call failed: " #__expr; \
p_snprintf(((cl_git_thread_err *)__threaderr)->error_msg, 4096, "thread 0x%" PRIxZ " - error %d - %s", \
@@ -87,38 +90,39 @@ GIT_INLINE(void) cl_git_thread_check(void *data)
{
cl_git_thread_err *threaderr = (cl_git_thread_err *)data;
if (threaderr->error != 0)
clar__assert(0, threaderr->file, threaderr->line, threaderr->expr, threaderr->error_msg, 1);
clar__assert(0, threaderr->file, threaderr->func, threaderr->line, threaderr->expr, threaderr->error_msg, 1);
}
void cl_git_report_failure(int, int, const char *, int, const char *);
void cl_git_report_failure(int, int, const char *, const char *, int, const char *);
#define cl_assert_at_line(expr,file,line) \
clar__assert((expr) != 0, file, line, "Expression is not true: " #expr, NULL, 1)
#define cl_assert_at_line(expr,file,func,line) \
clar__assert((expr) != 0, file, func, line, "Expression is not true: " #expr, NULL, 1)
GIT_INLINE(void) clar__assert_in_range(
int lo, int val, int hi,
const char *file, int line, const char *err, int should_abort)
const char *file, const char *func, int line,
const char *err, int should_abort)
{
if (lo > val || hi < val) {
char buf[128];
p_snprintf(buf, sizeof(buf), "%d not in [%d,%d]", val, lo, hi);
clar__fail(file, line, err, buf, should_abort);
clar__fail(file, func, line, err, buf, should_abort);
}
}
#define cl_assert_equal_sz(sz1,sz2) do { \
size_t __sz1 = (size_t)(sz1), __sz2 = (size_t)(sz2); \
clar__assert_equal(__FILE__,__LINE__,#sz1 " != " #sz2, 1, "%"PRIuZ, __sz1, __sz2); \
clar__assert_equal(__FILE__,__func__,__LINE__,#sz1 " != " #sz2, 1, "%"PRIuZ, __sz1, __sz2); \
} while (0)
#define cl_assert_in_range(L,V,H) \
clar__assert_in_range((L),(V),(H),__FILE__,__LINE__,"Range check: " #V " in [" #L "," #H "]", 1)
clar__assert_in_range((L),(V),(H),__FILE__,__func__,__LINE__,"Range check: " #V " in [" #L "," #H "]", 1)
#define cl_assert_equal_file(DATA,SIZE,PATH) \
clar__assert_equal_file(DATA,SIZE,0,PATH,__FILE__,(int)__LINE__)
clar__assert_equal_file(DATA,SIZE,0,PATH,__FILE__,__func__,(int)__LINE__)
#define cl_assert_equal_file_ignore_cr(DATA,SIZE,PATH) \
clar__assert_equal_file(DATA,SIZE,1,PATH,__FILE__,(int)__LINE__)
clar__assert_equal_file(DATA,SIZE,1,PATH,__FILE__,__func__,(int)__LINE__)
void clar__assert_equal_file(
const char *expected_data,
@@ -126,26 +130,63 @@ void clar__assert_equal_file(
int ignore_cr,
const char *path,
const char *file,
const char *func,
int line);
GIT_INLINE(void) clar__assert_equal_oid(
const char *file, int line, const char *desc,
const char *file, const char *func, int line, const char *desc,
const git_oid *one, const git_oid *two)
{
if (git_oid_cmp(one, two)) {
char err[] = "\"........................................\" != \"........................................\"";
if (git_oid_equal(one, two))
return;
if (git_oid_type(one) != git_oid_type(two)) {
char err[64];
snprintf(err, 64, "different oid types: %d vs %d", git_oid_type(one), git_oid_type(two));
clar__fail(file, func, line, desc, err, 1);
} else if (git_oid_type(one) == GIT_OID_SHA1) {
char err[] = "\"........................................\" != \"........................................\"";
git_oid_fmt(&err[1], one);
git_oid_fmt(&err[47], two);
clar__fail(file, line, desc, err, 1);
clar__fail(file, func, line, desc, err, 1);
#ifdef GIT_EXPERIMENTAL_SHA256
} else if (one->type == GIT_OID_SHA256) {
char err[] = "\"................................................................\" != \"................................................................\"";
git_oid_fmt(&err[1], one);
git_oid_fmt(&err[71], one);
clar__fail(file, func, line, desc, err, 1);
#endif
} else {
clar__fail(file, func, line, desc, "unknown oid types", 1);
}
}
GIT_INLINE(void) clar__assert_equal_oidstr(
const char *file, const char *func, int line, const char *desc,
const char *one_str, const git_oid *two)
{
git_oid one;
if (git_oid__fromstr(&one, one_str, git_oid_type(two)) < 0) {
clar__fail(file, func, line, desc, "could not parse oid string", 1);
} else {
clar__assert_equal_oid(file, func, line, desc, &one, two);
}
}
#define cl_assert_equal_oid(one, two) \
clar__assert_equal_oid(__FILE__, __LINE__, \
clar__assert_equal_oid(__FILE__, __func__, __LINE__, \
"OID mismatch: " #one " != " #two, (one), (two))
#define cl_assert_equal_oidstr(one_str, two) \
clar__assert_equal_oidstr(__FILE__, __func__, __LINE__, \
"OID mismatch: " #one_str " != " #two, (one_str), (two))
/*
* Some utility macros for building long strings
*/
@@ -207,17 +248,30 @@ void cl_repo_commit_from_index(
void cl_repo_set_bool(git_repository *repo, const char *cfg, int value);
int cl_repo_get_bool(git_repository *repo, const char *cfg);
void cl_repo_set_int(git_repository *repo, const char *cfg, int value);
int cl_repo_get_int(git_repository *repo, const char *cfg);
void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value);
/* set up a fake "home" directory and set libgit2 GLOBAL search path.
*
* automatically configures cleanup function to restore the regular search
* path, although you can call it explicitly if you wish (with NULL).
/*
* set up a fake "home" directory -- automatically configures cleanup
* function to restore the home directory, although you can call it
* explicitly if you wish (with NULL).
*/
void cl_fake_home(void);
void cl_fake_home_cleanup(void *);
void cl_fake_homedir(git_str *);
void cl_fake_homedir_cleanup(void *);
/*
* set up a fake global configuration directory -- automatically
* configures cleanup function to restore the global config
* although you can call it explicitly if you wish (with NULL).
*/
void cl_fake_globalconfig(git_str *);
void cl_fake_globalconfig_cleanup(void *);
void cl_sandbox_set_homedir(const char *);
void cl_sandbox_set_search_path_defaults(void);
void cl_sandbox_disable_ownership_validation(void);
#ifdef GIT_WIN32
# define cl_msleep(x) Sleep(x)

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "clar_libgit2_alloc.h"
static size_t bytes_available;
/*
* The clar allocator uses a tagging mechanism for pointers that
* prepends the actual pointer's number bytes as `size_t`.
*
* First, this is required in order to be able to implement
* proper bookkeeping of allocated bytes in both `free` and
* `realloc`.
*
* Second, it may also be able to spot bugs that are
* otherwise hard to grasp, as the returned pointer cannot be
* free'd directly via free(3P). Instead, one is forced to use
* the tandem of `cl__malloc` and `cl__free`, as otherwise the
* code is going to crash hard. This is considered to be a
* feature, as it helps e.g. in finding cases where by accident
* malloc(3P) and free(3P) were used instead of git__malloc and
* git__free, respectively.
*
* The downside is obviously that each allocation grows by
* sizeof(size_t) bytes. As the allocator is for testing purposes
* only, this tradeoff is considered to be perfectly fine,
* though.
*/
static void *cl__malloc(size_t len, const char *file, int line)
{
char *ptr = NULL;
size_t alloclen;
GIT_UNUSED(file);
GIT_UNUSED(line);
if (len > bytes_available)
goto out;
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, len, sizeof(size_t)) ||
(ptr = malloc(alloclen)) == NULL)
goto out;
memcpy(ptr, &len, sizeof(size_t));
bytes_available -= len;
out:
return ptr ? ptr + sizeof(size_t) : NULL;
}
static void cl__free(void *ptr)
{
if (ptr) {
char *p = ptr;
size_t len;
memcpy(&len, p - sizeof(size_t), sizeof(size_t));
free(p - sizeof(size_t));
bytes_available += len;
}
}
static void *cl__realloc(void *ptr, size_t size, const char *file, int line)
{
size_t copybytes = 0;
char *p = ptr;
void *new;
if (p)
memcpy(&copybytes, p - sizeof(size_t), sizeof(size_t));
if (copybytes > size)
copybytes = size;
if ((new = cl__malloc(size, file, line)) == NULL)
goto out;
if (p) {
memcpy(new, p, copybytes);
cl__free(p);
}
out:
return new;
}
void cl_alloc_limit(size_t bytes)
{
git_allocator alloc;
alloc.gmalloc = cl__malloc;
alloc.grealloc = cl__realloc;
alloc.gfree = cl__free;
git_allocator_setup(&alloc);
bytes_available = bytes;
}
void cl_alloc_reset(void)
{
git_allocator stdalloc;
git_stdalloc_init_allocator(&stdalloc);
git_allocator_setup(&stdalloc);
}

View File

@@ -0,0 +1,11 @@
#ifndef __CLAR_LIBGIT2_ALLOC__
#define __CLAR_LIBGIT2_ALLOC__
#include "clar.h"
#include "common.h"
#include "git2/sys/alloc.h"
void cl_alloc_limit(size_t bytes);
void cl_alloc_reset(void);
#endif

View File

@@ -1,6 +1,5 @@
#include "clar_libgit2.h"
#include "clar_libgit2_timer.h"
#include "buffer.h"
void cl_perf_timer__init(cl_perf_timer *t)
{
@@ -9,23 +8,23 @@ void cl_perf_timer__init(cl_perf_timer *t)
void cl_perf_timer__start(cl_perf_timer *t)
{
t->time_started = git__timer();
t->time_started = git_time_monotonic();
}
void cl_perf_timer__stop(cl_perf_timer *t)
{
double time_now = git__timer();
uint64_t time_now = git_time_monotonic();
t->last = time_now - t->time_started;
t->sum += t->last;
}
double cl_perf_timer__last(const cl_perf_timer *t)
uint64_t cl_perf_timer__last(const cl_perf_timer *t)
{
return t->last;
}
double cl_perf_timer__sum(const cl_perf_timer *t)
uint64_t cl_perf_timer__sum(const cl_perf_timer *t)
{
return t->sum;
}

View File

@@ -3,14 +3,14 @@
struct cl_perf_timer
{
/* cummulative running time across all start..stop intervals */
double sum;
/* cumulative running time across all start..stop intervals */
uint64_t sum;
/* value of last start..stop interval */
double last;
uint64_t last;
/* clock value at start */
double time_started;
uint64_t time_started;
};
#define CL_PERF_TIMER_INIT {0}
@@ -24,12 +24,12 @@ void cl_perf_timer__stop(cl_perf_timer *t);
/**
* return value of last start..stop interval in seconds.
*/
double cl_perf_timer__last(const cl_perf_timer *t);
uint64_t cl_perf_timer__last(const cl_perf_timer *t);
/**
* return cummulative running time across all start..stop
* return cumulative running time across all start..stop
* intervals in seconds.
*/
double cl_perf_timer__sum(const cl_perf_timer *t);
uint64_t cl_perf_timer__sum(const cl_perf_timer *t);
#endif /* __CLAR_LIBGIT2_TIMER__ */

View File

@@ -150,7 +150,7 @@ static cl_perf_timer s_timer_run = CL_PERF_TIMER_INIT;
*/
static cl_perf_timer s_timer_test = CL_PERF_TIMER_INIT;
void _cl_trace_cb__event_handler(
static void _cl_trace_cb__event_handler(
cl_trace_event ev,
const char *suite_name,
const char *test_name,
@@ -164,7 +164,7 @@ void _cl_trace_cb__event_handler(
switch (ev) {
case CL_TRACE__SUITE_BEGIN:
git_trace(GIT_TRACE_TRACE, "\n\n%s\n%s: Begin Suite", HR, suite_name);
#if 0 && defined(GIT_MSVC_CRTDBG)
#if 0 && defined(GIT_WIN32_LEAKCHECK)
git_win32__crtdbg_stacktrace__dump(
GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK,
suite_name);
@@ -172,7 +172,7 @@ void _cl_trace_cb__event_handler(
break;
case CL_TRACE__SUITE_END:
#if 0 && defined(GIT_MSVC_CRTDBG)
#if 0 && defined(GIT_WIN32_LEAKCHECK)
/* As an example of checkpointing, dump leaks within this suite.
* This may generate false positives for things like the global
* TLS error state and maybe the odb cache since they aren't
@@ -197,7 +197,7 @@ void _cl_trace_cb__event_handler(
case CL_TRACE__TEST__END:
cl_perf_timer__stop(&s_timer_test);
git_trace(GIT_TRACE_TRACE, "%s::%s: End Test (%.3f %.3f)", suite_name, test_name,
git_trace(GIT_TRACE_TRACE, "%s::%s: End Test (%" PRIuZ " %" PRIuZ ")", suite_name, test_name,
cl_perf_timer__last(&s_timer_run),
cl_perf_timer__last(&s_timer_test));
break;

View File

@@ -1,333 +0,0 @@
#ifdef _WIN32
#define RM_RETRY_COUNT 5
#define RM_RETRY_DELAY 10
#ifdef __MINGW32__
/* These security-enhanced functions are not available
* in MinGW, so just use the vanilla ones */
#define wcscpy_s(a, b, c) wcscpy((a), (c))
#define wcscat_s(a, b, c) wcscat((a), (c))
#endif /* __MINGW32__ */
static int
fs__dotordotdot(WCHAR *_tocheck)
{
return _tocheck[0] == '.' &&
(_tocheck[1] == '\0' ||
(_tocheck[1] == '.' && _tocheck[2] == '\0'));
}
static int
fs_rmdir_rmdir(WCHAR *_wpath)
{
unsigned retries = 1;
while (!RemoveDirectoryW(_wpath)) {
/* Only retry when we have retries remaining, and the
* error was ERROR_DIR_NOT_EMPTY. */
if (retries++ > RM_RETRY_COUNT ||
ERROR_DIR_NOT_EMPTY != GetLastError())
return -1;
/* Give whatever has a handle to a child item some time
* to release it before trying again */
Sleep(RM_RETRY_DELAY * retries * retries);
}
return 0;
}
static void
fs_rmdir_helper(WCHAR *_wsource)
{
WCHAR buffer[MAX_PATH];
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
size_t buffer_prefix_len;
/* Set up the buffer and capture the length */
wcscpy_s(buffer, MAX_PATH, _wsource);
wcscat_s(buffer, MAX_PATH, L"\\");
buffer_prefix_len = wcslen(buffer);
/* FindFirstFile needs a wildcard to match multiple items */
wcscat_s(buffer, MAX_PATH, L"*");
find_handle = FindFirstFileW(buffer, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
do {
/* FindFirstFile/FindNextFile gives back . and ..
* entries at the beginning */
if (fs__dotordotdot(find_data.cFileName))
continue;
wcscpy_s(buffer + buffer_prefix_len, MAX_PATH - buffer_prefix_len, find_data.cFileName);
if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
fs_rmdir_helper(buffer);
else {
/* If set, the +R bit must be cleared before deleting */
if (FILE_ATTRIBUTE_READONLY & find_data.dwFileAttributes)
cl_assert(SetFileAttributesW(buffer, find_data.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY));
cl_assert(DeleteFileW(buffer));
}
}
while (FindNextFileW(find_handle, &find_data));
/* Ensure that we successfully completed the enumeration */
cl_assert(ERROR_NO_MORE_FILES == GetLastError());
/* Close the find handle */
FindClose(find_handle);
/* Now that the directory is empty, remove it */
cl_assert(0 == fs_rmdir_rmdir(_wsource));
}
static int
fs_rm_wait(WCHAR *_wpath)
{
unsigned retries = 1;
DWORD last_error;
do {
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(_wpath))
last_error = GetLastError();
else
last_error = ERROR_SUCCESS;
/* Is the item gone? */
if (ERROR_FILE_NOT_FOUND == last_error ||
ERROR_PATH_NOT_FOUND == last_error)
return 0;
Sleep(RM_RETRY_DELAY * retries * retries);
}
while (retries++ <= RM_RETRY_COUNT);
return -1;
}
static void
fs_rm(const char *_source)
{
WCHAR wsource[MAX_PATH];
DWORD attrs;
/* The input path is UTF-8. Convert it to wide characters
* for use with the Windows API */
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_source,
-1, /* Indicates NULL termination */
wsource,
MAX_PATH));
/* Does the item exist? If not, we have no work to do */
attrs = GetFileAttributesW(wsource);
if (INVALID_FILE_ATTRIBUTES == attrs)
return;
if (FILE_ATTRIBUTE_DIRECTORY & attrs)
fs_rmdir_helper(wsource);
else {
/* The item is a file. Strip the +R bit */
if (FILE_ATTRIBUTE_READONLY & attrs)
cl_assert(SetFileAttributesW(wsource, attrs & ~FILE_ATTRIBUTE_READONLY));
cl_assert(DeleteFileW(wsource));
}
/* Wait for the DeleteFile or RemoveDirectory call to complete */
cl_assert(0 == fs_rm_wait(wsource));
}
static void
fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest)
{
WCHAR buf_source[MAX_PATH], buf_dest[MAX_PATH];
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
size_t buf_source_prefix_len, buf_dest_prefix_len;
wcscpy_s(buf_source, MAX_PATH, _wsource);
wcscat_s(buf_source, MAX_PATH, L"\\");
buf_source_prefix_len = wcslen(buf_source);
wcscpy_s(buf_dest, MAX_PATH, _wdest);
wcscat_s(buf_dest, MAX_PATH, L"\\");
buf_dest_prefix_len = wcslen(buf_dest);
/* Get an enumerator for the items in the source. */
wcscat_s(buf_source, MAX_PATH, L"*");
find_handle = FindFirstFileW(buf_source, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
/* Create the target directory. */
cl_assert(CreateDirectoryW(_wdest, NULL));
do {
/* FindFirstFile/FindNextFile gives back . and ..
* entries at the beginning */
if (fs__dotordotdot(find_data.cFileName))
continue;
wcscpy_s(buf_source + buf_source_prefix_len, MAX_PATH - buf_source_prefix_len, find_data.cFileName);
wcscpy_s(buf_dest + buf_dest_prefix_len, MAX_PATH - buf_dest_prefix_len, find_data.cFileName);
if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
fs_copydir_helper(buf_source, buf_dest);
else
cl_assert(CopyFileW(buf_source, buf_dest, TRUE));
}
while (FindNextFileW(find_handle, &find_data));
/* Ensure that we successfully completed the enumeration */
cl_assert(ERROR_NO_MORE_FILES == GetLastError());
/* Close the find handle */
FindClose(find_handle);
}
static void
fs_copy(const char *_source, const char *_dest)
{
WCHAR wsource[MAX_PATH], wdest[MAX_PATH];
DWORD source_attrs, dest_attrs;
HANDLE find_handle;
WIN32_FIND_DATAW find_data;
/* The input paths are UTF-8. Convert them to wide characters
* for use with the Windows API. */
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_source,
-1,
wsource,
MAX_PATH));
cl_assert(MultiByteToWideChar(CP_UTF8,
MB_ERR_INVALID_CHARS,
_dest,
-1,
wdest,
MAX_PATH));
/* Check the source for existence */
source_attrs = GetFileAttributesW(wsource);
cl_assert(INVALID_FILE_ATTRIBUTES != source_attrs);
/* Check the target for existence */
dest_attrs = GetFileAttributesW(wdest);
if (INVALID_FILE_ATTRIBUTES != dest_attrs) {
/* Target exists; append last path part of source to target.
* Use FindFirstFile to parse the path */
find_handle = FindFirstFileW(wsource, &find_data);
cl_assert(INVALID_HANDLE_VALUE != find_handle);
wcscat_s(wdest, MAX_PATH, L"\\");
wcscat_s(wdest, MAX_PATH, find_data.cFileName);
FindClose(find_handle);
/* Check the new target for existence */
cl_assert(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(wdest));
}
if (FILE_ATTRIBUTE_DIRECTORY & source_attrs)
fs_copydir_helper(wsource, wdest);
else
cl_assert(CopyFileW(wsource, wdest, TRUE));
}
void
cl_fs_cleanup(void)
{
fs_rm(fixture_path(_clar_path, "*"));
}
#else
#include <errno.h>
#include <string.h>
static int
shell_out(char * const argv[])
{
int status, piderr;
pid_t pid;
pid = fork();
if (pid < 0) {
fprintf(stderr,
"System error: `fork()` call failed (%d) - %s\n",
errno, strerror(errno));
exit(-1);
}
if (pid == 0) {
execv(argv[0], argv);
}
do {
piderr = waitpid(pid, &status, WUNTRACED);
} while (piderr < 0 && (errno == EAGAIN || errno == EINTR));
return WEXITSTATUS(status);
}
static void
fs_copy(const char *_source, const char *dest)
{
char *argv[5];
char *source;
size_t source_len;
source = strdup(_source);
source_len = strlen(source);
if (source[source_len - 1] == '/')
source[source_len - 1] = 0;
argv[0] = "/bin/cp";
argv[1] = "-R";
argv[2] = source;
argv[3] = (char *)dest;
argv[4] = NULL;
cl_must_pass_(
shell_out(argv),
"Failed to copy test fixtures to sandbox"
);
free(source);
}
static void
fs_rm(const char *source)
{
char *argv[4];
argv[0] = "/bin/rm";
argv[1] = "-Rf";
argv[2] = (char *)source;
argv[3] = NULL;
cl_must_pass_(
shell_out(argv),
"Failed to cleanup the sandbox"
);
}
void
cl_fs_cleanup(void)
{
clar_unsandbox();
clar_sandbox();
}
#endif

View File

@@ -8,7 +8,7 @@
from __future__ import with_statement
from string import Template
import re, fnmatch, os, sys, codecs, pickle
import re, fnmatch, os, sys, codecs, pickle, io
class Module(object):
class Template(object):
@@ -147,7 +147,7 @@ class TestSuite(object):
self.path = path
self.output = output
def should_generate(self, path):
def maybe_generate(self, path):
if not os.path.isfile(path):
return True
@@ -216,33 +216,82 @@ class TestSuite(object):
return sum(len(module.callbacks) for module in self.modules.values())
def write(self):
output = os.path.join(self.output, 'clar.suite')
wrote_suite = self.write_suite()
wrote_header = self.write_header()
if not self.should_generate(output):
if wrote_suite or wrote_header:
self.save_cache()
return True
return False
def write_output(self, fn, data):
if not self.maybe_generate(fn):
return False
with open(output, 'w') as data:
current = None
try:
with open(fn, 'r') as input:
current = input.read()
except OSError:
pass
except IOError:
pass
if current == data:
return False
with open(fn, 'w') as output:
output.write(data)
return True
def write_suite(self):
suite_fn = os.path.join(self.output, 'clar.suite')
with io.StringIO() as suite_file:
modules = sorted(self.modules.values(), key=lambda module: module.name)
for module in modules:
t = Module.DeclarationTemplate(module)
data.write(t.render())
suite_file.write(t.render())
for module in modules:
t = Module.CallbacksTemplate(module)
data.write(t.render())
suite_file.write(t.render())
suites = "static struct clar_suite _clar_suites[] = {" + ','.join(
Module.InfoTemplate(module).render() for module in modules
) + "\n};\n"
data.write(suites)
suite_file.write(suites)
data.write("static const size_t _clar_suite_count = %d;\n" % self.suite_count())
data.write("static const size_t _clar_callback_count = %d;\n" % self.callback_count())
suite_file.write(u"static const size_t _clar_suite_count = %d;\n" % self.suite_count())
suite_file.write(u"static const size_t _clar_callback_count = %d;\n" % self.callback_count())
self.save_cache()
return True
return self.write_output(suite_fn, suite_file.getvalue())
return False
def write_header(self):
header_fn = os.path.join(self.output, 'clar_suite.h')
with io.StringIO() as header_file:
header_file.write(u"#ifndef _____clar_suite_h_____\n")
header_file.write(u"#define _____clar_suite_h_____\n")
modules = sorted(self.modules.values(), key=lambda module: module.name)
for module in modules:
t = Module.DeclarationTemplate(module)
header_file.write(t.render())
header_file.write(u"#endif\n")
return self.write_output(header_fn, header_file.getvalue())
return False
if __name__ == '__main__':
from optparse import OptionParser
@@ -263,5 +312,5 @@ if __name__ == '__main__':
suite.load(options.force)
suite.disable(options.excluded)
if suite.write():
print("Written `clar.suite` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count()))
print("Written `clar.suite`, `clar_suite.h` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count()))

View File

@@ -1,6 +1,10 @@
#include "clar_libgit2.h"
#include "clar_libgit2_trace.h"
#ifdef GIT_WIN32_LEAKCHECK
# include "win32/w32_leakcheck.h"
#endif
#ifdef _WIN32
int __cdecl main(int argc, char *argv[])
#else
@@ -14,12 +18,16 @@ int main(int argc, char *argv[])
res = git_libgit2_init();
if (res < 0) {
fprintf(stderr, "failed to init libgit2");
const git_error *err = git_error_last();
const char *msg = err ? err->message : "unknown failure";
fprintf(stderr, "failed to init libgit2: %s\n", msg);
return res;
}
cl_global_trace_register();
cl_sandbox_set_homedir(getenv("CLAR_HOMEDIR"));
cl_sandbox_set_search_path_defaults();
cl_sandbox_disable_ownership_validation();
/* Run the test suite */
res = clar_test_run();
@@ -29,6 +37,11 @@ int main(int argc, char *argv[])
cl_global_trace_disable();
git_libgit2_shutdown();
#ifdef GIT_WIN32_LEAKCHECK
if (git_win32_leakcheck_has_leaks())
res = res || 1;
#endif
at_exit_cmd = getenv("CLAR_AT_EXIT");
if (at_exit_cmd != NULL) {
int at_exit = system(at_exit_cmd);

View File

@@ -1,67 +0,0 @@
static void clar_print_init(int test_count, int suite_count, const char *suite_names)
{
(void)test_count;
printf("Loaded %d suites: %s\n", (int)suite_count, suite_names);
printf("Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')\n");
}
static void clar_print_shutdown(int test_count, int suite_count, int error_count)
{
(void)test_count;
(void)suite_count;
(void)error_count;
printf("\n\n");
clar_report_all();
}
static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error)
{
printf(" %d) Failure:\n", num);
printf("%s::%s [%s:%"PRIuZ"]\n",
report->suite,
report->test,
error->file,
error->line_number);
printf(" %s\n", error->error_msg);
if (error->description != NULL)
printf(" %s\n", error->description);
printf("\n");
fflush(stdout);
}
static void clar_print_ontest(const char *test_name, int test_number, enum cl_test_status status)
{
(void)test_name;
(void)test_number;
switch(status) {
case CL_TEST_OK: printf("."); break;
case CL_TEST_FAILURE: printf("F"); break;
case CL_TEST_SKIP: printf("S"); break;
case CL_TEST_NOTRUN: printf("N"); break;
}
fflush(stdout);
}
static void clar_print_onsuite(const char *suite_name, int suite_index)
{
if (_clar.report_suite_names)
printf("\n%s", suite_name);
(void)suite_index;
}
static void clar_print_onabort(const char *msg, ...)
{
va_list argp;
va_start(argp, msg);
vfprintf(stderr, msg, argp);
va_end(argp);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,70 +0,0 @@
#include "clar_libgit2.h"
static git_oid id;
static git_oid idp;
static git_oid idm;
const char *str_oid = "ae90f12eea699729ed24555e40b9fd669da12a12";
const char *str_oid_p = "ae90f12eea699729ed";
const char *str_oid_m = "ae90f12eea699729ed24555e40b9fd669da12a12THIS IS EXTRA TEXT THAT SHOULD GET IGNORED";
void test_core_oid__initialize(void)
{
cl_git_pass(git_oid_fromstr(&id, str_oid));
cl_git_pass(git_oid_fromstrp(&idp, str_oid_p));
cl_git_fail(git_oid_fromstrp(&idm, str_oid_m));
}
void test_core_oid__streq(void)
{
cl_assert_equal_i(0, git_oid_streq(&id, str_oid));
cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeef"));
cl_assert_equal_i(-1, git_oid_streq(&id, "I'm not an oid.... :)"));
cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000"));
cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed"));
cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ed1"));
cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ec"));
cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeef"));
cl_assert_equal_i(-1, git_oid_streq(&idp, "I'm not an oid.... :)"));
}
void test_core_oid__strcmp(void)
{
cl_assert_equal_i(0, git_oid_strcmp(&id, str_oid));
cl_assert(git_oid_strcmp(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0);
cl_assert(git_oid_strcmp(&id, "deadbeef") < 0);
cl_assert_equal_i(-1, git_oid_strcmp(&id, "I'm not an oid.... :)"));
cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed0000000000000000000000"));
cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed"));
cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ed1") < 0);
cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ec") > 0);
cl_assert(git_oid_strcmp(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0);
cl_assert(git_oid_strcmp(&idp, "deadbeef") < 0);
cl_assert_equal_i(-1, git_oid_strcmp(&idp, "I'm not an oid.... :)"));
}
void test_core_oid__ncmp(void)
{
cl_assert(!git_oid_ncmp(&id, &idp, 0));
cl_assert(!git_oid_ncmp(&id, &idp, 1));
cl_assert(!git_oid_ncmp(&id, &idp, 2));
cl_assert(!git_oid_ncmp(&id, &idp, 17));
cl_assert(!git_oid_ncmp(&id, &idp, 18));
cl_assert(git_oid_ncmp(&id, &idp, 19));
cl_assert(git_oid_ncmp(&id, &idp, 40));
cl_assert(git_oid_ncmp(&id, &idp, 41));
cl_assert(git_oid_ncmp(&id, &idp, 42));
cl_assert(!git_oid_ncmp(&id, &id, 0));
cl_assert(!git_oid_ncmp(&id, &id, 1));
cl_assert(!git_oid_ncmp(&id, &id, 39));
cl_assert(!git_oid_ncmp(&id, &id, 40));
cl_assert(!git_oid_ncmp(&id, &id, 41));
}

View File

@@ -1,25 +0,0 @@
#include "clar_libgit2.h"
#include "cache.h"
void test_core_opts__readwrite(void)
{
size_t old_val = 0;
size_t new_val = 0;
git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &old_val);
git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, (size_t)1234);
git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &new_val);
cl_assert(new_val == 1234);
git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, old_val);
git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &new_val);
cl_assert(new_val == old_val);
}
void test_core_opts__invalid_option(void)
{
cl_git_fail(git_libgit2_opts(-1, "foobar"));
}

View File

@@ -1,687 +0,0 @@
#include "clar_libgit2.h"
#include "futils.h"
static void
check_dirname(const char *A, const char *B)
{
git_buf dir = GIT_BUF_INIT;
char *dir2;
cl_assert(git_path_dirname_r(&dir, A) >= 0);
cl_assert_equal_s(B, dir.ptr);
git_buf_dispose(&dir);
cl_assert((dir2 = git_path_dirname(A)) != NULL);
cl_assert_equal_s(B, dir2);
git__free(dir2);
}
static void
check_basename(const char *A, const char *B)
{
git_buf base = GIT_BUF_INIT;
char *base2;
cl_assert(git_path_basename_r(&base, A) >= 0);
cl_assert_equal_s(B, base.ptr);
git_buf_dispose(&base);
cl_assert((base2 = git_path_basename(A)) != NULL);
cl_assert_equal_s(B, base2);
git__free(base2);
}
static void
check_topdir(const char *A, const char *B)
{
const char *dir;
cl_assert((dir = git_path_topdir(A)) != NULL);
cl_assert_equal_s(B, dir);
}
static void
check_joinpath(const char *path_a, const char *path_b, const char *expected_path)
{
git_buf joined_path = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&joined_path, path_a, path_b));
cl_assert_equal_s(expected_path, joined_path.ptr);
git_buf_dispose(&joined_path);
}
static void
check_joinpath_n(
const char *path_a,
const char *path_b,
const char *path_c,
const char *path_d,
const char *expected_path)
{
git_buf joined_path = GIT_BUF_INIT;
cl_git_pass(git_buf_join_n(&joined_path, '/', 4,
path_a, path_b, path_c, path_d));
cl_assert_equal_s(expected_path, joined_path.ptr);
git_buf_dispose(&joined_path);
}
/* get the dirname of a path */
void test_core_path__00_dirname(void)
{
check_dirname(NULL, ".");
check_dirname("", ".");
check_dirname("a", ".");
check_dirname("/", "/");
check_dirname("/usr", "/");
check_dirname("/usr/", "/");
check_dirname("/usr/lib", "/usr");
check_dirname("/usr/lib/", "/usr");
check_dirname("/usr/lib//", "/usr");
check_dirname("usr/lib", "usr");
check_dirname("usr/lib/", "usr");
check_dirname("usr/lib//", "usr");
check_dirname(".git/", ".");
check_dirname(REP16("/abc"), REP15("/abc"));
#ifdef GIT_WIN32
check_dirname("C:/", "C:/");
check_dirname("C:", "C:/");
check_dirname("C:/path/", "C:/");
check_dirname("C:/path", "C:/");
check_dirname("//computername/", "//computername/");
check_dirname("//computername", "//computername/");
check_dirname("//computername/path/", "//computername/");
check_dirname("//computername/path", "//computername/");
check_dirname("//computername/sub/path/", "//computername/sub");
check_dirname("//computername/sub/path", "//computername/sub");
#endif
}
/* get the base name of a path */
void test_core_path__01_basename(void)
{
check_basename(NULL, ".");
check_basename("", ".");
check_basename("a", "a");
check_basename("/", "/");
check_basename("/usr", "usr");
check_basename("/usr/", "usr");
check_basename("/usr/lib", "lib");
check_basename("/usr/lib//", "lib");
check_basename("usr/lib", "lib");
check_basename(REP16("/abc"), "abc");
check_basename(REP1024("/abc"), "abc");
}
/* get the latest component in a path */
void test_core_path__02_topdir(void)
{
check_topdir(".git/", ".git/");
check_topdir("/.git/", ".git/");
check_topdir("usr/local/.git/", ".git/");
check_topdir("./.git/", ".git/");
check_topdir("/usr/.git/", ".git/");
check_topdir("/", "/");
check_topdir("a/", "a/");
cl_assert(git_path_topdir("/usr/.git") == NULL);
cl_assert(git_path_topdir(".") == NULL);
cl_assert(git_path_topdir("") == NULL);
cl_assert(git_path_topdir("a") == NULL);
}
/* properly join path components */
void test_core_path__05_joins(void)
{
check_joinpath("", "", "");
check_joinpath("", "a", "a");
check_joinpath("", "/a", "/a");
check_joinpath("a", "", "a/");
check_joinpath("a", "/", "a/");
check_joinpath("a", "b", "a/b");
check_joinpath("/", "a", "/a");
check_joinpath("/", "", "/");
check_joinpath("/a", "/b", "/a/b");
check_joinpath("/a", "/b/", "/a/b/");
check_joinpath("/a/", "b/", "/a/b/");
check_joinpath("/a/", "/b/", "/a/b/");
check_joinpath("/abcd", "/defg", "/abcd/defg");
check_joinpath("/abcd", "/defg/", "/abcd/defg/");
check_joinpath("/abcd/", "defg/", "/abcd/defg/");
check_joinpath("/abcd/", "/defg/", "/abcd/defg/");
check_joinpath("/abcdefgh", "/12345678", "/abcdefgh/12345678");
check_joinpath("/abcdefgh", "/12345678/", "/abcdefgh/12345678/");
check_joinpath("/abcdefgh/", "12345678/", "/abcdefgh/12345678/");
check_joinpath(REP1024("aaaa"), "", REP1024("aaaa") "/");
check_joinpath(REP1024("aaaa/"), "", REP1024("aaaa/"));
check_joinpath(REP1024("/aaaa"), "", REP1024("/aaaa") "/");
check_joinpath(REP1024("aaaa"), REP1024("bbbb"),
REP1024("aaaa") "/" REP1024("bbbb"));
check_joinpath(REP1024("/aaaa"), REP1024("/bbbb"),
REP1024("/aaaa") REP1024("/bbbb"));
}
/* properly join path components for more than one path */
void test_core_path__06_long_joins(void)
{
check_joinpath_n("", "", "", "", "");
check_joinpath_n("", "a", "", "", "a/");
check_joinpath_n("a", "", "", "", "a/");
check_joinpath_n("", "", "", "a", "a");
check_joinpath_n("a", "b", "", "/c/d/", "a/b/c/d/");
check_joinpath_n("a", "b", "", "/c/d", "a/b/c/d");
check_joinpath_n("abcd", "efgh", "ijkl", "mnop", "abcd/efgh/ijkl/mnop");
check_joinpath_n("abcd/", "efgh/", "ijkl/", "mnop/", "abcd/efgh/ijkl/mnop/");
check_joinpath_n("/abcd/", "/efgh/", "/ijkl/", "/mnop/", "/abcd/efgh/ijkl/mnop/");
check_joinpath_n(REP1024("a"), REP1024("b"), REP1024("c"), REP1024("d"),
REP1024("a") "/" REP1024("b") "/"
REP1024("c") "/" REP1024("d"));
check_joinpath_n(REP1024("/a"), REP1024("/b"), REP1024("/c"), REP1024("/d"),
REP1024("/a") REP1024("/b")
REP1024("/c") REP1024("/d"));
}
static void
check_path_to_dir(
const char* path,
const char* expected)
{
git_buf tgt = GIT_BUF_INIT;
git_buf_sets(&tgt, path);
cl_git_pass(git_path_to_dir(&tgt));
cl_assert_equal_s(expected, tgt.ptr);
git_buf_dispose(&tgt);
}
static void
check_string_to_dir(
const char* path,
size_t maxlen,
const char* expected)
{
size_t len = strlen(path);
char *buf = git__malloc(len + 2);
cl_assert(buf);
strncpy(buf, path, len + 2);
git_path_string_to_dir(buf, maxlen);
cl_assert_equal_s(expected, buf);
git__free(buf);
}
/* convert paths to dirs */
void test_core_path__07_path_to_dir(void)
{
check_path_to_dir("", "");
check_path_to_dir(".", "./");
check_path_to_dir("./", "./");
check_path_to_dir("a/", "a/");
check_path_to_dir("ab", "ab/");
/* make sure we try just under and just over an expansion that will
* require a realloc
*/
check_path_to_dir("abcdef", "abcdef/");
check_path_to_dir("abcdefg", "abcdefg/");
check_path_to_dir("abcdefgh", "abcdefgh/");
check_path_to_dir("abcdefghi", "abcdefghi/");
check_path_to_dir(REP1024("abcd") "/", REP1024("abcd") "/");
check_path_to_dir(REP1024("abcd"), REP1024("abcd") "/");
check_string_to_dir("", 1, "");
check_string_to_dir(".", 1, ".");
check_string_to_dir(".", 2, "./");
check_string_to_dir(".", 3, "./");
check_string_to_dir("abcd", 3, "abcd");
check_string_to_dir("abcd", 4, "abcd");
check_string_to_dir("abcd", 5, "abcd/");
check_string_to_dir("abcd", 6, "abcd/");
}
/* join path to itself */
void test_core_path__08_self_join(void)
{
git_buf path = GIT_BUF_INIT;
size_t asize = 0;
asize = path.asize;
cl_git_pass(git_buf_sets(&path, "/foo"));
cl_assert_equal_s(path.ptr, "/foo");
cl_assert(asize < path.asize);
asize = path.asize;
cl_git_pass(git_buf_joinpath(&path, path.ptr, "this is a new string"));
cl_assert_equal_s(path.ptr, "/foo/this is a new string");
cl_assert(asize < path.asize);
asize = path.asize;
cl_git_pass(git_buf_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer"));
cl_assert_equal_s(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer");
cl_assert(asize < path.asize);
git_buf_dispose(&path);
cl_git_pass(git_buf_sets(&path, "/foo/bar"));
cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "baz"));
cl_assert_equal_s(path.ptr, "/bar/baz");
asize = path.asize;
cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc"));
cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc");
cl_assert(asize < path.asize);
git_buf_dispose(&path);
}
static void check_percent_decoding(const char *expected_result, const char *input)
{
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git__percent_decode(&buf, input));
cl_assert_equal_s(expected_result, git_buf_cstr(&buf));
git_buf_dispose(&buf);
}
void test_core_path__09_percent_decode(void)
{
check_percent_decoding("abcd", "abcd");
check_percent_decoding("a2%", "a2%");
check_percent_decoding("a2%3", "a2%3");
check_percent_decoding("a2%%3", "a2%%3");
check_percent_decoding("a2%3z", "a2%3z");
check_percent_decoding("a,", "a%2c");
check_percent_decoding("a21", "a2%31");
check_percent_decoding("a2%1", "a2%%31");
check_percent_decoding("a bc ", "a%20bc%20");
check_percent_decoding("Vicent Mart" "\355", "Vicent%20Mart%ED");
}
static void check_fromurl(const char *expected_result, const char *input, int should_fail)
{
git_buf buf = GIT_BUF_INIT;
assert(should_fail || expected_result);
if (!should_fail) {
cl_git_pass(git_path_fromurl(&buf, input));
cl_assert_equal_s(expected_result, git_buf_cstr(&buf));
} else
cl_git_fail(git_path_fromurl(&buf, input));
git_buf_dispose(&buf);
}
#ifdef GIT_WIN32
#define ABS_PATH_MARKER ""
#else
#define ABS_PATH_MARKER "/"
#endif
void test_core_path__10_fromurl(void)
{
/* Failing cases */
check_fromurl(NULL, "a", 1);
check_fromurl(NULL, "http:///c:/Temp%20folder/note.txt", 1);
check_fromurl(NULL, "file://c:/Temp%20folder/note.txt", 1);
check_fromurl(NULL, "file:////c:/Temp%20folder/note.txt", 1);
check_fromurl(NULL, "file:///", 1);
check_fromurl(NULL, "file:////", 1);
check_fromurl(NULL, "file://servername/c:/Temp%20folder/note.txt", 1);
/* Passing cases */
check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file:///c:/Temp%20folder/note.txt", 0);
check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file://localhost/c:/Temp%20folder/note.txt", 0);
check_fromurl(ABS_PATH_MARKER "c:/Temp+folder/note.txt", "file:///c:/Temp+folder/note.txt", 0);
check_fromurl(ABS_PATH_MARKER "a", "file:///a", 0);
}
typedef struct {
int expect_idx;
int cancel_after;
char **expect;
} check_walkup_info;
#define CANCEL_VALUE 1234
static int check_one_walkup_step(void *ref, const char *path)
{
check_walkup_info *info = (check_walkup_info *)ref;
if (!info->cancel_after) {
cl_assert_equal_s(info->expect[info->expect_idx], "[CANCEL]");
return CANCEL_VALUE;
}
info->cancel_after--;
cl_assert(info->expect[info->expect_idx] != NULL);
cl_assert_equal_s(info->expect[info->expect_idx], path);
info->expect_idx++;
return 0;
}
void test_core_path__11_walkup(void)
{
git_buf p = GIT_BUF_INIT;
char *expect[] = {
/* 1 */ "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
/* 2 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
/* 3 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
/* 4 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
/* 5 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
/* 6 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
/* 7 */ "this_is_a_path", "", NULL,
/* 8 */ "this_is_a_path/", "", NULL,
/* 9 */ "///a///b///c///d///e///", "///a///b///c///d///", "///a///b///c///", "///a///b///", "///a///", "///", NULL,
/* 10 */ "a/b/c/", "a/b/", "a/", "", NULL,
/* 11 */ "a/b/c", "a/b/", "a/", "", NULL,
/* 12 */ "a/b/c/", "a/b/", "a/", NULL,
/* 13 */ "", NULL,
/* 14 */ "/", NULL,
/* 15 */ NULL
};
char *root[] = {
/* 1 */ NULL,
/* 2 */ NULL,
/* 3 */ "/",
/* 4 */ "",
/* 5 */ "/a/b",
/* 6 */ "/a/b/",
/* 7 */ NULL,
/* 8 */ NULL,
/* 9 */ NULL,
/* 10 */ NULL,
/* 11 */ NULL,
/* 12 */ "a/",
/* 13 */ NULL,
/* 14 */ NULL,
};
int i, j;
check_walkup_info info;
info.expect = expect;
info.cancel_after = -1;
for (i = 0, j = 0; expect[i] != NULL; i++, j++) {
git_buf_sets(&p, expect[i]);
info.expect_idx = i;
cl_git_pass(
git_path_walk_up(&p, root[j], check_one_walkup_step, &info)
);
cl_assert_equal_s(p.ptr, expect[i]);
cl_assert(expect[info.expect_idx] == NULL);
i = info.expect_idx;
}
git_buf_dispose(&p);
}
void test_core_path__11a_walkup_cancel(void)
{
git_buf p = GIT_BUF_INIT;
int cancel[] = { 3, 2, 1, 0 };
char *expect[] = {
"/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "[CANCEL]", NULL,
"/a/b/c/d/e", "/a/b/c/d/", "[CANCEL]", NULL,
"/a/b/c/d/e", "[CANCEL]", NULL,
"[CANCEL]", NULL,
NULL
};
char *root[] = { NULL, NULL, "/", "", NULL };
int i, j;
check_walkup_info info;
info.expect = expect;
for (i = 0, j = 0; expect[i] != NULL; i++, j++) {
git_buf_sets(&p, expect[i]);
info.cancel_after = cancel[j];
info.expect_idx = i;
cl_assert_equal_i(
CANCEL_VALUE,
git_path_walk_up(&p, root[j], check_one_walkup_step, &info)
);
/* skip to next run of expectations */
while (expect[i] != NULL) i++;
}
git_buf_dispose(&p);
}
void test_core_path__12_offset_to_path_root(void)
{
cl_assert(git_path_root("non/rooted/path") == -1);
cl_assert(git_path_root("/rooted/path") == 0);
#ifdef GIT_WIN32
/* Windows specific tests */
cl_assert(git_path_root("C:non/rooted/path") == -1);
cl_assert(git_path_root("C:/rooted/path") == 2);
cl_assert(git_path_root("//computername/sharefolder/resource") == 14);
cl_assert(git_path_root("//computername/sharefolder") == 14);
cl_assert(git_path_root("//computername") == -1);
#endif
}
#define NON_EXISTING_FILEPATH "i_hope_i_do_not_exist"
void test_core_path__13_cannot_prettify_a_non_existing_file(void)
{
git_buf p = GIT_BUF_INIT;
cl_assert_equal_b(git_path_exists(NON_EXISTING_FILEPATH), false);
cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH, NULL));
cl_assert_equal_i(GIT_ENOTFOUND, git_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL));
git_buf_dispose(&p);
}
void test_core_path__14_apply_relative(void)
{
git_buf p = GIT_BUF_INIT;
cl_git_pass(git_buf_sets(&p, "/this/is/a/base"));
cl_git_pass(git_path_apply_relative(&p, "../test"));
cl_assert_equal_s("/this/is/a/test", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../../the/./end"));
cl_assert_equal_s("/this/is/the/end", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "./of/this/../the/string"));
cl_assert_equal_s("/this/is/the/end/of/the/string", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../../../../../.."));
cl_assert_equal_s("/this/", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../"));
cl_assert_equal_s("/", p.ptr);
cl_git_fail(git_path_apply_relative(&p, "../../.."));
cl_git_pass(git_buf_sets(&p, "d:/another/test"));
cl_git_pass(git_path_apply_relative(&p, "../.."));
cl_assert_equal_s("d:/", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "from/here/to/../and/./back/."));
cl_assert_equal_s("d:/from/here/and/back/", p.ptr);
cl_git_pass(git_buf_sets(&p, "https://my.url.com/test.git"));
cl_git_pass(git_path_apply_relative(&p, "../another.git"));
cl_assert_equal_s("https://my.url.com/another.git", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../full/path/url.patch"));
cl_assert_equal_s("https://my.url.com/full/path/url.patch", p.ptr);
cl_git_pass(git_path_apply_relative(&p, ".."));
cl_assert_equal_s("https://my.url.com/full/path/", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../../../"));
cl_assert_equal_s("https://", p.ptr);
cl_git_pass(git_buf_sets(&p, "../../this/is/relative"));
cl_git_pass(git_path_apply_relative(&p, "../../preserves/the/prefix"));
cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../../../../that"));
cl_assert_equal_s("../../that", p.ptr);
cl_git_pass(git_path_apply_relative(&p, "../there"));
cl_assert_equal_s("../../there", p.ptr);
git_buf_dispose(&p);
}
static void assert_resolve_relative(
git_buf *buf, const char *expected, const char *path)
{
cl_git_pass(git_buf_sets(buf, path));
cl_git_pass(git_path_resolve_relative(buf, 0));
cl_assert_equal_s(expected, buf->ptr);
}
void test_core_path__15_resolve_relative(void)
{
git_buf buf = GIT_BUF_INIT;
assert_resolve_relative(&buf, "", "");
assert_resolve_relative(&buf, "", ".");
assert_resolve_relative(&buf, "", "./");
assert_resolve_relative(&buf, "..", "..");
assert_resolve_relative(&buf, "../", "../");
assert_resolve_relative(&buf, "..", "./..");
assert_resolve_relative(&buf, "../", "./../");
assert_resolve_relative(&buf, "../", "../.");
assert_resolve_relative(&buf, "../", ".././");
assert_resolve_relative(&buf, "../..", "../..");
assert_resolve_relative(&buf, "../../", "../../");
assert_resolve_relative(&buf, "/", "/");
assert_resolve_relative(&buf, "/", "/.");
assert_resolve_relative(&buf, "", "a/..");
assert_resolve_relative(&buf, "", "a/../");
assert_resolve_relative(&buf, "", "a/../.");
assert_resolve_relative(&buf, "/a", "/a");
assert_resolve_relative(&buf, "/a/", "/a/.");
assert_resolve_relative(&buf, "/", "/a/../");
assert_resolve_relative(&buf, "/", "/a/../.");
assert_resolve_relative(&buf, "/", "/a/.././");
assert_resolve_relative(&buf, "a", "a");
assert_resolve_relative(&buf, "a/", "a/");
assert_resolve_relative(&buf, "a/", "a/.");
assert_resolve_relative(&buf, "a/", "a/./");
assert_resolve_relative(&buf, "a/b", "a//b");
assert_resolve_relative(&buf, "a/b/c", "a/b/c");
assert_resolve_relative(&buf, "b/c", "./b/c");
assert_resolve_relative(&buf, "a/c", "a/./c");
assert_resolve_relative(&buf, "a/b/", "a/b/.");
assert_resolve_relative(&buf, "/a/b/c", "///a/b/c");
assert_resolve_relative(&buf, "/", "////");
assert_resolve_relative(&buf, "/a", "///a");
assert_resolve_relative(&buf, "/", "///.");
assert_resolve_relative(&buf, "/", "///a/..");
assert_resolve_relative(&buf, "../../path", "../../test//../././path");
assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d");
cl_git_pass(git_buf_sets(&buf, "/.."));
cl_git_fail(git_path_resolve_relative(&buf, 0));
cl_git_pass(git_buf_sets(&buf, "/./.."));
cl_git_fail(git_path_resolve_relative(&buf, 0));
cl_git_pass(git_buf_sets(&buf, "/.//.."));
cl_git_fail(git_path_resolve_relative(&buf, 0));
cl_git_pass(git_buf_sets(&buf, "/../."));
cl_git_fail(git_path_resolve_relative(&buf, 0));
cl_git_pass(git_buf_sets(&buf, "/../.././../a"));
cl_git_fail(git_path_resolve_relative(&buf, 0));
cl_git_pass(git_buf_sets(&buf, "////.."));
cl_git_fail(git_path_resolve_relative(&buf, 0));
/* things that start with Windows network paths */
#ifdef GIT_WIN32
assert_resolve_relative(&buf, "//a/b/c", "//a/b/c");
assert_resolve_relative(&buf, "//a/", "//a/b/..");
assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c");
cl_git_pass(git_buf_sets(&buf, "//a/b/../.."));
cl_git_fail(git_path_resolve_relative(&buf, 0));
#else
assert_resolve_relative(&buf, "/a/b/c", "//a/b/c");
assert_resolve_relative(&buf, "/a/", "//a/b/..");
assert_resolve_relative(&buf, "/a/b/c", "//a/Q/../b/x/y/../../c");
assert_resolve_relative(&buf, "/", "//a/b/../..");
#endif
git_buf_dispose(&buf);
}
#define assert_common_dirlen(i, p, q) \
cl_assert_equal_i((i), git_path_common_dirlen((p), (q)));
void test_core_path__16_resolve_relative(void)
{
assert_common_dirlen(0, "", "");
assert_common_dirlen(0, "", "bar.txt");
assert_common_dirlen(0, "foo.txt", "bar.txt");
assert_common_dirlen(0, "foo.txt", "");
assert_common_dirlen(0, "foo/bar.txt", "bar/foo.txt");
assert_common_dirlen(0, "foo/bar.txt", "../foo.txt");
assert_common_dirlen(1, "/one.txt", "/two.txt");
assert_common_dirlen(4, "foo/one.txt", "foo/two.txt");
assert_common_dirlen(5, "/foo/one.txt", "/foo/two.txt");
assert_common_dirlen(6, "a/b/c/foo.txt", "a/b/c/d/e/bar.txt");
assert_common_dirlen(7, "/a/b/c/foo.txt", "/a/b/c/d/e/bar.txt");
}
void test_core_path__git_path_is_file(void)
{
cl_git_fail(git_path_is_gitfile("blob", 4, -1, GIT_PATH_FS_HFS));
cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITIGNORE, GIT_PATH_FS_HFS));
cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS));
cl_git_pass(git_path_is_gitfile("blob", 4, GIT_PATH_GITFILE_GITATTRIBUTES, GIT_PATH_FS_HFS));
cl_git_fail(git_path_is_gitfile("blob", 4, 3, GIT_PATH_FS_HFS));
}

View File

@@ -1,120 +0,0 @@
#include "clar_libgit2.h"
#include "futils.h"
static const char *empty_tmp_dir = "test_gitfo_rmdir_recurs_test";
void test_core_rmdir__initialize(void)
{
git_buf path = GIT_BUF_INIT;
cl_must_pass(p_mkdir(empty_tmp_dir, 0777));
cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one"));
cl_must_pass(p_mkdir(path.ptr, 0777));
cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_one"));
cl_must_pass(p_mkdir(path.ptr, 0777));
cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_two"));
cl_must_pass(p_mkdir(path.ptr, 0777));
cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one/two_two/three"));
cl_must_pass(p_mkdir(path.ptr, 0777));
cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/two"));
cl_must_pass(p_mkdir(path.ptr, 0777));
git_buf_dispose(&path);
}
void test_core_rmdir__cleanup(void)
{
if (git_path_exists(empty_tmp_dir))
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES));
}
/* make sure empty dir can be deleted recusively */
void test_core_rmdir__delete_recursive(void)
{
git_buf path = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&path, empty_tmp_dir, "/one"));
cl_assert(git_path_exists(git_buf_cstr(&path)));
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
cl_assert(!git_path_exists(git_buf_cstr(&path)));
git_buf_dispose(&path);
}
/* make sure non-empty dir cannot be deleted recusively */
void test_core_rmdir__fail_to_delete_non_empty_dir(void)
{
git_buf file = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&file, empty_tmp_dir, "/two/file.txt"));
cl_git_mkfile(git_buf_cstr(&file), "dummy");
cl_git_fail(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
cl_must_pass(p_unlink(file.ptr));
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
cl_assert(!git_path_exists(empty_tmp_dir));
git_buf_dispose(&file);
}
void test_core_rmdir__keep_base(void)
{
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_ROOT));
cl_assert(git_path_exists(empty_tmp_dir));
}
void test_core_rmdir__can_skip_non_empty_dir(void)
{
git_buf file = GIT_BUF_INIT;
cl_git_pass(git_buf_joinpath(&file, empty_tmp_dir, "/two/file.txt"));
cl_git_mkfile(git_buf_cstr(&file), "dummy");
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_SKIP_NONEMPTY));
cl_assert(git_path_exists(git_buf_cstr(&file)) == true);
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_REMOVE_FILES));
cl_assert(git_path_exists(empty_tmp_dir) == false);
git_buf_dispose(&file);
}
void test_core_rmdir__can_remove_empty_parents(void)
{
git_buf file = GIT_BUF_INIT;
cl_git_pass(
git_buf_joinpath(&file, empty_tmp_dir, "/one/two_two/three/file.txt"));
cl_git_mkfile(git_buf_cstr(&file), "dummy");
cl_assert(git_path_isfile(git_buf_cstr(&file)));
cl_git_pass(git_futils_rmdir_r("one/two_two/three/file.txt", empty_tmp_dir,
GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_EMPTY_PARENTS));
cl_assert(!git_path_exists(git_buf_cstr(&file)));
git_buf_rtruncate_at_char(&file, '/'); /* three (only contained file.txt) */
cl_assert(!git_path_exists(git_buf_cstr(&file)));
git_buf_rtruncate_at_char(&file, '/'); /* two_two (only contained three) */
cl_assert(!git_path_exists(git_buf_cstr(&file)));
git_buf_rtruncate_at_char(&file, '/'); /* one (contained two_one also) */
cl_assert(git_path_exists(git_buf_cstr(&file)));
cl_assert(git_path_exists(empty_tmp_dir) == true);
git_buf_dispose(&file);
cl_git_pass(git_futils_rmdir_r(empty_tmp_dir, NULL, GIT_RMDIR_EMPTY_HIERARCHY));
}

View File

@@ -1,64 +0,0 @@
#include "clar_libgit2.h"
#include "hash.h"
#define FIXTURE_DIR "sha1"
void test_core_sha1__initialize(void)
{
cl_fixture_sandbox(FIXTURE_DIR);
}
void test_core_sha1__cleanup(void)
{
cl_fixture_cleanup(FIXTURE_DIR);
}
static int sha1_file(git_oid *oid, const char *filename)
{
git_hash_ctx ctx;
char buf[2048];
int fd, ret;
ssize_t read_len;
fd = p_open(filename, O_RDONLY);
cl_assert(fd >= 0);
cl_git_pass(git_hash_ctx_init(&ctx));
while ((read_len = p_read(fd, buf, 2048)) > 0)
cl_git_pass(git_hash_update(&ctx, buf, (size_t)read_len));
cl_assert_equal_i(0, read_len);
p_close(fd);
ret = git_hash_final(oid, &ctx);
git_hash_ctx_cleanup(&ctx);
return ret;
}
void test_core_sha1__sum(void)
{
git_oid oid, expected;
cl_git_pass(sha1_file(&oid, FIXTURE_DIR "/hello_c"));
git_oid_fromstr(&expected, "4e72679e3ea4d04e0c642f029e61eb8056c7ed94");
cl_assert_equal_oid(&expected, &oid);
}
/* test that sha1 collision detection works when enabled */
void test_core_sha1__detect_collision_attack(void)
{
git_oid oid, expected;
#ifdef GIT_SHA1_COLLISIONDETECT
GIT_UNUSED(expected);
cl_git_fail(sha1_file(&oid, FIXTURE_DIR "/shattered-1.pdf"));
cl_assert_equal_s("SHA1 collision attack detected", git_error_last()->message);
#else
cl_git_pass(sha1_file(&oid, FIXTURE_DIR "/shattered-1.pdf"));
git_oid_fromstr(&expected, "38762cf7f55934b34d179ae6a4c80cadccbb7f0a");
cl_assert_equal_oid(&expected, &oid);
#endif
}

View File

@@ -1,15 +0,0 @@
#include "clar_libgit2.h"
#include "util.h"
void test_date_date__overflow(void)
{
#ifdef __LP64__
git_time_t d2038, d2039;
/* This is expected to fail on a 32-bit machine. */
cl_git_pass(git__date_parse(&d2038, "2038-1-1"));
cl_git_pass(git__date_parse(&d2039, "2039-1-1"));
cl_assert(d2038 < d2039);
#endif
}

View File

@@ -1,40 +0,0 @@
#include "clar_libgit2.h"
#include "util.h"
void test_date_rfc2822__format_rfc2822_no_offset(void)
{
git_time t = {1397031663, 0};
char buf[GIT_DATE_RFC2822_SZ];
cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
cl_assert(strcmp(buf, "Wed, 9 Apr 2014 08:21:03 +0000") == 0);
}
void test_date_rfc2822__format_rfc2822_positive_offset(void)
{
git_time t = {1397031663, 120};
char buf[GIT_DATE_RFC2822_SZ];
cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
cl_assert(strcmp(buf, "Wed, 9 Apr 2014 10:21:03 +0200") == 0);
}
void test_date_rfc2822__format_rfc2822_negative_offset(void)
{
git_time t = {1397031663, -120};
char buf[GIT_DATE_RFC2822_SZ];
cl_git_pass(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
cl_assert(strcmp(buf, "Wed, 9 Apr 2014 06:21:03 -0200") == 0);
}
void test_date_rfc2822__format_rfc2822_buffer_too_small(void)
{
/* "Wed, 10 Apr 2014 08:21:03 +0000" */
git_time t = {1397031663 + 86400, 0};
char buf[GIT_DATE_RFC2822_SZ-1];
cl_git_fail(git__date_rfc2822_fmt(buf, sizeof(buf), &t));
}

View File

@@ -0,0 +1,14 @@
# Header file validation project: ensure that we do not publish any sloppy
# definitions in our headers and that a consumer can include <git2.dll>
# even when they have aggressive C90 warnings enabled.
add_executable(headertest headertest.c)
set_target_properties(headertest PROPERTIES C_STANDARD 90)
set_target_properties(headertest PROPERTIES C_EXTENSIONS OFF)
target_include_directories(headertest PRIVATE ${LIBGIT2_INCLUDES})
if (MSVC)
target_compile_options(headertest PUBLIC /W4 /WX)
else()
target_compile_options(headertest PUBLIC -Wall -Wextra -pedantic -Werror)
endif()

View File

@@ -0,0 +1,13 @@
/*
* Dummy project to validate header files
*
* This project is not intended to be executed, it should only include all
* header files to make sure that they can be used with stricter compiler
* settings than the libgit2 source files generally supports.
*/
#include "git2.h"
int main(void)
{
return 0;
}

View File

@@ -0,0 +1,77 @@
# tests: the unit and integration tests for libgit2
set(Python_ADDITIONAL_VERSIONS 3 2.7)
find_package(PythonInterp)
if(NOT PYTHONINTERP_FOUND)
message(FATAL_ERROR "Could not find a python interpreter, which is needed to build the tests. "
"Make sure python is available, or pass -DBUILD_TESTS=OFF to skip building the tests")
ENDIF()
set(CLAR_PATH "${PROJECT_SOURCE_DIR}/tests/clar")
set(CLAR_FIXTURES "${PROJECT_SOURCE_DIR}/tests/resources/")
set(TEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
add_definitions(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
add_definitions(-DCLAR_TMPDIR=\"libgit2_tests\")
add_definitions(-DCLAR_WIN32_LONGPATHS)
add_definitions(-D_FILE_OFFSET_BITS=64)
# Ensure that we do not use deprecated functions internally
add_definitions(-DGIT_DEPRECATE_HARD)
set(TEST_INCLUDES "${CLAR_PATH}" "${TEST_PATH}" "${CMAKE_CURRENT_BINARY_DIR}")
file(GLOB_RECURSE SRC_TEST ${TEST_PATH}/*/*.c ${TEST_PATH}/*/*.h)
file(GLOB_RECURSE SRC_CLAR ${CLAR_PATH}/*.c ${CLAR_PATH}/*.h)
if(MSVC_IDE)
list(APPEND SRC_TEST "precompiled.c")
endif()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clar.suite ${CMAKE_CURRENT_BINARY_DIR}/clar_suite.h
COMMAND ${PYTHON_EXECUTABLE} ${CLAR_PATH}/generate.py -o "${CMAKE_CURRENT_BINARY_DIR}" -f -xonline -xstress -xperf .
DEPENDS ${SRC_TEST}
WORKING_DIRECTORY ${TEST_PATH}
)
set_source_files_properties(
${CLAR_PATH}/clar.c
PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite)
add_executable(libgit2_tests ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS})
set_target_properties(libgit2_tests PROPERTIES C_STANDARD 90)
set_target_properties(libgit2_tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
target_include_directories(libgit2_tests PRIVATE ${TEST_INCLUDES} ${LIBGIT2_INCLUDES} ${LIBGIT2_DEPENDENCY_INCLUDES})
target_include_directories(libgit2_tests SYSTEM PRIVATE ${LIBGIT2_SYSTEM_INCLUDES})
target_link_libraries(libgit2_tests ${LIBGIT2_SYSTEM_LIBS})
ide_split_sources(libgit2_tests)
#
# Old versions of gcc require us to declare our test functions; don't do
# this on newer compilers to avoid unnecessary recompilation.
#
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
target_compile_options(libgit2_tests PRIVATE -include "clar_suite.h")
endif()
if(MSVC_IDE)
# Precompiled headers
set_target_properties(libgit2_tests PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h")
set_source_files_properties("precompiled.c" COMPILE_FLAGS "/Ycprecompiled.h")
endif()
include(AddClarTest)
add_clar_test(libgit2_tests offline -v -xonline)
add_clar_test(libgit2_tests invasive -v -sfilter::stream::bigfile -sodb::largefiles -siterator::workdir::filesystem_gunk -srepo::init -srepo::init::at_filesystem_root -sonline::clone::connect_timeout_default)
add_clar_test(libgit2_tests online -v -sonline -xonline::customcert)
add_clar_test(libgit2_tests online_customcert -v -sonline::customcert)
add_clar_test(libgit2_tests gitdaemon -v -sonline::push)
add_clar_test(libgit2_tests gitdaemon_namespace -v -sonline::clone::namespace)
add_clar_test(libgit2_tests gitdaemon_sha256 -v -sonline::clone::sha256)
add_clar_test(libgit2_tests ssh -v -sonline::push -sonline::clone::ssh_cert -sonline::clone::ssh_with_paths -sonline::clone::path_whitespace_ssh -sonline::clone::ssh_auth_methods)
add_clar_test(libgit2_tests proxy -v -sonline::clone::proxy)
add_clar_test(libgit2_tests auth_clone -v -sonline::clone::cred)
add_clar_test(libgit2_tests auth_clone_and_push -v -sonline::clone::push -sonline::push)

View File

@@ -14,7 +14,7 @@ static int iterator_compare(const git_index_entry *entry, void *_data)
struct iterator_compare_data *data = (struct iterator_compare_data *)_data;
cl_assert_equal_i(GIT_INDEX_ENTRY_STAGE(entry), data->expected[data->idx].stage);
cl_git_pass(git_oid_fromstr(&expected_id, data->expected[data->idx].oid_str));
cl_git_pass(git_oid__fromstr(&expected_id, data->expected[data->idx].oid_str, GIT_OID_SHA1));
cl_assert_equal_oid(&entry->id, &expected_id);
cl_assert_equal_i(entry->mode, data->expected[data->idx].mode);
cl_assert_equal_s(entry->path, data->expected[data->idx].path);

View File

@@ -1,4 +1,5 @@
#include "../merge/merge_helpers.h"
#include "../diff/diff_helpers.h"
#define TEST_REPO_PATH "merge-recursive"
@@ -474,6 +475,15 @@
"-asparagus which had been laid by, boil it until these last articles are\n" \
"-sufficiently done, thicken with flour, butter and milk, and serve it up.\n"
#define DIFF_ADD_INVALID_FILENAME \
"diff --git a/.git/hello_world.txt b/.git/hello_world.txt\n" \
"new file mode 100644\n" \
"index 0000000..f75ba05\n" \
"--- /dev/null\n" \
"+++ b/.git/hello_world.txt\n" \
"@@ -0,0 +1 @@\n" \
"+Hello, world.\n"
void validate_apply_workdir(
git_repository *repo,
struct merge_index_entry *workdir_entries,

View File

@@ -12,7 +12,7 @@ void test_apply_both__initialize(void)
repo = cl_git_sandbox_init(TEST_REPO_PATH);
git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &oid));
cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
git_commit_free(commit);
@@ -42,8 +42,8 @@ void test_apply_both__generated_diff(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f");
git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid));
@@ -78,7 +78,7 @@ void test_apply_both__parsed_diff(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -102,7 +102,7 @@ void test_apply_both__removes_file(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_FILE,
strlen(DIFF_DELETE_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -128,7 +128,7 @@ void test_apply_both__adds_file(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_ADD_FILE, strlen(DIFF_ADD_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -161,7 +161,7 @@ void test_apply_both__application_failure_leaves_index_unmodified(void)
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -192,13 +192,13 @@ void test_apply_both__index_must_match_workdir(void)
memset(&idx_entry, 0, sizeof(git_index_entry));
idx_entry.mode = 0100644;
idx_entry.path = "asparagus.txt";
cl_git_pass(git_oid_fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538"));
cl_git_pass(git_oid__fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538", GIT_OID_SHA1));
cl_git_pass(git_index_add(index, &idx_entry));
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
git_diff_free(diff);
@@ -214,7 +214,7 @@ void test_apply_both__index_mode_must_match_workdir(void)
/* Set a file in the working directory executable. */
cl_must_pass(p_chmod("merge-recursive/asparagus.txt", 0755));
cl_git_pass(git_diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES,
cl_git_pass(diff_from_buffer(&diff, DIFF_MODIFY_TWO_FILES,
strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -248,7 +248,7 @@ void test_apply_both__application_failure_leaves_workdir_unmodified(void)
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
validate_apply_workdir(repo, workdir_expected, workdir_expected_cnt);
@@ -290,7 +290,7 @@ void test_apply_both__keeps_nonconflicting_changes(void)
memset(&idx_entry, 0, sizeof(git_index_entry));
idx_entry.mode = 0100644;
idx_entry.path = "beef.txt";
cl_git_pass(git_oid_fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e"));
cl_git_pass(git_oid__fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e", GIT_OID_SHA1));
cl_git_pass(git_index_add(index, &idx_entry));
cl_git_pass(git_index_remove(index, "bouilli.txt", 0));
@@ -301,7 +301,7 @@ void test_apply_both__keeps_nonconflicting_changes(void)
cl_git_rmfile("merge-recursive/oyster.txt");
cl_git_rewritefile("merge-recursive/gravy.txt", "Hello, world.\n");
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -341,7 +341,7 @@ void test_apply_both__can_apply_nonconflicting_file_changes(void)
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
validate_apply_index(repo, both_expected, both_expected_cnt);
@@ -386,12 +386,12 @@ void test_apply_both__honors_crlf_attributes(void)
cl_git_rmfile("merge-recursive/asparagus.txt");
cl_git_rmfile("merge-recursive/veal.txt");
git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &oid));
cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
git_commit_free(commit);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -415,7 +415,7 @@ void test_apply_both__rename(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_FILE,
strlen(DIFF_RENAME_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -440,7 +440,7 @@ void test_apply_both__rename_and_modify(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_FILE,
strlen(DIFF_RENAME_AND_MODIFY_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -465,7 +465,7 @@ void test_apply_both__rename_a_to_b_to_c(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C,
strlen(DIFF_RENAME_A_TO_B_TO_C)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -490,7 +490,7 @@ void test_apply_both__rename_a_to_b_to_c_exact(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C_EXACT,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_A_TO_B_TO_C_EXACT,
strlen(DIFF_RENAME_A_TO_B_TO_C_EXACT)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -515,7 +515,7 @@ void test_apply_both__rename_circular(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_CIRCULAR,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_CIRCULAR,
strlen(DIFF_RENAME_CIRCULAR)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -539,7 +539,7 @@ void test_apply_both__rename_2_to_1(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_2_TO_1,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_2_TO_1,
strlen(DIFF_RENAME_2_TO_1)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -565,7 +565,7 @@ void test_apply_both__rename_1_to_2(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_1_TO_2,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_1_TO_2,
strlen(DIFF_RENAME_1_TO_2)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -590,7 +590,7 @@ void test_apply_both__two_deltas_one_file(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_FILE,
strlen(DIFF_TWO_DELTAS_ONE_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -616,7 +616,7 @@ void test_apply_both__two_deltas_one_new_file(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_NEW_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_TWO_DELTAS_ONE_NEW_FILE,
strlen(DIFF_TWO_DELTAS_ONE_NEW_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -641,7 +641,7 @@ void test_apply_both__rename_and_modify_deltas(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_DELTAS,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_DELTAS,
strlen(DIFF_RENAME_AND_MODIFY_DELTAS)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -667,7 +667,7 @@ void test_apply_both__rename_delta_after_modify_delta(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY,
strlen(DIFF_RENAME_AFTER_MODIFY)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -681,7 +681,7 @@ void test_apply_both__cant_rename_after_modify_nonexistent_target_path(void)
{
git_diff *diff;
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY_TARGET_PATH,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AFTER_MODIFY_TARGET_PATH,
strlen(DIFF_RENAME_AFTER_MODIFY_TARGET_PATH)));
cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -692,7 +692,7 @@ void test_apply_both__cant_modify_source_path_after_rename(void)
{
git_diff *diff;
cl_git_pass(git_diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_SOURCE_PATH,
cl_git_pass(diff_from_buffer(&diff, DIFF_RENAME_AND_MODIFY_SOURCE_PATH,
strlen(DIFF_RENAME_AND_MODIFY_SOURCE_PATH)));
cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -714,7 +714,7 @@ void test_apply_both__readd_deleted_file(void)
size_t both_expected_cnt = sizeof(both_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_AND_READD_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_AND_READD_FILE,
strlen(DIFF_DELETE_AND_READD_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
@@ -728,9 +728,20 @@ void test_apply_both__cant_remove_file_twice(void)
{
git_diff *diff;
cl_git_pass(git_diff_from_buffer(&diff, DIFF_REMOVE_FILE_TWICE,
cl_git_pass(diff_from_buffer(&diff, DIFF_REMOVE_FILE_TWICE,
strlen(DIFF_REMOVE_FILE_TWICE)));
cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
git_diff_free(diff);
}
void test_apply_both__cant_add_invalid_filename(void)
{
git_diff *diff;
cl_git_pass(diff_from_buffer(&diff, DIFF_ADD_INVALID_FILENAME,
strlen(DIFF_ADD_INVALID_FILENAME)));
cl_git_fail(git_apply(repo, diff, GIT_APPLY_LOCATION_BOTH, NULL));
git_diff_free(diff);
}

View File

@@ -12,7 +12,7 @@ void test_apply_callbacks__initialize(void)
repo = cl_git_sandbox_init(TEST_REPO_PATH);
git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &oid));
cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
git_commit_free(commit);
@@ -40,7 +40,7 @@ void test_apply_callbacks__delta_aborts(void)
opts.delta_cb = delta_abort_cb;
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_fail_with(-99,
git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts));
@@ -79,7 +79,7 @@ void test_apply_callbacks__delta_can_skip(void)
opts.delta_cb = delta_skip_cb;
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts));
@@ -117,7 +117,7 @@ void test_apply_callbacks__hunk_can_skip(void)
opts.hunk_cb = hunk_skip_odds_cb;
opts.payload = &count;
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MANY_CHANGES_ONE, strlen(DIFF_MANY_CHANGES_ONE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts));

View File

@@ -12,7 +12,7 @@ void test_apply_check__initialize(void)
repo = cl_git_sandbox_init(TEST_REPO_PATH);
git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &oid));
cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
git_commit_free(commit);
@@ -32,8 +32,8 @@ void test_apply_check__generate_diff(void)
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
cl_git_pass(git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707"));
cl_git_pass(git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"));
cl_git_pass(git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1));
cl_git_pass(git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid));
@@ -60,7 +60,7 @@ void test_apply_check__parsed_diff(void)
git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
opts.flags |= GIT_APPLY_CHECK;
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts));
@@ -76,7 +76,7 @@ void test_apply_check__binary(void)
git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
opts.flags |= GIT_APPLY_CHECK;
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES_BINARY,
strlen(DIFF_MODIFY_TWO_FILES_BINARY)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts));
@@ -112,7 +112,7 @@ void test_apply_check__does_not_apply(void)
git_index_free(index);
opts.flags |= GIT_APPLY_CHECK;
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, &opts));
validate_apply_index(repo, index_expected, index_expected_cnt);

View File

@@ -3,7 +3,6 @@
#include "apply.h"
#include "repository.h"
#include "buf_text.h"
#include "../patch/patch_common.h"
@@ -23,15 +22,15 @@ void test_apply_fromdiff__cleanup(void)
}
static int apply_gitbuf(
const git_buf *old,
const git_str *old,
const char *oldname,
const git_buf *new,
const git_str *new,
const char *newname,
const char *patch_expected,
const git_diff_options *diff_opts)
{
git_patch *patch;
git_buf result = GIT_BUF_INIT;
git_str result = GIT_STR_INIT;
git_buf patchbuf = GIT_BUF_INIT;
char *filename;
unsigned int mode;
@@ -63,7 +62,7 @@ static int apply_gitbuf(
}
git__free(filename);
git_buf_dispose(&result);
git_str_dispose(&result);
git_buf_dispose(&patchbuf);
git_patch_free(patch);
@@ -78,7 +77,7 @@ static int apply_buf(
const char *patch_expected,
const git_diff_options *diff_opts)
{
git_buf o = GIT_BUF_INIT, n = GIT_BUF_INIT,
git_str o = GIT_STR_INIT, n = GIT_STR_INIT,
*optr = NULL, *nptr = NULL;
if (old) {
@@ -276,7 +275,7 @@ void test_apply_fromdiff__no_change(void)
void test_apply_fromdiff__binary_add(void)
{
git_buf newfile = GIT_BUF_INIT;
git_str newfile = GIT_STR_INIT;
newfile.ptr = FILE_BINARY_DELTA_MODIFIED;
newfile.size = FILE_BINARY_DELTA_MODIFIED_LEN;
@@ -289,7 +288,7 @@ void test_apply_fromdiff__binary_add(void)
void test_apply_fromdiff__binary_no_change(void)
{
git_buf original = GIT_BUF_INIT;
git_str original = GIT_STR_INIT;
original.ptr = FILE_BINARY_DELTA_ORIGINAL;
original.size = FILE_BINARY_DELTA_ORIGINAL_LEN;
@@ -302,7 +301,7 @@ void test_apply_fromdiff__binary_no_change(void)
void test_apply_fromdiff__binary_change_delta(void)
{
git_buf original = GIT_BUF_INIT, modified = GIT_BUF_INIT;
git_str original = GIT_STR_INIT, modified = GIT_STR_INIT;
original.ptr = FILE_BINARY_DELTA_ORIGINAL;
original.size = FILE_BINARY_DELTA_ORIGINAL_LEN;
@@ -318,7 +317,7 @@ void test_apply_fromdiff__binary_change_delta(void)
void test_apply_fromdiff__binary_change_literal(void)
{
git_buf original = GIT_BUF_INIT, modified = GIT_BUF_INIT;
git_str original = GIT_STR_INIT, modified = GIT_STR_INIT;
original.ptr = FILE_BINARY_LITERAL_ORIGINAL;
original.size = FILE_BINARY_LITERAL_ORIGINAL_LEN;
@@ -334,7 +333,7 @@ void test_apply_fromdiff__binary_change_literal(void)
void test_apply_fromdiff__binary_delete(void)
{
git_buf original = GIT_BUF_INIT;
git_str original = GIT_STR_INIT;
original.ptr = FILE_BINARY_DELTA_MODIFIED;
original.size = FILE_BINARY_DELTA_MODIFIED_LEN;
@@ -347,7 +346,7 @@ void test_apply_fromdiff__binary_delete(void)
void test_apply_fromdiff__patching_correctly_truncates_source(void)
{
git_buf original = GIT_BUF_INIT, patched = GIT_BUF_INIT;
git_str original = GIT_STR_INIT, patched = GIT_STR_INIT;
git_patch *patch;
unsigned int mode;
char *path;
@@ -372,8 +371,8 @@ void test_apply_fromdiff__patching_correctly_truncates_source(void)
cl_git_pass(git_apply__patch(&patched, &path, &mode,
"foo\nbar\n", 7, patch, NULL));
git_buf_dispose(&original);
git_buf_dispose(&patched);
git_str_dispose(&original);
git_str_dispose(&patched);
git_patch_free(patch);
git__free(path);
}

View File

@@ -5,7 +5,6 @@
#include "patch.h"
#include "patch_parse.h"
#include "repository.h"
#include "buf_text.h"
#include "../patch/patch_common.h"
@@ -31,8 +30,8 @@ static int apply_patchfile(
unsigned int mode_expected)
{
git_patch *patch;
git_buf result = GIT_BUF_INIT;
git_buf patchbuf = GIT_BUF_INIT;
git_str result = GIT_STR_INIT;
git_str patchbuf = GIT_STR_INIT;
char *filename;
unsigned int mode;
int error;
@@ -51,8 +50,8 @@ static int apply_patchfile(
}
git__free(filename);
git_buf_dispose(&result);
git_buf_dispose(&patchbuf);
git_str_dispose(&result);
git_str_dispose(&patchbuf);
git_patch_free(patch);
return error;

View File

@@ -12,7 +12,7 @@ void test_apply_index__initialize(void)
repo = cl_git_sandbox_init(TEST_REPO_PATH);
git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &oid));
cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
git_commit_free(commit);
@@ -42,8 +42,8 @@ void test_apply_index__generate_diff(void)
size_t index_expected_cnt = sizeof(index_expected) /
sizeof(struct merge_index_entry);
git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f");
git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid));
@@ -78,7 +78,7 @@ void test_apply_index__parsed_diff(void)
size_t index_expected_cnt = sizeof(index_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
@@ -102,7 +102,7 @@ void test_apply_index__removes_file(void)
size_t index_expected_cnt = sizeof(index_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_FILE,
strlen(DIFF_DELETE_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
@@ -128,7 +128,7 @@ void test_apply_index__adds_file(void)
size_t index_expected_cnt = sizeof(index_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_ADD_FILE, strlen(DIFF_ADD_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
@@ -169,7 +169,7 @@ void test_apply_index__modified_workdir_with_unmodified_index_is_ok(void)
cl_git_rmfile("merge-recursive/asparagus.txt");
cl_git_rewritefile("merge-recursive/veal.txt", "Hello, world.\n");
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -201,7 +201,7 @@ void test_apply_index__application_failure_leaves_index_unmodified(void)
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -233,14 +233,14 @@ void test_apply_index__keeps_nonconflicting_changes(void)
memset(&idx_entry, 0, sizeof(git_index_entry));
idx_entry.mode = 0100644;
idx_entry.path = "beef.txt";
cl_git_pass(git_oid_fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e"));
cl_git_pass(git_oid__fromstr(&idx_entry.id, "898d12687fb35be271c27c795a6b32c8b51da79e", GIT_OID_SHA1));
cl_git_pass(git_index_add(index, &idx_entry));
cl_git_pass(git_index_remove(index, "bouilli.txt", 0));
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -279,13 +279,13 @@ void test_apply_index__can_apply_nonconflicting_file_changes(void)
memset(&idx_entry, 0, sizeof(git_index_entry));
idx_entry.mode = 0100644;
idx_entry.path = "asparagus.txt";
cl_git_pass(git_oid_fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538"));
cl_git_pass(git_oid__fromstr(&idx_entry.id, "06d3fefb8726ab1099acc76e02dfb85e034b2538", GIT_OID_SHA1));
cl_git_pass(git_index_add(index, &idx_entry));
cl_git_pass(git_index_write(index));
git_index_free(index);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -311,7 +311,7 @@ void test_apply_index__change_mode(void)
size_t index_expected_cnt = sizeof(index_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_INDEX, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);

View File

@@ -3,7 +3,6 @@
#include "apply.h"
#include "repository.h"
#include "buf_text.h"
#include "../patch/patch_common.h"
@@ -84,8 +83,8 @@ static int apply_buf(
void *payload)
{
git_patch *patch;
git_buf result = GIT_BUF_INIT;
git_buf patchbuf = GIT_BUF_INIT;
git_str result = GIT_STR_INIT;
git_str patchbuf = GIT_STR_INIT;
git_apply_options opts = GIT_APPLY_OPTIONS_INIT;
char *filename;
unsigned int mode;
@@ -104,8 +103,8 @@ static int apply_buf(
}
git__free(filename);
git_buf_dispose(&result);
git_buf_dispose(&patchbuf);
git_str_dispose(&result);
git_str_dispose(&patchbuf);
git_patch_free(patch);
return error;

View File

@@ -35,8 +35,8 @@ void test_apply_tree__one(void)
{ 0100644, "a7b066537e6be7109abfe4ff97b675d4e077da20", 0, "veal.txt" },
};
git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f");
git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid));
@@ -75,13 +75,13 @@ void test_apply_tree__adds_file(void)
{ 0100644, "94d2c01087f48213bd157222d54edfefd77c9bba", 0, "veal.txt" },
};
git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
cl_git_pass(git_commit_tree(&a_tree, a_commit));
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_ADD_FILE, strlen(DIFF_ADD_FILE)));
cl_git_pass(git_apply_to_tree(&index, repo, a_tree, diff, NULL));

View File

@@ -12,7 +12,7 @@ void test_apply_workdir__initialize(void)
repo = cl_git_sandbox_init(TEST_REPO_PATH);
git_oid_fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid__fromstr(&oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &oid));
cl_git_pass(git_reset(repo, (git_object *)commit, GIT_RESET_HARD, NULL));
git_commit_free(commit);
@@ -42,8 +42,8 @@ void test_apply_workdir__generated_diff(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
git_oid_fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707");
git_oid_fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f"); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
git_oid__fromstr(&a_oid, "539bd011c4822c560c1d17cab095006b7a10f707", GIT_OID_SHA1);
git_oid__fromstr(&b_oid, "7c7bf85e978f1d18c0566f702d2cb7766b9c8d4f", GIT_OID_SHA1); cl_git_pass(git_commit_lookup(&a_commit, repo, &a_oid));
cl_git_pass(git_commit_lookup(&b_commit, repo, &b_oid));
cl_git_pass(git_commit_tree(&a_tree, a_commit));
@@ -77,7 +77,7 @@ void test_apply_workdir__parsed_diff(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
@@ -101,7 +101,7 @@ void test_apply_workdir__removes_file(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, DIFF_DELETE_FILE,
cl_git_pass(diff_from_buffer(&diff, DIFF_DELETE_FILE,
strlen(DIFF_DELETE_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
@@ -127,7 +127,7 @@ void test_apply_workdir__adds_file(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_ADD_FILE, strlen(DIFF_ADD_FILE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
@@ -171,13 +171,13 @@ void test_apply_workdir__modified_index_with_unmodified_workdir_is_ok(void)
idx_entry.mode = 0100644;
idx_entry.path = "veal.txt";
cl_git_pass(git_oid_fromstr(&idx_entry.id, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d"));
cl_git_pass(git_oid__fromstr(&idx_entry.id, "ffb36e513f5fdf8a6ba850a20142676a2ac4807d", GIT_OID_SHA1));
cl_git_pass(git_index_add(index, &idx_entry));
cl_git_pass(git_index_remove(index, "asparagus.txt", 0));
cl_git_pass(git_index_write(index));
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
validate_apply_index(repo, index_expected, index_expected_cnt);
@@ -208,7 +208,7 @@ void test_apply_workdir__application_failure_leaves_workdir_unmodified(void)
cl_git_rewritefile("merge-recursive/veal.txt",
"This is a modification.\n");
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_fail_with(GIT_EAPPLYFAIL, git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
validate_apply_workdir(repo, workdir_expected, workdir_expected_cnt);
@@ -233,7 +233,7 @@ void test_apply_workdir__keeps_nonconflicting_changes(void)
cl_git_rmfile("merge-recursive/oyster.txt");
cl_git_rewritefile("merge-recursive/gravy.txt", "Hello, world.\n");
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MODIFY_TWO_FILES, strlen(DIFF_MODIFY_TWO_FILES)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
@@ -268,7 +268,7 @@ void test_apply_workdir__can_apply_nonconflicting_file_changes(void)
cl_git_append2file("merge-recursive/asparagus.txt",
"This line is added in the workdir.\n");
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
validate_index_unchanged(repo);
@@ -295,7 +295,7 @@ void test_apply_workdir__change_mode(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(diff_from_buffer(&diff, diff_file, strlen(diff_file)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, NULL));
validate_index_unchanged(repo);
@@ -321,7 +321,7 @@ void test_apply_workdir__apply_many_changes_one(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MANY_CHANGES_ONE, strlen(DIFF_MANY_CHANGES_ONE)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts));
@@ -347,7 +347,7 @@ void test_apply_workdir__apply_many_changes_two(void)
size_t workdir_expected_cnt = sizeof(workdir_expected) /
sizeof(struct merge_index_entry);
cl_git_pass(git_diff_from_buffer(&diff,
cl_git_pass(diff_from_buffer(&diff,
DIFF_MANY_CHANGES_TWO, strlen(DIFF_MANY_CHANGES_TWO)));
cl_git_pass(git_apply(repo, diff, GIT_APPLY_LOCATION_WORKDIR, &opts));

View File

@@ -236,6 +236,7 @@ void test_attr_lookup__check_attr_examples(void)
void test_attr_lookup__from_buffer(void)
{
git_attr_file *file;
git_attr_file_source source = {0};
struct attr_expected cases[] = {
{ "abc", "foo", EXPECT_TRUE, NULL },
@@ -250,7 +251,7 @@ void test_attr_lookup__from_buffer(void)
{ NULL, NULL, 0, NULL }
};
cl_git_pass(git_attr_file__new(&file, NULL, 0));
cl_git_pass(git_attr_file__new(&file, NULL, &source));
cl_git_pass(git_attr_file__parse_buffer(NULL, file, "a* foo\nabc bar\n* baz", true));

View File

@@ -71,11 +71,11 @@ void test_attr_repo__get_one(void)
}
cl_assert(git_attr_cache__is_cached(
g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/attributes"));
g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".git/info/attributes"));
cl_assert(git_attr_cache__is_cached(
g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitattributes"));
g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".gitattributes"));
cl_assert(git_attr_cache__is_cached(
g_repo, GIT_ATTR_FILE__FROM_FILE, "sub/.gitattributes"));
g_repo, GIT_ATTR_FILE_SOURCE_FILE, "sub/.gitattributes"));
}
void test_attr_repo__get_one_start_deep(void)
@@ -92,11 +92,11 @@ void test_attr_repo__get_one_start_deep(void)
}
cl_assert(git_attr_cache__is_cached(
g_repo, GIT_ATTR_FILE__FROM_FILE, ".git/info/attributes"));
g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".git/info/attributes"));
cl_assert(git_attr_cache__is_cached(
g_repo, GIT_ATTR_FILE__FROM_FILE, ".gitattributes"));
g_repo, GIT_ATTR_FILE_SOURCE_FILE, ".gitattributes"));
cl_assert(git_attr_cache__is_cached(
g_repo, GIT_ATTR_FILE__FROM_FILE, "sub/.gitattributes"));
g_repo, GIT_ATTR_FILE_SOURCE_FILE, "sub/.gitattributes"));
}
void test_attr_repo__get_many(void)
@@ -230,12 +230,12 @@ void test_attr_repo__manpage_example(void)
static void add_to_workdir(const char *filename, const char *content)
{
git_buf buf = GIT_BUF_INIT;
git_str buf = GIT_STR_INIT;
cl_git_pass(git_buf_joinpath(&buf, "attr", filename));
cl_git_rewritefile(git_buf_cstr(&buf), content);
cl_git_pass(git_str_joinpath(&buf, "attr", filename));
cl_git_rewritefile(git_str_cstr(&buf), content);
git_buf_dispose(&buf);
git_str_dispose(&buf);
}
static void assert_proper_normalization(git_index *index, const char *filename, const char *expected_sha)
@@ -283,7 +283,7 @@ void test_attr_repo__bare_repo_with_index(void)
git_index_free(index);
cl_must_pass(p_unlink("attr/.gitattributes"));
cl_assert(!git_path_exists("attr/.gitattributes"));
cl_assert(!git_fs_path_exists("attr/.gitattributes"));
cl_git_pass(git_repository_set_bare(g_repo));
@@ -309,14 +309,39 @@ void test_attr_repo__bare_repo_with_index(void)
cl_assert(GIT_ATTR_IS_UNSPECIFIED(values[3]));
}
void test_attr_repo__inmemory_repo_without_index(void)
{
const char *names[1] = { "fake" };
const char *values[1];
git_repository *inmemory;
git_index *index = NULL;
/* setup bare in-memory repo without index */
#ifdef GIT_EXPERIMENTAL_SHA256
cl_git_pass(git_repository_new(&inmemory, GIT_OID_SHA1));
#else
cl_git_pass(git_repository_new(&inmemory));
#endif
cl_assert(git_repository_is_bare(inmemory));
/* verify repo isn't given an index upfront in future */
git_repository_index(&index, inmemory);
cl_assert(!index);
/* check attributes can be queried without error due to missing index */
cl_git_pass(git_attr_get_many(values, inmemory, 0, "fake.txt", 1, names));
git_repository_free(inmemory);
}
void test_attr_repo__sysdir(void)
{
git_buf sysdir = GIT_BUF_INIT;
git_str sysdir = GIT_STR_INIT;
const char *value;
cl_git_pass(p_mkdir("system", 0777));
cl_git_rewritefile("system/gitattributes", "file merge=foo");
cl_git_pass(git_buf_joinpath(&sysdir, clar_sandbox_path(), "system"));
cl_git_pass(git_str_joinpath(&sysdir, clar_sandbox_path(), "system"));
cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, sysdir.ptr));
g_repo = cl_git_sandbox_reopen();
@@ -325,30 +350,30 @@ void test_attr_repo__sysdir(void)
cl_git_pass(p_unlink("system/gitattributes"));
cl_git_pass(p_rmdir("system"));
git_buf_dispose(&sysdir);
git_str_dispose(&sysdir);
}
void test_attr_repo__sysdir_with_session(void)
{
const char *values[2], *attrs[2] = { "foo", "bar" };
git_buf sysdir = GIT_BUF_INIT;
git_str sysdir = GIT_STR_INIT;
git_attr_session session;
cl_git_pass(p_mkdir("system", 0777));
cl_git_rewritefile("system/gitattributes", "file foo=1 bar=2");
cl_git_pass(git_buf_joinpath(&sysdir, clar_sandbox_path(), "system"));
cl_git_pass(git_str_joinpath(&sysdir, clar_sandbox_path(), "system"));
cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, sysdir.ptr));
g_repo = cl_git_sandbox_reopen();
cl_git_pass(git_attr_session__init(&session, g_repo));
cl_git_pass(git_attr_get_many_with_session(values, g_repo, &session, 0, "file", ARRAY_SIZE(attrs), attrs));
cl_git_pass(git_attr_get_many_with_session(values, g_repo, &session, NULL, "file", ARRAY_SIZE(attrs), attrs));
cl_assert_equal_s(values[0], "1");
cl_assert_equal_s(values[1], "2");
cl_git_pass(p_unlink("system/gitattributes"));
cl_git_pass(p_rmdir("system"));
git_buf_dispose(&sysdir);
git_str_dispose(&sysdir);
git_attr_session__free(&session);
}
@@ -371,11 +396,11 @@ void test_attr_repo__rewrite(void)
void test_attr_repo__rewrite_sysdir(void)
{
git_buf sysdir = GIT_BUF_INIT;
git_str sysdir = GIT_STR_INIT;
const char *value;
cl_git_pass(p_mkdir("system", 0777));
cl_git_pass(git_buf_joinpath(&sysdir, clar_sandbox_path(), "system"));
cl_git_pass(git_str_joinpath(&sysdir, clar_sandbox_path(), "system"));
cl_git_pass(git_sysdir_set(GIT_SYSDIR_SYSTEM, sysdir.ptr));
g_repo = cl_git_sandbox_reopen();
@@ -387,7 +412,7 @@ void test_attr_repo__rewrite_sysdir(void)
cl_git_pass(git_attr_get(&value, g_repo, 0, "file", "foo"));
cl_assert_equal_s(value, "second");
git_buf_dispose(&sysdir);
git_str_dispose(&sysdir);
}
void test_attr_repo__unlink(void)

View File

@@ -17,7 +17,7 @@ void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...)
void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx,
size_t start_line, size_t len, char boundary, const char *commit_id, const char *orig_path)
{
char expected[GIT_OID_HEXSZ+1] = {0}, actual[GIT_OID_HEXSZ+1] = {0};
char expected[GIT_OID_SHA1_HEXSIZE+1] = {0}, actual[GIT_OID_SHA1_HEXSIZE+1] = {0};
const git_blame_hunk *hunk = git_blame_get_hunk_byindex(blame, idx);
cl_assert(hunk);
@@ -31,13 +31,13 @@ void check_blame_hunk_index(git_repository *repo, git_blame *blame, int idx,
}
if (hunk->final_start_line_number != start_line) {
hunk_message(idx, hunk, "mismatched start line number: expected %d, got %d",
hunk_message(idx, hunk, "mismatched start line number: expected %"PRIuZ", got %"PRIuZ,
start_line, hunk->final_start_line_number);
}
cl_assert_equal_i(hunk->final_start_line_number, start_line);
if (hunk->lines_in_hunk != len) {
hunk_message(idx, hunk, "mismatched line count: expected %d, got %d",
hunk_message(idx, hunk, "mismatched line count: expected %"PRIuZ", got %"PRIuZ,
len, hunk->lines_in_hunk);
}
cl_assert_equal_i(hunk->lines_in_hunk, len);

View File

@@ -1,7 +1,7 @@
#include "clar_libgit2.h"
#include "blame.h"
void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...);
void hunk_message(size_t idx, const git_blame_hunk *hunk, const char *fmt, ...) GIT_FORMAT_PRINTF(3, 4);
void check_blame_hunk_index(
git_repository *repo,

View File

@@ -0,0 +1,420 @@
#include "blame_helpers.h"
static git_repository *g_repo;
static git_blame *g_fileblame, *g_bufferblame;
void test_blame_buffer__initialize(void)
{
cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
cl_git_pass(git_blame_file(&g_fileblame, g_repo, "b.txt", NULL));
g_bufferblame = NULL;
}
void test_blame_buffer__cleanup(void)
{
git_blame_free(g_fileblame);
git_blame_free(g_bufferblame);
git_repository_free(g_repo);
}
void test_blame_buffer__4_edits(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
xEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
x\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 2, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 3, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 4, 1, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 5, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 6, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 5, 7, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 6, 8, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 7, 9, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 8, 10, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 9, 11, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__two_added_lines_and_one_modified(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
x\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
x\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 3, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 4, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 5, 1, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 6, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 7, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 5, 8, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 6, 9, 3, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 7, 12, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__two_added_lines(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
abc\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
def\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 3, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 4, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 5, 1, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 6, 1, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 7, 5, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 5, 12, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__added_blocks(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
abcdefg\n\
hijlmno\n\
pqrstuv\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
abcdefg\n\
hijlmno\n\
pqrstuv\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
\n\
abcdefg\n\
hijlmno\n\
pqrstuv\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 4, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 5, 1, 1, "b99f7ac0", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 3, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 9, 4, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 13, 3, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 5, 16, 5, 0, "aa06ecca", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 6, 21, 3, 0, "000000", "b.txt");
}
void test_blame_buffer__overlapping_blocks(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
abcdefg\n\
hijlmno\n\
pqrstuv\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
\n\
";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 3, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 4, 3, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 7, 4, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 11, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__2_add_splits_hunk(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
abc\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
abc\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 2, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 3, 1, 0, "00000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 4, 2, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 6, 1, 1, "b99f7ac0", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 7, 2, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 5, 9, 1, 0, "00000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 6, 10, 3, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 7, 13, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__index(void)
{
const git_blame_hunk *hunk;
const char *buffer = "Hello\nWorld!";
git_blame_free(g_fileblame);
g_fileblame = NULL;
cl_git_pass(git_blame_file(&g_fileblame, g_repo, "file.txt", NULL));
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(2, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 1, 0, "836bc00b", "file.txt");
hunk = git_blame_get_hunk_byline(g_bufferblame, 1);
cl_assert(hunk);
cl_assert_equal_s("lhchavez", hunk->final_signature->name);
check_blame_hunk_index(g_repo, g_bufferblame, 1, 2, 1, 0, "00000000", "file.txt");
hunk = git_blame_get_hunk_byline(g_bufferblame, 2);
cl_assert(hunk);
cl_assert(hunk->final_signature == NULL);
}
void test_blame_buffer__added_line(void)
{
const git_blame_hunk *hunk;
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
abcdefg\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "000000", "b.txt");
hunk = git_blame_get_hunk_byline(g_bufferblame, 16);
cl_assert(hunk);
cl_assert_equal_s("Ben Straub", hunk->final_signature->name);
}
void test_blame_buffer__added_lines(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
\n\
\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
\n\
\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
\n\
\n\
\n\
\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(7, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 3, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 14, 3, 0, "000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 6, 22, 3, 0, "000000", "b.txt");
}
void test_blame_buffer__deleted_line(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 3, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 9, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 10, 5, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__add_splits_hunk(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
abc\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 2, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 8, 1, 0, "00000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 9, 3, 0, "63d671eb", "b.txt");
}
void test_blame_buffer__delete_crosses_hunk_boundary(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 2, 0, "aa06ecca", "b.txt");
}
void test_blame_buffer__replace_line(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
abc\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 1, 0, "00000000", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 8, 3, 0, "63d671eb", "b.txt");
}
void test_blame_buffer__add_lines_at_end(void)
{
const char *buffer = "\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
\n\
abc\n\
def\n";
cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
check_blame_hunk_index(g_repo, g_bufferblame, 0, 1, 4, 0, "da237394", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 1, 5, 1, 1, "b99f7ac0", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 5, 0, "63d671eb", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 3, 11, 5, 0, "aa06ecca", "b.txt");
check_blame_hunk_index(g_repo, g_bufferblame, 4, 16, 2, 0, "00000000", "b.txt");
}

View File

@@ -10,11 +10,11 @@ void test_blame_getters__initialize(void)
git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
git_blame_hunk hunks[] = {
{ 3, {{0}}, 1, NULL, {{0}}, "a", 0},
{ 3, {{0}}, 4, NULL, {{0}}, "b", 0},
{ 3, {{0}}, 7, NULL, {{0}}, "c", 0},
{ 3, {{0}}, 10, NULL, {{0}}, "d", 0},
{ 3, {{0}}, 13, NULL, {{0}}, "e", 0},
{ 3, GIT_OID_SHA1_ZERO, 1, NULL, GIT_OID_SHA1_ZERO, "a", 0},
{ 3, GIT_OID_SHA1_ZERO, 4, NULL, GIT_OID_SHA1_ZERO, "b", 0},
{ 3, GIT_OID_SHA1_ZERO, 7, NULL, GIT_OID_SHA1_ZERO, "c", 0},
{ 3, GIT_OID_SHA1_ZERO, 10, NULL, GIT_OID_SHA1_ZERO, "d", 0},
{ 3, GIT_OID_SHA1_ZERO, 13, NULL, GIT_OID_SHA1_ZERO, "e", 0},
};
g_blame = git_blame__alloc(NULL, opts, "");

View File

@@ -238,6 +238,24 @@ void test_blame_simple__can_restrict_lines_min(void)
check_blame_hunk_index(g_repo, g_blame, 1, 11, 5, 0, "aa06ecca", "b.txt");
}
/*
* $ git blame -n c.txt
* orig line no final line no
* commit V author timestamp V
* 702c7aa5 1 (Carl Schwan 2020-01-29 01:52:31 +0100 4
*/
void test_blame_simple__can_ignore_whitespace_change(void)
{
git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
cl_git_pass(git_repository_open(&g_repo, cl_fixture("blametest.git")));
opts.flags |= GIT_BLAME_IGNORE_WHITESPACE;
cl_git_pass(git_blame_file(&g_blame, g_repo, "c.txt", &opts));
cl_assert_equal_i(1, git_blame_get_hunk_count(g_blame));
check_blame_hunk_index(g_repo, g_blame, 0, 1, 4, 0, "702c7aa5", "c.txt");
}
/*
* $ git blame -n b.txt -L ,6
* orig line no final line no

View File

@@ -3,6 +3,7 @@
#include "repo/repo_helpers.h"
#include "path.h"
#include "futils.h"
#include "odb.h"
static git_repository *g_repo;
@@ -35,13 +36,13 @@ static void execute_test(void)
git_commit_free(commit);
/* Verify that the lenna.jpg file was checked out correctly */
cl_git_pass(git_oid_fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1"));
cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJECT_BLOB));
cl_git_pass(git_oid__fromstr(&check, "8ab005d890fe53f65eda14b23672f60d9f4ec5a1", GIT_OID_SHA1));
cl_git_pass(git_odb__hashfile(&oid, "binaryunicode/lenna.jpg", GIT_OBJECT_BLOB, GIT_OID_SHA1));
cl_assert_equal_oid(&oid, &check);
/* Verify that the text file was checked out correctly */
cl_git_pass(git_oid_fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a"));
cl_git_pass(git_odb_hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJECT_BLOB));
cl_git_pass(git_oid__fromstr(&check, "965b223880dd4249e2c66a0cc0b4cffe1dc40f5a", GIT_OID_SHA1));
cl_git_pass(git_odb__hashfile(&oid, "binaryunicode/utf16_withbom_noeol_crlf.txt", GIT_OBJECT_BLOB, GIT_OID_SHA1));
cl_assert_equal_oid(&oid, &check);
}

View File

@@ -7,16 +7,16 @@
void assert_on_branch(git_repository *repo, const char *branch)
{
git_reference *head;
git_buf bname = GIT_BUF_INIT;
git_str bname = GIT_STR_INIT;
cl_git_pass(git_reference_lookup(&head, repo, GIT_HEAD_FILE));
cl_assert_(git_reference_type(head) == GIT_REFERENCE_SYMBOLIC, branch);
cl_git_pass(git_buf_joinpath(&bname, "refs/heads", branch));
cl_git_pass(git_str_joinpath(&bname, "refs/heads", branch));
cl_assert_equal_s(bname.ptr, git_reference_symbolic_target(head));
git_reference_free(head);
git_buf_dispose(&bname);
git_str_dispose(&bname);
}
void reset_index_to_treeish(git_object *treeish)

View File

@@ -1,4 +1,3 @@
#include "buffer.h"
#include "git2/object.h"
#include "git2/repository.h"

View File

@@ -49,7 +49,7 @@ static git_index *g_index;
struct checkout_index_entry {
uint16_t mode;
char oid_str[GIT_OID_HEXSZ+1];
char oid_str[GIT_OID_SHA1_HEXSIZE+1];
int stage;
char path[128];
};
@@ -85,14 +85,14 @@ void test_checkout_conflict__cleanup(void)
static void create_index(struct checkout_index_entry *entries, size_t entries_len)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
size_t i;
for (i = 0; i < entries_len; i++) {
git_buf_joinpath(&path, TEST_REPO_PATH, entries[i].path);
git_str_joinpath(&path, TEST_REPO_PATH, entries[i].path);
if (entries[i].stage == 3 && (i == 0 || strcmp(entries[i-1].path, entries[i].path) != 0 || entries[i-1].stage != 2))
p_unlink(git_buf_cstr(&path));
p_unlink(git_str_cstr(&path));
cl_git_pass(git_index_remove_bypath(g_index, entries[i].path));
}
@@ -104,13 +104,13 @@ static void create_index(struct checkout_index_entry *entries, size_t entries_le
entry.mode = entries[i].mode;
GIT_INDEX_ENTRY_STAGE_SET(&entry, entries[i].stage);
git_oid_fromstr(&entry.id, entries[i].oid_str);
git_oid__fromstr(&entry.id, entries[i].oid_str, GIT_OID_SHA1);
entry.path = entries[i].path;
cl_git_pass(git_index_add(g_index, &entry));
}
git_buf_dispose(&path);
git_str_dispose(&path);
}
static void create_index_names(struct checkout_name_entry *entries, size_t entries_len)
@@ -139,23 +139,23 @@ static void create_conflicting_index(void)
static void ensure_workdir_contents(const char *path, const char *contents)
{
git_buf fullpath = GIT_BUF_INIT, data_buf = GIT_BUF_INIT;
git_str fullpath = GIT_STR_INIT, data_buf = GIT_STR_INIT;
cl_git_pass(
git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
git_str_joinpath(&fullpath, git_repository_workdir(g_repo), path));
cl_git_pass(git_futils_readbuffer(&data_buf, git_buf_cstr(&fullpath)));
cl_assert(strcmp(git_buf_cstr(&data_buf), contents) == 0);
cl_git_pass(git_futils_readbuffer(&data_buf, git_str_cstr(&fullpath)));
cl_assert(strcmp(git_str_cstr(&data_buf), contents) == 0);
git_buf_dispose(&fullpath);
git_buf_dispose(&data_buf);
git_str_dispose(&fullpath);
git_str_dispose(&data_buf);
}
static void ensure_workdir_oid(const char *path, const char *oid_str)
{
git_oid expected, actual;
cl_git_pass(git_oid_fromstr(&expected, oid_str));
cl_git_pass(git_oid__fromstr(&expected, oid_str, GIT_OID_SHA1));
cl_git_pass(git_repository_hashfile(&actual, g_repo, path, GIT_OBJECT_BLOB, NULL));
cl_assert_equal_oid(&expected, &actual);
}
@@ -166,16 +166,16 @@ static void ensure_workdir_mode(const char *path, int mode)
GIT_UNUSED(path);
GIT_UNUSED(mode);
#else
git_buf fullpath = GIT_BUF_INIT;
git_str fullpath = GIT_STR_INIT;
struct stat st;
cl_git_pass(
git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
git_str_joinpath(&fullpath, git_repository_workdir(g_repo), path));
cl_git_pass(p_stat(git_buf_cstr(&fullpath), &st));
cl_git_pass(p_stat(git_str_cstr(&fullpath), &st));
cl_assert_equal_i((mode & S_IRWXU), (st.st_mode & S_IRWXU));
git_buf_dispose(&fullpath);
git_str_dispose(&fullpath);
#endif
}
@@ -197,22 +197,22 @@ static void ensure_workdir_link(
if (!symlinks) {
ensure_workdir_contents(path, target);
} else {
git_buf fullpath = GIT_BUF_INIT;
git_str fullpath = GIT_STR_INIT;
char actual[1024];
struct stat st;
int len;
cl_git_pass(
git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));
git_str_joinpath(&fullpath, git_repository_workdir(g_repo), path));
cl_git_pass(p_lstat(git_buf_cstr(&fullpath), &st));
cl_git_pass(p_lstat(git_str_cstr(&fullpath), &st));
cl_assert(S_ISLNK(st.st_mode));
cl_assert((len = p_readlink(git_buf_cstr(&fullpath), actual, 1024)) > 0);
cl_assert((len = p_readlink(git_str_cstr(&fullpath), actual, 1024)) > 0);
actual[len] = '\0';
cl_assert(strcmp(actual, target) == 0);
git_buf_dispose(&fullpath);
git_str_dispose(&fullpath);
}
}
@@ -227,7 +227,7 @@ void test_checkout_conflict__ignored(void)
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
cl_assert(!git_path_exists(TEST_REPO_PATH "/conflicting.txt"));
cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/conflicting.txt"));
}
void test_checkout_conflict__ours(void)
@@ -1030,15 +1030,15 @@ void test_checkout_conflict__update_only(void)
ensure_workdir_contents("automergeable.txt", AUTOMERGEABLE_MERGED_FILE);
ensure_workdir("directory_file-two/file", 0100644, CONFLICTING_OURS_OID);
cl_assert(!git_path_exists("merge-resolve/modify-delete"));
cl_assert(!git_path_exists("merge-resolve/test-one.txt"));
cl_assert(!git_path_exists("merge-resolve/test-one-side-one.txt"));
cl_assert(!git_path_exists("merge-resolve/test-one-side-two.txt"));
cl_assert(!git_path_exists("merge-resolve/test-one.txt~ours"));
cl_assert(!git_path_exists("merge-resolve/test-one.txt~theirs"));
cl_assert(!git_path_exists("merge-resolve/directory_file-one/file"));
cl_assert(!git_path_exists("merge-resolve/directory_file-one~ours"));
cl_assert(!git_path_exists("merge-resolve/directory_file-two~theirs"));
cl_assert(!git_fs_path_exists("merge-resolve/modify-delete"));
cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt"));
cl_assert(!git_fs_path_exists("merge-resolve/test-one-side-one.txt"));
cl_assert(!git_fs_path_exists("merge-resolve/test-one-side-two.txt"));
cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt~ours"));
cl_assert(!git_fs_path_exists("merge-resolve/test-one.txt~theirs"));
cl_assert(!git_fs_path_exists("merge-resolve/directory_file-one/file"));
cl_assert(!git_fs_path_exists("merge-resolve/directory_file-one~ours"));
cl_assert(!git_fs_path_exists("merge-resolve/directory_file-two~theirs"));
}
void test_checkout_conflict__path_filters(void)
@@ -1076,9 +1076,9 @@ void test_checkout_conflict__path_filters(void)
cl_git_pass(git_checkout_index(g_repo, g_index, &opts));
ensure_workdir_contents("conflicting-1.txt", CONFLICTING_DIFF3_FILE);
cl_assert(!git_path_exists("merge-resolve/conflicting-2.txt"));
cl_assert(!git_fs_path_exists("merge-resolve/conflicting-2.txt"));
ensure_workdir_contents("conflicting-3.txt", AUTOMERGEABLE_MERGED_FILE);
cl_assert(!git_path_exists("merge-resolve/conflicting-4.txt"));
cl_assert(!git_fs_path_exists("merge-resolve/conflicting-4.txt"));
}
static void collect_progress(

View File

@@ -11,13 +11,13 @@
static git_repository *g_repo;
static const char *systype;
static git_buf expected_fixture = GIT_BUF_INIT;
static git_str expected_fixture = GIT_STR_INIT;
static int unlink_file(void *payload, git_buf *path)
static int unlink_file(void *payload, git_str *path)
{
char *fn;
cl_assert(fn = git_path_basename(path->ptr));
cl_assert(fn = git_fs_path_basename(path->ptr));
GIT_UNUSED(payload);
@@ -30,7 +30,7 @@ static int unlink_file(void *payload, git_buf *path)
void test_checkout_crlf__initialize(void)
{
git_buf reponame = GIT_BUF_INIT;
git_str reponame = GIT_STR_INIT;
g_repo = cl_git_sandbox_init("crlf");
@@ -38,15 +38,15 @@ void test_checkout_crlf__initialize(void)
* remove the contents of the working directory so that we can
* check out over it.
*/
cl_git_pass(git_buf_puts(&reponame, "crlf"));
cl_git_pass(git_path_direach(&reponame, 0, unlink_file, NULL));
cl_git_pass(git_str_puts(&reponame, "crlf"));
cl_git_pass(git_fs_path_direach(&reponame, 0, unlink_file, NULL));
if (GIT_EOL_NATIVE == GIT_EOL_CRLF)
systype = "windows";
else
systype = "posix";
git_buf_dispose(&reponame);
git_str_dispose(&reponame);
}
void test_checkout_crlf__cleanup(void)
@@ -55,7 +55,7 @@ void test_checkout_crlf__cleanup(void)
if (expected_fixture.size) {
cl_fixture_cleanup(expected_fixture.ptr);
git_buf_dispose(&expected_fixture);
git_str_dispose(&expected_fixture);
}
}
@@ -66,17 +66,17 @@ struct compare_data
const char *attrs;
};
static int compare_file(void *payload, git_buf *actual_path)
static int compare_file(void *payload, git_str *actual_path)
{
git_buf expected_path = GIT_BUF_INIT;
git_buf actual_contents = GIT_BUF_INIT;
git_buf expected_contents = GIT_BUF_INIT;
git_str expected_path = GIT_STR_INIT;
git_str actual_contents = GIT_STR_INIT;
git_str expected_contents = GIT_STR_INIT;
struct compare_data *cd = payload;
bool failed = true;
int cmp_git, cmp_gitattributes;
char *basename;
basename = git_path_basename(actual_path->ptr);
basename = git_fs_path_basename(actual_path->ptr);
cmp_git = strcmp(basename, ".git");
cmp_gitattributes = strcmp(basename, ".gitattributes");
@@ -85,10 +85,10 @@ static int compare_file(void *payload, git_buf *actual_path)
goto done;
}
cl_git_pass(git_buf_joinpath(&expected_path, cd->dirname, basename));
cl_git_pass(git_str_joinpath(&expected_path, cd->dirname, basename));
if (!git_path_isfile(expected_path.ptr) ||
!git_path_isfile(actual_path->ptr))
if (!git_fs_path_isfile(expected_path.ptr) ||
!git_fs_path_isfile(actual_path->ptr))
goto done;
if (git_futils_readbuffer(&actual_contents, actual_path->ptr) < 0 ||
@@ -105,78 +105,78 @@ static int compare_file(void *payload, git_buf *actual_path)
done:
if (failed) {
git_buf details = GIT_BUF_INIT;
git_buf_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}",
git_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs);
clar__fail(__FILE__, __LINE__,
git_str details = GIT_STR_INIT;
git_str_printf(&details, "filename=%s, system=%s, autocrlf=%s, attrs={%s}",
git_fs_path_basename(actual_path->ptr), systype, cd->autocrlf, cd->attrs);
clar__fail(__FILE__, __func__, __LINE__,
"checked out contents did not match expected", details.ptr, 0);
git_buf_dispose(&details);
git_str_dispose(&details);
}
git__free(basename);
git_buf_dispose(&expected_contents);
git_buf_dispose(&actual_contents);
git_buf_dispose(&expected_path);
git_str_dispose(&expected_contents);
git_str_dispose(&actual_contents);
git_str_dispose(&expected_path);
return 0;
}
static void test_checkout(const char *autocrlf, const char *attrs)
{
git_buf attrbuf = GIT_BUF_INIT;
git_buf expected_dirname = GIT_BUF_INIT;
git_buf systype_and_direction = GIT_BUF_INIT;
git_buf sandboxname = GIT_BUF_INIT;
git_buf reponame = GIT_BUF_INIT;
git_str attrbuf = GIT_STR_INIT;
git_str expected_dirname = GIT_STR_INIT;
git_str systype_and_direction = GIT_STR_INIT;
git_str sandboxname = GIT_STR_INIT;
git_str reponame = GIT_STR_INIT;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
struct compare_data compare_data = { NULL, autocrlf, attrs };
const char *c;
cl_git_pass(git_buf_puts(&reponame, "crlf"));
cl_git_pass(git_str_puts(&reponame, "crlf"));
cl_git_pass(git_buf_puts(&systype_and_direction, systype));
cl_git_pass(git_buf_puts(&systype_and_direction, "_to_workdir"));
cl_git_pass(git_str_puts(&systype_and_direction, systype));
cl_git_pass(git_str_puts(&systype_and_direction, "_to_workdir"));
cl_git_pass(git_buf_puts(&sandboxname, "autocrlf_"));
cl_git_pass(git_buf_puts(&sandboxname, autocrlf));
cl_git_pass(git_str_puts(&sandboxname, "autocrlf_"));
cl_git_pass(git_str_puts(&sandboxname, autocrlf));
if (*attrs) {
cl_git_pass(git_buf_puts(&sandboxname, ","));
cl_git_pass(git_str_puts(&sandboxname, ","));
for (c = attrs; *c; c++) {
if (*c == ' ')
cl_git_pass(git_buf_putc(&sandboxname, ','));
cl_git_pass(git_str_putc(&sandboxname, ','));
else if (*c == '=')
cl_git_pass(git_buf_putc(&sandboxname, '_'));
cl_git_pass(git_str_putc(&sandboxname, '_'));
else
cl_git_pass(git_buf_putc(&sandboxname, *c));
cl_git_pass(git_str_putc(&sandboxname, *c));
}
cl_git_pass(git_buf_printf(&attrbuf, "* %s\n", attrs));
cl_git_pass(git_str_printf(&attrbuf, "* %s\n", attrs));
cl_git_mkfile("crlf/.gitattributes", attrbuf.ptr);
}
cl_repo_set_string(g_repo, "core.autocrlf", autocrlf);
cl_git_pass(git_buf_joinpath(&expected_dirname, systype_and_direction.ptr, sandboxname.ptr));
cl_git_pass(git_buf_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr));
cl_git_pass(git_str_joinpath(&expected_dirname, systype_and_direction.ptr, sandboxname.ptr));
cl_git_pass(git_str_joinpath(&expected_fixture, "crlf_data", expected_dirname.ptr));
cl_fixture_sandbox(expected_fixture.ptr);
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
compare_data.dirname = sandboxname.ptr;
cl_git_pass(git_path_direach(&reponame, 0, compare_file, &compare_data));
cl_git_pass(git_fs_path_direach(&reponame, 0, compare_file, &compare_data));
cl_fixture_cleanup(expected_fixture.ptr);
git_buf_dispose(&expected_fixture);
git_str_dispose(&expected_fixture);
git_buf_dispose(&attrbuf);
git_buf_dispose(&expected_fixture);
git_buf_dispose(&expected_dirname);
git_buf_dispose(&sandboxname);
git_buf_dispose(&systype_and_direction);
git_buf_dispose(&reponame);
git_str_dispose(&attrbuf);
git_str_dispose(&expected_fixture);
git_str_dispose(&expected_dirname);
git_str_dispose(&sandboxname);
git_str_dispose(&systype_and_direction);
git_str_dispose(&reponame);
}
static void empty_workdir(const char *name)
@@ -187,9 +187,9 @@ static void empty_workdir(const char *name)
size_t i;
const char *fn;
cl_git_pass(git_path_dirload(&contents, name, 0, 0));
cl_git_pass(git_fs_path_dirload(&contents, name, 0, 0));
git_vector_foreach(&contents, i, fn) {
cl_assert(basename = git_path_basename(fn));
cl_assert(basename = git_fs_path_basename(fn));
cmp = strncasecmp(basename, ".git", 4);
git__free(basename);
@@ -239,10 +239,10 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
cl_repo_set_bool(g_repo, "core.autocrlf", false);
git_repository_index(&index, g_repo);
cl_git_pass(git_repository_index(&index, g_repo));
tick_index(index);
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW));

View File

@@ -43,7 +43,7 @@ void test_checkout_head__with_index_only_tree(void)
cl_git_pass(git_index_add_bypath(index, "newdir/newfile.txt"));
cl_git_pass(git_index_write(index));
cl_assert(git_path_isfile("testrepo/newdir/newfile.txt"));
cl_assert(git_fs_path_isfile("testrepo/newdir/newfile.txt"));
cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) != NULL);
git_index_free(index);
@@ -55,7 +55,7 @@ void test_checkout_head__with_index_only_tree(void)
cl_git_pass(git_repository_index(&index, g_repo));
cl_assert(!git_path_isfile("testrepo/newdir/newfile.txt"));
cl_assert(!git_fs_path_isfile("testrepo/newdir/newfile.txt"));
cl_assert(git_index_get_bypath(index, "newdir/newfile.txt", 0) == NULL);
git_index_free(index);
@@ -79,8 +79,8 @@ void test_checkout_head__do_not_remove_untracked_file(void)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isfile("testrepo/tracked/tracked"));
cl_assert(git_path_isfile("testrepo/tracked/untracked"));
cl_assert(!git_fs_path_isfile("testrepo/tracked/tracked"));
cl_assert(git_fs_path_isfile("testrepo/tracked/untracked"));
}
void test_checkout_head__do_not_remove_untracked_file_in_subdir(void)
@@ -104,9 +104,35 @@ void test_checkout_head__do_not_remove_untracked_file_in_subdir(void)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isfile("testrepo/tracked/tracked"));
cl_assert(!git_path_isfile("testrepo/tracked/subdir/tracked"));
cl_assert(git_path_isfile("testrepo/tracked/subdir/untracked"));
cl_assert(!git_fs_path_isfile("testrepo/tracked/tracked"));
cl_assert(!git_fs_path_isfile("testrepo/tracked/subdir/tracked"));
cl_assert(git_fs_path_isfile("testrepo/tracked/subdir/untracked"));
}
void test_checkout_head__do_remove_untracked_paths(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_index *index;
char *paths[] = {"tracked/untracked"};
cl_git_pass(p_mkdir("testrepo/tracked", 0755));
cl_git_pass(p_mkdir("testrepo/tracked/subdir", 0755));
cl_git_mkfile("testrepo/tracked/tracked", "tracked\n");
cl_git_mkfile("testrepo/tracked/untracked", "untracked\n");
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_add_bypath(index, "tracked/tracked"));
cl_git_pass(git_index_write(index));
git_index_free(index);
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
opts.paths.strings = paths;
opts.paths.count = 1;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(git_fs_path_isfile("testrepo/tracked/tracked"));
cl_assert(!git_fs_path_isfile("testrepo/tracked/untracked"));
}
void test_checkout_head__do_remove_tracked_subdir(void)
@@ -132,9 +158,9 @@ void test_checkout_head__do_remove_tracked_subdir(void)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isdir("testrepo/subdir/tracked"));
cl_assert(!git_path_isfile("testrepo/subdir/tracked-file"));
cl_assert(git_path_isfile("testrepo/subdir/untracked-file"));
cl_assert(!git_fs_path_isdir("testrepo/subdir/tracked"));
cl_assert(!git_fs_path_isfile("testrepo/subdir/tracked-file"));
cl_assert(git_fs_path_isfile("testrepo/subdir/untracked-file"));
}
void test_checkout_head__typechange_workdir(void)

View File

@@ -46,19 +46,19 @@ void test_checkout_icase__cleanup(void)
static char *get_filename(const char *in)
{
char *search_dirname, *search_filename, *filename = NULL;
git_buf out = GIT_BUF_INIT;
git_str out = GIT_STR_INIT;
DIR *dir;
struct dirent *de;
cl_assert(search_dirname = git_path_dirname(in));
cl_assert(search_filename = git_path_basename(in));
cl_assert(search_dirname = git_fs_path_dirname(in));
cl_assert(search_filename = git_fs_path_basename(in));
cl_assert(dir = opendir(search_dirname));
while ((de = readdir(dir))) {
if (strcasecmp(de->d_name, search_filename) == 0) {
git_buf_join(&out, '/', search_dirname, de->d_name);
filename = git_buf_detach(&out);
git_str_join(&out, '/', search_dirname, de->d_name);
filename = git_str_detach(&out);
break;
}
}
@@ -67,7 +67,7 @@ static char *get_filename(const char *in)
git__free(search_dirname);
git__free(search_filename);
git_buf_dispose(&out);
git_str_dispose(&out);
return filename;
}
@@ -134,7 +134,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_files(void)
cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
cl_assert(!git_path_exists("tmp"));
cl_assert(!git_fs_path_exists("tmp"));
assert_name_is("testrepo/BRANCH_FILE.txt");
}
@@ -146,7 +146,7 @@ void test_checkout_icase__overwrites_links_for_files_when_forced(void)
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
cl_assert(!git_path_exists("tmp"));
cl_assert(!git_fs_path_exists("tmp"));
assert_name_is("testrepo/new.txt");
}
@@ -159,7 +159,7 @@ void test_checkout_icase__overwrites_empty_folders_for_files(void)
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
assert_name_is("testrepo/new.txt");
cl_assert(!git_path_isdir("testrepo/new.txt"));
cl_assert(!git_fs_path_isdir("testrepo/new.txt"));
}
void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void)
@@ -173,7 +173,7 @@ void test_checkout_icase__refuses_to_overwrite_populated_folders_for_files(void)
cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
assert_name_is("testrepo/BRANCH_FILE.txt");
cl_assert(git_path_isdir("testrepo/BRANCH_FILE.txt"));
cl_assert(git_fs_path_isdir("testrepo/BRANCH_FILE.txt"));
}
void test_checkout_icase__overwrites_folders_for_files_when_forced(void)
@@ -187,7 +187,7 @@ void test_checkout_icase__overwrites_folders_for_files_when_forced(void)
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
assert_name_is("testrepo/new.txt");
cl_assert(!git_path_isdir("testrepo/new.txt"));
cl_assert(!git_fs_path_isdir("testrepo/new.txt"));
}
void test_checkout_icase__refuses_to_overwrite_files_for_folders(void)
@@ -199,7 +199,7 @@ void test_checkout_icase__refuses_to_overwrite_files_for_folders(void)
cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
assert_name_is("testrepo/A");
cl_assert(!git_path_isdir("testrepo/A"));
cl_assert(!git_fs_path_isdir("testrepo/A"));
}
void test_checkout_icase__overwrites_files_for_folders_when_forced(void)
@@ -211,7 +211,7 @@ void test_checkout_icase__overwrites_files_for_folders_when_forced(void)
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
assert_name_is("testrepo/a");
cl_assert(git_path_isdir("testrepo/a"));
cl_assert(git_fs_path_isdir("testrepo/a"));
}
void test_checkout_icase__refuses_to_overwrite_links_for_folders(void)
@@ -222,7 +222,7 @@ void test_checkout_icase__refuses_to_overwrite_links_for_folders(void)
cl_git_fail(git_checkout_tree(repo, obj, &checkout_opts));
cl_assert(!git_path_exists("b.txt"));
cl_assert(!git_fs_path_exists("b.txt"));
assert_name_is("testrepo/A");
}
@@ -234,7 +234,7 @@ void test_checkout_icase__overwrites_links_for_folders_when_forced(void)
cl_git_pass(git_checkout_tree(repo, obj, &checkout_opts));
cl_assert(!git_path_exists("b.txt"));
cl_assert(!git_fs_path_exists("b.txt"));
assert_name_is("testrepo/a");
}

View File

@@ -4,11 +4,12 @@
#include "git2/checkout.h"
#include "futils.h"
#include "repository.h"
#include "index.h"
#include "remote.h"
#include "repo/repo_helpers.h"
static git_repository *g_repo;
static git_buf g_global_path = GIT_BUF_INIT;
static git_str g_global_path = GIT_STR_INIT;
void test_checkout_index__initialize(void)
{
@@ -33,7 +34,7 @@ void test_checkout_index__cleanup(void)
{
git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL,
g_global_path.ptr);
git_buf_dispose(&g_global_path);
git_str_dispose(&g_global_path);
cl_git_sandbox_cleanup();
@@ -56,9 +57,9 @@ void test_checkout_index__can_create_missing_files(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt"));
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
@@ -77,7 +78,7 @@ void test_checkout_index__can_remove_untracked_files(void)
cl_git_mkfile("./testrepo/dir/one", "one\n");
cl_git_mkfile("./testrepo/dir/subdir/two", "two\n");
cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir"));
cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/dir/subdir/subsubdir"));
opts.checkout_strategy =
GIT_CHECKOUT_SAFE |
@@ -86,7 +87,62 @@ void test_checkout_index__can_remove_untracked_files(void)
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
cl_assert_equal_i(false, git_path_isdir("./testrepo/dir"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/dir"));
}
void test_checkout_index__can_disable_pathspec_match(void)
{
char *files_to_checkout[] = { "test10.txt", "test11.txt"};
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_object *objects;
git_index *index;
/* reset to beginning of history (i.e. just a README file) */
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
cl_git_pass(git_revparse_single(&objects, g_repo, "8496071c1b46c854b31185ea97743be6a8774479"));
cl_git_pass(git_checkout_tree(g_repo, objects, &opts));
cl_git_pass(git_repository_set_head_detached(g_repo, git_object_id(objects)));
git_object_free(objects);
cl_git_pass(git_repository_index(&index, g_repo));
/* We create 4 files and commit them */
cl_git_mkfile("testrepo/test9.txt", "original\n");
cl_git_mkfile("testrepo/test10.txt", "original\n");
cl_git_mkfile("testrepo/test11.txt", "original\n");
cl_git_mkfile("testrepo/test12.txt", "original\n");
cl_git_pass(git_index_add_bypath(index, "test9.txt"));
cl_git_pass(git_index_add_bypath(index, "test10.txt"));
cl_git_pass(git_index_add_bypath(index, "test11.txt"));
cl_git_pass(git_index_add_bypath(index, "test12.txt"));
cl_git_pass(git_index_write(index));
cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit our test files");
/* We modify the content of all 4 of our files */
cl_git_rewritefile("testrepo/test9.txt", "modified\n");
cl_git_rewritefile("testrepo/test10.txt", "modified\n");
cl_git_rewritefile("testrepo/test11.txt", "modified\n");
cl_git_rewritefile("testrepo/test12.txt", "modified\n");
/* We checkout only test10.txt and test11.txt */
opts.checkout_strategy =
GIT_CHECKOUT_FORCE |
GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
opts.paths.strings = files_to_checkout;
opts.paths.count = ARRAY_SIZE(files_to_checkout);
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
/* The only files that have been reverted to their original content
should be test10.txt and test11.txt */
check_file_contents("testrepo/test9.txt", "modified\n");
check_file_contents("testrepo/test10.txt", "original\n");
check_file_contents("testrepo/test11.txt", "original\n");
check_file_contents("testrepo/test12.txt", "modified\n");
git_index_free(index);
}
void test_checkout_index__honor_the_specified_pathspecs(void)
@@ -97,15 +153,15 @@ void test_checkout_index__honor_the_specified_pathspecs(void)
opts.paths.strings = entries;
opts.paths.count = 1;
cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt"));
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README"));
check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
check_file_contents("./testrepo/new.txt", "my new file\n");
}
@@ -148,14 +204,14 @@ void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void)
static void populate_symlink_workdir(void)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
git_repository *repo;
git_remote *origin;
git_object *target;
const char *url = git_repository_path(g_repo);
cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), "symlink.git"));
cl_git_pass(git_str_joinpath(&path, clar_sandbox_path(), "symlink.git"));
cl_git_pass(git_repository_init(&repo, path.ptr, true));
cl_git_pass(git_repository_set_workdir(repo, "symlink", 1));
@@ -171,7 +227,7 @@ static void populate_symlink_workdir(void)
git_object_free(target);
git_repository_free(repo);
git_buf_dispose(&path);
git_str_dispose(&path);
}
void test_checkout_index__honor_coresymlinks_default_true(void)
@@ -181,7 +237,7 @@ void test_checkout_index__honor_coresymlinks_default_true(void)
cl_must_pass(p_mkdir("symlink", 0777));
if (!git_path_supports_symlinks("symlink/test"))
if (!git_fs_path_supports_symlinks("symlink/test"))
cl_skip();
#ifdef GIT_WIN32
@@ -214,7 +270,7 @@ void test_checkout_index__honor_coresymlinks_default_false(void)
* supports symlinks. Bail entirely on POSIX platforms that
* do support symlinks.
*/
if (git_path_supports_symlinks("symlink/test"))
if (git_fs_path_supports_symlinks("symlink/test"))
cl_skip();
#endif
@@ -226,7 +282,7 @@ void test_checkout_index__coresymlinks_set_to_true_fails_when_unsupported(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
if (git_path_supports_symlinks("testrepo/test")) {
if (git_fs_path_supports_symlinks("testrepo/test")) {
cl_skip();
}
@@ -242,7 +298,7 @@ void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
char link_data[GIT_PATH_MAX];
size_t link_size = GIT_PATH_MAX;
if (!git_path_supports_symlinks("testrepo/test")) {
if (!git_fs_path_supports_symlinks("testrepo/test")) {
cl_skip();
}
@@ -523,8 +579,8 @@ void test_checkout_index__can_overcome_name_clashes(void)
cl_git_pass(p_mkdir("./testrepo/path0", 0777));
cl_git_mkfile("./testrepo/path0/file0", "content\r\n");
cl_assert(git_path_isfile("./testrepo/path1"));
cl_assert(git_path_isfile("./testrepo/path0/file0"));
cl_assert(git_fs_path_isfile("./testrepo/path1"));
cl_assert(git_fs_path_isfile("./testrepo/path0/file0"));
opts.checkout_strategy =
GIT_CHECKOUT_SAFE |
@@ -532,14 +588,14 @@ void test_checkout_index__can_overcome_name_clashes(void)
GIT_CHECKOUT_ALLOW_CONFLICTS;
cl_git_pass(git_checkout_index(g_repo, index, &opts));
cl_assert(git_path_isfile("./testrepo/path1"));
cl_assert(git_path_isfile("./testrepo/path0/file0"));
cl_assert(git_fs_path_isfile("./testrepo/path1"));
cl_assert(git_fs_path_isfile("./testrepo/path0/file0"));
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_index(g_repo, index, &opts));
cl_assert(git_path_isfile("./testrepo/path0"));
cl_assert(git_path_isfile("./testrepo/path1/file1"));
cl_assert(git_fs_path_isfile("./testrepo/path0"));
cl_assert(git_fs_path_isfile("./testrepo/path1/file1"));
git_index_free(index);
}
@@ -567,9 +623,9 @@ void test_checkout_index__can_update_prefixed_files(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt"));
cl_git_mkfile("./testrepo/READ", "content\n");
cl_git_mkfile("./testrepo/README.after", "content\n");
@@ -592,10 +648,10 @@ void test_checkout_index__can_update_prefixed_files(void)
check_file_contents_nocr("./testrepo/branch_file.txt", "hi\nbye!\n");
check_file_contents_nocr("./testrepo/new.txt", "my new file\n");
cl_assert(!git_path_exists("testrepo/READ"));
cl_assert(!git_path_exists("testrepo/README.after"));
cl_assert(!git_path_exists("testrepo/branch_file"));
cl_assert(!git_path_exists("testrepo/branch_file.txt.after"));
cl_assert(!git_fs_path_exists("testrepo/READ"));
cl_assert(!git_fs_path_exists("testrepo/README.after"));
cl_assert(!git_fs_path_exists("testrepo/branch_file"));
cl_assert(!git_fs_path_exists("testrepo/branch_file.txt.after"));
}
void test_checkout_index__can_checkout_a_newly_initialized_repository(void)
@@ -633,7 +689,7 @@ void test_checkout_index__target_directory(void)
opts.checkout_strategy = GIT_CHECKOUT_SAFE |
GIT_CHECKOUT_RECREATE_MISSING;
opts.target_directory = "alternative";
cl_assert(!git_path_isdir("alternative"));
cl_assert(!git_fs_path_isdir("alternative"));
opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
opts.notify_cb = checkout_count_callback;
@@ -686,7 +742,7 @@ void test_checkout_index__target_directory_from_bare(void)
cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
opts.target_directory = "alternative";
cl_assert(!git_path_isdir("alternative"));
cl_assert(!git_fs_path_isdir("alternative"));
cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
@@ -710,9 +766,9 @@ void test_checkout_index__can_get_repo_from_index(void)
git_index *index;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/README"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/branch_file.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("./testrepo/new.txt"));
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
@@ -736,15 +792,15 @@ static void add_conflict(git_index *index, const char *path)
entry.mode = 0100644;
entry.path = path;
git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46");
git_oid__fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46", GIT_OID_SHA1);
GIT_INDEX_ENTRY_STAGE_SET(&entry, 1);
cl_git_pass(git_index_add(index, &entry));
git_oid_fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10");
git_oid__fromstr(&entry.id, "4e886e602529caa9ab11d71f86634bd1b6e0de10", GIT_OID_SHA1);
GIT_INDEX_ENTRY_STAGE_SET(&entry, 2);
cl_git_pass(git_index_add(index, &entry));
git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863");
git_oid__fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1);
GIT_INDEX_ENTRY_STAGE_SET(&entry, 3);
cl_git_pass(git_index_add(index, &entry));
}
@@ -753,7 +809,7 @@ void test_checkout_index__writes_conflict_file(void)
{
git_index *index;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_buf conflicting_buf = GIT_BUF_INIT;
git_str conflicting_buf = GIT_STR_INIT;
cl_git_pass(git_repository_index(&index, g_repo));
@@ -769,7 +825,7 @@ void test_checkout_index__writes_conflict_file(void)
"=======\n"
"this file is changed in branch and master\n"
">>>>>>> theirs\n") == 0);
git_buf_dispose(&conflicting_buf);
git_str_dispose(&conflicting_buf);
git_index_free(index);
}
@@ -779,7 +835,7 @@ void test_checkout_index__adding_conflict_removes_stage_0(void)
git_index *new_index, *index;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
cl_git_pass(git_index_new(&new_index));
cl_git_pass(git_index__new(&new_index, GIT_OID_SHA1));
add_conflict(new_index, "new.txt");
cl_git_pass(git_checkout_index(g_repo, new_index, &opts));
@@ -800,7 +856,7 @@ void test_checkout_index__conflicts_honor_coreautocrlf(void)
#ifdef GIT_WIN32
git_index *index;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_buf conflicting_buf = GIT_BUF_INIT;
git_str conflicting_buf = GIT_STR_INIT;
cl_git_pass(p_unlink("./testrepo/.gitattributes"));
cl_repo_set_bool(g_repo, "core.autocrlf", true);
@@ -819,7 +875,7 @@ void test_checkout_index__conflicts_honor_coreautocrlf(void)
"=======\r\n"
"this file is changed in branch and master\r\n"
">>>>>>> theirs\r\n") == 0);
git_buf_dispose(&conflicting_buf);
git_str_dispose(&conflicting_buf);
git_index_free(index);
#endif

View File

@@ -3,7 +3,6 @@
#include "git2/checkout.h"
#include "repository.h"
#include "buffer.h"
#include "futils.h"
static const char *repo_name = "nasty";
@@ -28,9 +27,9 @@ static void test_checkout_passes(const char *refname, const char *filename)
git_oid commit_id;
git_commit *commit;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
cl_git_pass(git_buf_joinpath(&path, repo_name, filename));
cl_git_pass(git_str_joinpath(&path, repo_name, filename));
cl_git_pass(git_reference_name_to_id(&commit_id, repo, refname));
cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
@@ -39,10 +38,10 @@ static void test_checkout_passes(const char *refname, const char *filename)
GIT_CHECKOUT_DONT_UPDATE_INDEX;
cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts));
cl_assert(!git_path_exists(path.ptr));
cl_assert(!git_fs_path_exists(path.ptr));
git_commit_free(commit);
git_buf_dispose(&path);
git_str_dispose(&path);
}
static void test_checkout_fails(const char *refname, const char *filename)
@@ -50,9 +49,9 @@ static void test_checkout_fails(const char *refname, const char *filename)
git_oid commit_id;
git_commit *commit;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
cl_git_pass(git_buf_joinpath(&path, repo_name, filename));
cl_git_pass(git_str_joinpath(&path, repo_name, filename));
cl_git_pass(git_reference_name_to_id(&commit_id, repo, refname));
cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));
@@ -60,10 +59,10 @@ static void test_checkout_fails(const char *refname, const char *filename)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_fail(git_checkout_tree(repo, (const git_object *)commit, &opts));
cl_assert(!git_path_exists(path.ptr));
cl_assert(!git_fs_path_exists(path.ptr));
git_commit_free(commit);
git_buf_dispose(&path);
git_str_dispose(&path);
}
/* A tree that contains ".git" as a tree, with a blob inside
@@ -247,7 +246,7 @@ void test_checkout_nasty__only_looks_like_a_git_shortname(void)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_tree(repo, (const git_object *)commit, &opts));
cl_assert(git_path_exists("nasty/git~3/foobar"));
cl_assert(git_fs_path_exists("nasty/git~3/foobar"));
git_commit_free(commit);
#endif

View File

@@ -3,7 +3,6 @@
#include "git2/checkout.h"
#include "repository.h"
#include "buffer.h"
#include "futils.h"
static git_repository *g_repo;
@@ -35,7 +34,7 @@ void test_checkout_tree__cleanup(void)
cl_git_sandbox_cleanup();
if (git_path_isdir("alternative"))
if (git_fs_path_isdir("alternative"))
git_futils_rmdir_r("alternative", NULL, GIT_RMDIR_REMOVE_FILES);
}
@@ -55,19 +54,19 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_commit(void)
cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/fgh/1.txt"));
}
void test_checkout_tree__can_checkout_and_remove_directory(void)
{
cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/"));
/* Checkout brach "subtrees" and update HEAD, so that HEAD matches the
/* Checkout branch "subtrees" and update HEAD, so that HEAD matches the
* current working tree
*/
cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
@@ -75,14 +74,14 @@ void test_checkout_tree__can_checkout_and_remove_directory(void)
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
cl_assert_equal_i(true, git_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/fgh/1.txt"));
cl_assert_equal_i(true, git_fs_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/fgh/1.txt"));
git_object_free(g_object);
g_object = NULL;
/* Checkout brach "master" and update HEAD, so that HEAD matches the
/* Checkout branch "master" and update HEAD, so that HEAD matches the
* current working tree
*/
cl_git_pass(git_revparse_single(&g_object, g_repo, "master"));
@@ -91,7 +90,7 @@ void test_checkout_tree__can_checkout_and_remove_directory(void)
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
/* This directory should no longer exist */
cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/"));
}
void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void)
@@ -103,12 +102,12 @@ void test_checkout_tree__can_checkout_a_subdirectory_from_a_subtree(void)
cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees:ab"));
cl_assert_equal_i(false, git_path_isdir("./testrepo/de/"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/de/"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert_equal_i(true, git_path_isfile("./testrepo/de/2.txt"));
cl_assert_equal_i(true, git_path_isfile("./testrepo/de/fgh/1.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/de/2.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/de/fgh/1.txt"));
}
static void progress(const char *path, size_t cur, size_t tot, void *payload)
@@ -140,8 +139,8 @@ void test_checkout_tree__doesnt_write_unrequested_files_to_worktree(void)
git_commit* p_chomped_commit;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_oid_fromstr(&master_oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
git_oid_fromstr(&chomped_oid, "e90810b8df3e80c413d903f631643c716887138d");
git_oid__fromstr(&master_oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1);
git_oid__fromstr(&chomped_oid, "e90810b8df3e80c413d903f631643c716887138d", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&p_master_commit, g_repo, &master_oid));
cl_git_pass(git_commit_lookup(&p_chomped_commit, g_repo, &chomped_oid));
@@ -150,7 +149,7 @@ void test_checkout_tree__doesnt_write_unrequested_files_to_worktree(void)
*/
opts.checkout_strategy = GIT_CHECKOUT_NONE;
git_checkout_tree(g_repo, (git_object*)p_chomped_commit, &opts);
cl_assert_equal_i(false, git_path_isfile("testrepo/readme.txt"));
cl_assert_equal_i(false, git_fs_path_isfile("testrepo/readme.txt"));
git_commit_free(p_master_commit);
git_commit_free(p_chomped_commit);
@@ -175,12 +174,12 @@ void test_checkout_tree__can_switch_branches(void)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
cl_assert(git_path_isfile("testrepo/README"));
cl_assert(git_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_path_isfile("testrepo/new.txt"));
cl_assert(git_path_isfile("testrepo/a/b.txt"));
cl_assert(git_fs_path_isfile("testrepo/README"));
cl_assert(git_fs_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_fs_path_isfile("testrepo/new.txt"));
cl_assert(git_fs_path_isfile("testrepo/a/b.txt"));
cl_assert(!git_path_isdir("testrepo/ab"));
cl_assert(!git_fs_path_isdir("testrepo/ab"));
assert_on_branch(g_repo, "dir");
@@ -195,15 +194,15 @@ void test_checkout_tree__can_switch_branches(void)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
cl_assert(git_path_isfile("testrepo/README"));
cl_assert(git_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_path_isfile("testrepo/new.txt"));
cl_assert(git_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_path_isfile("testrepo/ab/c/3.txt"));
cl_assert(git_path_isfile("testrepo/ab/de/2.txt"));
cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt"));
cl_assert(git_fs_path_isfile("testrepo/README"));
cl_assert(git_fs_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_fs_path_isfile("testrepo/new.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/c/3.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/de/2.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/de/fgh/1.txt"));
cl_assert(!git_path_isdir("testrepo/a"));
cl_assert(!git_fs_path_isdir("testrepo/a"));
assert_on_branch(g_repo, "subtrees");
@@ -217,11 +216,11 @@ void test_checkout_tree__can_remove_untracked(void)
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_REMOVE_UNTRACKED;
cl_git_mkfile("testrepo/untracked_file", "as you wish");
cl_assert(git_path_isfile("testrepo/untracked_file"));
cl_assert(git_fs_path_isfile("testrepo/untracked_file"));
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isfile("testrepo/untracked_file"));
cl_assert(!git_fs_path_isfile("testrepo/untracked_file"));
}
void test_checkout_tree__can_remove_ignored(void)
@@ -238,11 +237,11 @@ void test_checkout_tree__can_remove_ignored(void)
cl_git_pass(git_ignore_path_is_ignored(&ignored, g_repo, "ignored_file"));
cl_assert_equal_i(1, ignored);
cl_assert(git_path_isfile("testrepo/ignored_file"));
cl_assert(git_fs_path_isfile("testrepo/ignored_file"));
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isfile("testrepo/ignored_file"));
cl_assert(!git_fs_path_isfile("testrepo/ignored_file"));
}
static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir)
@@ -265,12 +264,12 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
cl_assert(git_path_isfile("testrepo/README"));
cl_assert(git_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_path_isfile("testrepo/new.txt"));
cl_assert(git_path_isfile("testrepo/a/b.txt"));
cl_assert(git_fs_path_isfile("testrepo/README"));
cl_assert(git_fs_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_fs_path_isfile("testrepo/new.txt"));
cl_assert(git_fs_path_isfile("testrepo/a/b.txt"));
cl_assert(!git_path_isdir("testrepo/ab"));
cl_assert(!git_fs_path_isdir("testrepo/ab"));
assert_on_branch(g_repo, "dir");
@@ -286,12 +285,12 @@ static int checkout_tree_with_blob_ignored_in_workdir(int strategy, bool isdir)
cl_git_mkfile("testrepo/ab/4.txt/file2.txt", "foo bar foo");
cl_git_mkfile("testrepo/ab/4.txt/file3.txt", "inky blinky pinky clyde");
cl_assert(git_path_isdir("testrepo/ab/4.txt"));
cl_assert(git_fs_path_isdir("testrepo/ab/4.txt"));
} else {
cl_must_pass(p_mkdir("testrepo/ab", 0777));
cl_git_mkfile("testrepo/ab/4.txt", "as you wish");
cl_assert(git_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/4.txt"));
}
cl_git_pass(git_ignore_add_rule(g_repo, "ab/4.txt\n"));
@@ -325,7 +324,7 @@ void test_checkout_tree__can_overwrite_ignored_by_default(void)
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
cl_assert(git_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/4.txt"));
assert_on_branch(g_repo, "subtrees");
}
@@ -346,7 +345,7 @@ void test_checkout_tree__can_overwrite_ignored_folder_by_default(void)
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
cl_assert(git_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/4.txt"));
assert_on_branch(g_repo, "subtrees");
@@ -365,7 +364,7 @@ void test_checkout_tree__can_update_only(void)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_path_isdir("testrepo/a"));
cl_assert(!git_fs_path_isdir("testrepo/a"));
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
@@ -385,7 +384,7 @@ void test_checkout_tree__can_update_only(void)
* the test_checkout_tree__can_switch_branches test), but with
* UPDATE_ONLY it will not have been created.
*/
cl_assert(!git_path_isdir("testrepo/a"));
cl_assert(!git_fs_path_isdir("testrepo/a"));
/* but this file still should have been updated */
check_file_contents_nocr("testrepo/branch_file.txt", "hi\n");
@@ -411,10 +410,10 @@ void test_checkout_tree__can_checkout_with_pattern(void)
git_object_free(g_object);
g_object = NULL;
cl_assert(git_path_exists("testrepo/README"));
cl_assert(!git_path_exists("testrepo/branch_file.txt"));
cl_assert(!git_path_exists("testrepo/link_to_new.txt"));
cl_assert(!git_path_exists("testrepo/new.txt"));
cl_assert(git_fs_path_exists("testrepo/README"));
cl_assert(!git_fs_path_exists("testrepo/branch_file.txt"));
cl_assert(!git_fs_path_exists("testrepo/link_to_new.txt"));
cl_assert(!git_fs_path_exists("testrepo/new.txt"));
/* now to a narrow patterned checkout */
@@ -426,10 +425,10 @@ void test_checkout_tree__can_checkout_with_pattern(void)
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert(git_path_exists("testrepo/README"));
cl_assert(!git_path_exists("testrepo/branch_file.txt"));
cl_assert(git_path_exists("testrepo/link_to_new.txt"));
cl_assert(git_path_exists("testrepo/new.txt"));
cl_assert(git_fs_path_exists("testrepo/README"));
cl_assert(!git_fs_path_exists("testrepo/branch_file.txt"));
cl_assert(git_fs_path_exists("testrepo/link_to_new.txt"));
cl_assert(git_fs_path_exists("testrepo/new.txt"));
}
void test_checkout_tree__pathlist_checkout_ignores_non_matches(void)
@@ -446,10 +445,10 @@ void test_checkout_tree__pathlist_checkout_ignores_non_matches(void)
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
cl_assert(git_path_exists("testrepo/README"));
cl_assert(git_path_exists("testrepo/branch_file.txt"));
cl_assert(git_path_exists("testrepo/link_to_new.txt"));
cl_assert(git_path_exists("testrepo/new.txt"));
cl_assert(git_fs_path_exists("testrepo/README"));
cl_assert(git_fs_path_exists("testrepo/branch_file.txt"));
cl_assert(git_fs_path_exists("testrepo/link_to_new.txt"));
cl_assert(git_fs_path_exists("testrepo/new.txt"));
git_object_free(g_object);
cl_git_pass(git_revparse_single(&g_object, g_repo, "8496071c1b46c854b31185ea97743be6a8774479"));
@@ -461,10 +460,10 @@ void test_checkout_tree__pathlist_checkout_ignores_non_matches(void)
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert(git_path_exists("testrepo/README"));
cl_assert(!git_path_exists("testrepo/branch_file.txt"));
cl_assert(!git_path_exists("testrepo/link_to_new.txt"));
cl_assert(git_path_exists("testrepo/new.txt"));
cl_assert(git_fs_path_exists("testrepo/README"));
cl_assert(!git_fs_path_exists("testrepo/branch_file.txt"));
cl_assert(!git_fs_path_exists("testrepo/link_to_new.txt"));
cl_assert(git_fs_path_exists("testrepo/new.txt"));
}
void test_checkout_tree__can_disable_pattern_match(void)
@@ -485,7 +484,7 @@ void test_checkout_tree__can_disable_pattern_match(void)
git_object_free(g_object);
g_object = NULL;
cl_assert(!git_path_isfile("testrepo/branch_file.txt"));
cl_assert(!git_fs_path_isfile("testrepo/branch_file.txt"));
/* now to a narrow patterned checkout, but disable pattern */
@@ -499,7 +498,7 @@ void test_checkout_tree__can_disable_pattern_match(void)
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert(!git_path_isfile("testrepo/branch_file.txt"));
cl_assert(!git_fs_path_isfile("testrepo/branch_file.txt"));
/* let's try that again, but allow the pattern match */
@@ -507,10 +506,10 @@ void test_checkout_tree__can_disable_pattern_match(void)
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert(git_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_fs_path_isfile("testrepo/branch_file.txt"));
}
void assert_conflict(
static void assert_conflict(
const char *entry_path,
const char *new_content,
const char *parent_sha,
@@ -519,7 +518,7 @@ void assert_conflict(
git_index *index;
git_object *hack_tree;
git_reference *branch, *head;
git_buf file_path = GIT_BUF_INIT;
git_str file_path = GIT_STR_INIT;
cl_git_pass(git_repository_index(&index, g_repo));
@@ -538,7 +537,7 @@ void assert_conflict(
g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
/* Hack-ishy workaound to ensure *all* the index entries
/* Hack-ishy workaround to ensure *all* the index entries
* match the content of the tree
*/
cl_git_pass(git_object_peel(&hack_tree, g_object, GIT_OBJECT_TREE));
@@ -549,9 +548,9 @@ void assert_conflict(
g_object = NULL;
/* Create a conflicting file */
cl_git_pass(git_buf_joinpath(&file_path, "./testrepo", entry_path));
cl_git_mkfile(git_buf_cstr(&file_path), new_content);
git_buf_dispose(&file_path);
cl_git_pass(git_str_joinpath(&file_path, "./testrepo", entry_path));
cl_git_mkfile(git_str_cstr(&file_path), new_content);
git_str_dispose(&file_path);
/* Trying to checkout the original commit */
cl_git_pass(git_revparse_single(&g_object, g_repo, commit_sha));
@@ -616,7 +615,7 @@ void test_checkout_tree__donot_update_deleted_file_by_default(void)
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_oid_fromstr(&old_id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
cl_git_pass(git_oid__fromstr(&old_id, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&old_commit, g_repo, &old_id));
cl_git_pass(git_reset(g_repo, (git_object *)old_commit, GIT_RESET_HARD, NULL));
@@ -624,9 +623,9 @@ void test_checkout_tree__donot_update_deleted_file_by_default(void)
cl_git_pass(git_index_remove_bypath(index ,"branch_file.txt"));
cl_git_pass(git_index_write(index));
cl_assert(!git_path_exists("testrepo/branch_file.txt"));
cl_assert(!git_fs_path_exists("testrepo/branch_file.txt"));
cl_git_pass(git_oid_fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff"));
cl_git_pass(git_oid__fromstr(&new_id, "099fabac3a9ea935598528c27f866e34089c2eff", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&new_commit, g_repo, &new_id));
@@ -687,16 +686,16 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
opts.notify_payload = &ca;
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_assert(!git_path_exists("testrepo/new.txt"));
cl_assert(!git_fs_path_exists("testrepo/new.txt"));
cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), -5555);
cl_assert(!git_path_exists("testrepo/new.txt"));
cl_assert(!git_fs_path_exists("testrepo/new.txt"));
/* on case-insensitive FS = a/b.txt, branch_file.txt, new.txt */
/* on case-sensitive FS = README, then above */
if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */
if (git_fs_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */
cl_assert_equal_i(3, ca.count);
else
cl_assert_equal_i(4, ca.count);
@@ -708,9 +707,9 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
cl_git_fail_with(git_checkout_tree(g_repo, obj, &opts), 123);
cl_assert(!git_path_exists("testrepo/new.txt"));
cl_assert(!git_fs_path_exists("testrepo/new.txt"));
if (git_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */
if (git_fs_path_exists("testrepo/.git/CoNfIg")) /* case insensitive */
cl_assert_equal_i(4, ca.count);
else
cl_assert_equal_i(1, ca.count);
@@ -800,7 +799,7 @@ void test_checkout_tree__can_write_to_empty_dirs(void)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_assert(git_path_isfile("testrepo/a/b.txt"));
cl_assert(git_fs_path_isfile("testrepo/a/b.txt"));
git_object_free(obj);
}
@@ -819,7 +818,7 @@ void test_checkout_tree__fails_when_dir_in_use(void)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_assert(git_path_isfile("testrepo/a/b.txt"));
cl_assert(git_fs_path_isfile("testrepo/a/b.txt"));
git_object_free(obj);
@@ -832,7 +831,7 @@ void test_checkout_tree__fails_when_dir_in_use(void)
cl_git_pass(p_chdir("../.."));
cl_assert(git_path_is_empty_dir("testrepo/a"));
cl_assert(git_fs_path_is_empty_dir("testrepo/a"));
git_object_free(obj);
#endif
@@ -853,7 +852,7 @@ void test_checkout_tree__can_continue_when_dir_in_use(void)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_assert(git_path_isfile("testrepo/a/b.txt"));
cl_assert(git_fs_path_isfile("testrepo/a/b.txt"));
git_object_free(obj);
@@ -866,7 +865,7 @@ void test_checkout_tree__can_continue_when_dir_in_use(void)
cl_git_pass(p_chdir("../.."));
cl_assert(git_path_is_empty_dir("testrepo/a"));
cl_assert(git_fs_path_is_empty_dir("testrepo/a"));
git_object_free(obj);
#endif
@@ -897,7 +896,7 @@ void test_checkout_tree__target_directory_from_bare(void)
cl_git_fail(git_checkout_tree(g_repo, g_object, &opts));
opts.target_directory = "alternative";
cl_assert(!git_path_isdir("alternative"));
cl_assert(!git_fs_path_isdir("alternative"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &opts));
@@ -917,19 +916,19 @@ void test_checkout_tree__extremely_long_file_name(void)
{
/* A utf-8 string with 83 characters, but 249 bytes. */
const char *longname = "\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97";
char path[1024];
char path[1024] = {0};
g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_revparse_single(&g_object, g_repo, "long-file-name"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
sprintf(path, "testrepo/%s.txt", longname);
cl_assert(git_path_exists(path));
cl_assert(git_fs_path_exists(path));
git_object_free(g_object);
cl_git_pass(git_revparse_single(&g_object, g_repo, "master"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &g_opts));
cl_assert(!git_path_exists(path));
cl_assert(!git_fs_path_exists(path));
}
static void create_conflict(const char *path)
@@ -942,16 +941,16 @@ static void create_conflict(const char *path)
memset(&entry, 0x0, sizeof(git_index_entry));
entry.mode = 0100644;
GIT_INDEX_ENTRY_STAGE_SET(&entry, 1);
git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46");
git_oid__fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46", GIT_OID_SHA1);
entry.path = path;
cl_git_pass(git_index_add(index, &entry));
GIT_INDEX_ENTRY_STAGE_SET(&entry, 2);
git_oid_fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf");
git_oid__fromstr(&entry.id, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", GIT_OID_SHA1);
cl_git_pass(git_index_add(index, &entry));
GIT_INDEX_ENTRY_STAGE_SET(&entry, 3);
git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863");
git_oid__fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", GIT_OID_SHA1);
cl_git_pass(git_index_add(index, &entry));
cl_git_pass(git_index_write(index));
@@ -989,7 +988,7 @@ void test_checkout_tree__filemode_preserved_in_index(void)
cl_git_pass(git_repository_index(&index, g_repo));
/* test a freshly added executable */
cl_git_pass(git_oid_fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
cl_git_pass(git_oid__fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1000,7 +999,7 @@ void test_checkout_tree__filemode_preserved_in_index(void)
/* Now start with a commit which has a text file */
cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9"));
cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1011,7 +1010,7 @@ void test_checkout_tree__filemode_preserved_in_index(void)
/* And then check out to a commit which converts the text file to an executable */
cl_git_pass(git_oid_fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e"));
cl_git_pass(git_oid__fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1022,7 +1021,7 @@ void test_checkout_tree__filemode_preserved_in_index(void)
/* Finally, check out the text file again and check that the exec bit is cleared */
cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9"));
cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1035,22 +1034,24 @@ void test_checkout_tree__filemode_preserved_in_index(void)
git_index_free(index);
}
mode_t read_filemode(const char *path)
#ifndef GIT_WIN32
static mode_t read_filemode(const char *path)
{
git_buf fullpath = GIT_BUF_INIT;
git_str fullpath = GIT_STR_INIT;
struct stat st;
mode_t result;
git_buf_joinpath(&fullpath, "testrepo", path);
git_str_joinpath(&fullpath, "testrepo", path);
cl_must_pass(p_stat(fullpath.ptr, &st));
result = GIT_PERMS_IS_EXEC(st.st_mode) ?
GIT_FILEMODE_BLOB_EXECUTABLE : GIT_FILEMODE_BLOB;
git_buf_dispose(&fullpath);
git_str_dispose(&fullpath);
return result;
}
#endif
void test_checkout_tree__filemode_preserved_in_workdir(void)
{
@@ -1062,7 +1063,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void)
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
/* test a freshly added executable */
cl_git_pass(git_oid_fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
cl_git_pass(git_oid__fromstr(&executable_oid, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1072,7 +1073,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void)
/* Now start with a commit which has a text file */
cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9"));
cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1082,7 +1083,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void)
/* And then check out to a commit which converts the text file to an executable */
cl_git_pass(git_oid_fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e"));
cl_git_pass(git_oid__fromstr(&executable_oid, "144344043ba4d4a405da03de3844aa829ae8be0e", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1092,7 +1093,7 @@ void test_checkout_tree__filemode_preserved_in_workdir(void)
/* Finally, check out the text file again and check that the exec bit is cleared */
cl_git_pass(git_oid_fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9"));
cl_git_pass(git_oid__fromstr(&executable_oid, "cf80f8de9f1185bf3a05f993f6121880dd0cfbc9", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &executable_oid));
cl_git_pass(git_checkout_tree(g_repo, (const git_object *)commit, &opts));
@@ -1111,7 +1112,7 @@ void test_checkout_tree__removes_conflicts(void)
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_index *index;
cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
cl_git_pass(git_oid__fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
@@ -1139,7 +1140,7 @@ void test_checkout_tree__removes_conflicts(void)
cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 2));
cl_assert_equal_p(NULL, git_index_get_bypath(index, "other.txt", 3));
cl_assert(!git_path_exists("testrepo/other.txt"));
cl_assert(!git_fs_path_exists("testrepo/other.txt"));
git_commit_free(commit);
git_index_free(index);
@@ -1154,7 +1155,7 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void)
git_index *index;
const char *path = "executable.txt";
cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
cl_git_pass(git_oid__fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6", GIT_OID_SHA1));
cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
@@ -1184,7 +1185,7 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void)
cl_assert(git_index_get_bypath(index, "other.txt", 2) != NULL);
cl_assert(git_index_get_bypath(index, "other.txt", 3) != NULL);
cl_assert(git_path_exists("testrepo/other.txt"));
cl_assert(git_fs_path_exists("testrepo/other.txt"));
git_commit_free(commit);
git_index_free(index);
@@ -1215,8 +1216,8 @@ void test_checkout_tree__case_changing_rename(void)
cl_git_pass(git_checkout_tree(g_repo, (git_object *)dir_commit, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
cl_assert(git_path_isfile("testrepo/README"));
case_sensitive = !git_path_isfile("testrepo/readme");
cl_assert(git_fs_path_isfile("testrepo/README"));
case_sensitive = !git_fs_path_isfile("testrepo/readme");
cl_assert(index_entry = git_index_get_bypath(index, "README", 0));
cl_assert_equal_s("README", index_entry->path);
@@ -1234,11 +1235,11 @@ void test_checkout_tree__case_changing_rename(void)
cl_git_pass(git_signature_new(&signature, "Renamer", "rename@contoso.com", time(NULL), 0));
cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, (const git_commit **)&dir_commit));
cl_git_pass(git_commit_create(&commit_id, g_repo, "refs/heads/dir", signature, signature, NULL, "case-changing rename", tree, 1, &dir_commit));
cl_assert(git_path_isfile("testrepo/readme"));
cl_assert(git_fs_path_isfile("testrepo/readme"));
if (case_sensitive)
cl_assert(!git_path_isfile("testrepo/README"));
cl_assert(!git_fs_path_isfile("testrepo/README"));
cl_assert(index_entry = git_index_get_bypath(index, "readme", 0));
cl_assert_equal_s("readme", index_entry->path);
@@ -1254,9 +1255,9 @@ void test_checkout_tree__case_changing_rename(void)
assert_on_branch(g_repo, "master");
cl_assert(git_path_isfile("testrepo/README"));
cl_assert(git_fs_path_isfile("testrepo/README"));
if (case_sensitive)
cl_assert(!git_path_isfile("testrepo/readme"));
cl_assert(!git_fs_path_isfile("testrepo/readme"));
cl_assert(index_entry = git_index_get_bypath(index, "README", 0));
cl_assert_equal_s("README", index_entry->path);
@@ -1268,7 +1269,7 @@ void test_checkout_tree__case_changing_rename(void)
git_commit_free(master_commit);
}
void perfdata_cb(const git_checkout_perfdata *in, void *payload)
static void perfdata_cb(const git_checkout_perfdata *in, void *payload)
{
memcpy(payload, in, sizeof(git_checkout_perfdata));
}
@@ -1297,7 +1298,7 @@ void test_checkout_tree__can_collect_perfdata(void)
git_object_free(obj);
}
void update_attr_callback(
static void update_attr_callback(
const char *path,
size_t completed_steps,
size_t total_steps,
@@ -1317,7 +1318,7 @@ void test_checkout_tree__caches_attributes_during_checkout(void)
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_oid oid;
git_object *obj = NULL;
git_buf ident1 = GIT_BUF_INIT, ident2 = GIT_BUF_INIT;
git_str ident1 = GIT_STR_INIT, ident2 = GIT_STR_INIT;
char *ident_paths[] = { "ident1.txt", "ident2.txt" };
opts.progress_cb = update_attr_callback;
@@ -1346,8 +1347,8 @@ void test_checkout_tree__caches_attributes_during_checkout(void)
cl_assert_equal_strn(ident1.ptr, "# $Id: ", 7);
cl_assert_equal_strn(ident2.ptr, "# $Id: ", 7);
git_buf_dispose(&ident1);
git_buf_dispose(&ident2);
git_str_dispose(&ident1);
git_str_dispose(&ident2);
git_object_free(obj);
}
@@ -1367,13 +1368,13 @@ void test_checkout_tree__can_not_update_index(void)
cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts));
cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/"));
cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &opts));
cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt"));
cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt"));
cl_assert_equal_i(GIT_STATUS_WT_NEW, status);
@@ -1404,13 +1405,13 @@ void test_checkout_tree__can_update_but_not_write_index(void)
cl_git_pass(git_reset(g_repo, head, GIT_RESET_HARD, &g_opts));
cl_assert_equal_i(false, git_path_isdir("./testrepo/ab/"));
cl_assert_equal_i(false, git_fs_path_isdir("./testrepo/ab/"));
cl_git_pass(git_revparse_single(&g_object, g_repo, "subtrees"));
cl_git_pass(git_checkout_tree(g_repo, g_object, &opts));
cl_assert_equal_i(true, git_path_isfile("./testrepo/ab/de/2.txt"));
cl_assert_equal_i(true, git_fs_path_isfile("./testrepo/ab/de/2.txt"));
cl_git_pass(git_status_file(&status, g_repo, "ab/de/2.txt"));
cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status);
@@ -1451,15 +1452,15 @@ void test_checkout_tree__safe_proceeds_if_no_index(void)
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees"));
cl_assert(git_path_isfile("testrepo/README"));
cl_assert(git_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_path_isfile("testrepo/new.txt"));
cl_assert(git_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_path_isfile("testrepo/ab/c/3.txt"));
cl_assert(git_path_isfile("testrepo/ab/de/2.txt"));
cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt"));
cl_assert(git_fs_path_isfile("testrepo/README"));
cl_assert(git_fs_path_isfile("testrepo/branch_file.txt"));
cl_assert(git_fs_path_isfile("testrepo/new.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/4.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/c/3.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/de/2.txt"));
cl_assert(git_fs_path_isfile("testrepo/ab/de/fgh/1.txt"));
cl_assert(!git_path_isdir("testrepo/a"));
cl_assert(!git_fs_path_isdir("testrepo/a"));
assert_on_branch(g_repo, "subtrees");
@@ -1582,7 +1583,7 @@ static void modify_index_ondisk(void)
cl_git_pass(git_repository_open(&other_repo, git_repository_workdir(g_repo)));
cl_git_pass(git_repository_index(&other_index, other_repo));
cl_git_pass(git_oid_fromstr(&entry.id, "1385f264afb75a56a5bec74243be9b367ba4ca08"));
cl_git_pass(git_oid__fromstr(&entry.id, "1385f264afb75a56a5bec74243be9b367ba4ca08", GIT_OID_SHA1));
entry.mode = 0100644;
entry.path = "README";
@@ -1636,3 +1637,49 @@ void test_checkout_tree__no_index_refresh(void)
modify_index_and_checkout_tree(&opts);
assert_status_entrycount(g_repo, 0);
}
void test_checkout_tree__dry_run(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_oid oid;
git_object *obj = NULL;
checkout_counts ct;
/* first let's get things into a known state - by checkout out the HEAD */
assert_on_branch(g_repo, "master");
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert(!git_fs_path_isdir("testrepo/a"));
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
/* now checkout branch but with dry run enabled */
memset(&ct, 0, sizeof(ct));
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_DRY_RUN;
opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
opts.notify_cb = checkout_count_callback;
opts.notify_payload = &ct;
cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJECT_ANY));
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/dir"));
assert_on_branch(g_repo, "dir");
/* these normally would have been created and updated, but with
* DRY_RUN they will be unchanged.
*/
cl_assert(!git_fs_path_isdir("testrepo/a"));
check_file_contents_nocr("testrepo/branch_file.txt", "hi\nbye!\n");
/* check that notify callback was invoked */
cl_assert_equal_i(ct.n_updates, 2);
git_object_free(obj);
}

View File

@@ -76,12 +76,12 @@ void test_checkout_typechange__cleanup(void)
static void assert_file_exists(const char *path)
{
cl_assert_(git_path_isfile(path), path);
cl_assert_(git_fs_path_isfile(path), path);
}
static void assert_dir_exists(const char *path)
{
cl_assert_(git_path_isdir(path), path);
cl_assert_(git_fs_path_isdir(path), path);
}
static void assert_workdir_matches_tree(
@@ -90,7 +90,7 @@ static void assert_workdir_matches_tree(
git_object *obj;
git_tree *tree;
size_t i, max_i;
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
if (!root)
root = git_repository_workdir(repo);
@@ -106,7 +106,7 @@ static void assert_workdir_matches_tree(
const git_tree_entry *te = git_tree_entry_byindex(tree, i);
cl_assert(te);
cl_git_pass(git_buf_joinpath(&path, root, git_tree_entry_name(te)));
cl_git_pass(git_str_joinpath(&path, root, git_tree_entry_name(te)));
switch (git_tree_entry_type(te)) {
case GIT_OBJECT_COMMIT:
@@ -126,7 +126,7 @@ static void assert_workdir_matches_tree(
/* because of cross-platform, don't confirm exec bit yet */
break;
case GIT_FILEMODE_LINK:
cl_assert_(git_path_exists(path.ptr), path.ptr);
cl_assert_(git_fs_path_exists(path.ptr), path.ptr);
/* because of cross-platform, don't confirm link yet */
break;
default:
@@ -139,7 +139,7 @@ static void assert_workdir_matches_tree(
}
git_tree_free(tree);
git_buf_dispose(&path);
git_str_dispose(&path);
}
void test_checkout_typechange__checkout_typechanges_safe(void)
@@ -163,19 +163,19 @@ void test_checkout_typechange__checkout_typechanges_safe(void)
git_object_free(obj);
if (!g_typechange_empty[i]) {
cl_assert(git_path_isdir("typechanges"));
cl_assert(git_path_exists("typechanges/a"));
cl_assert(git_path_exists("typechanges/b"));
cl_assert(git_path_exists("typechanges/c"));
cl_assert(git_path_exists("typechanges/d"));
cl_assert(git_path_exists("typechanges/e"));
cl_assert(git_fs_path_isdir("typechanges"));
cl_assert(git_fs_path_exists("typechanges/a"));
cl_assert(git_fs_path_exists("typechanges/b"));
cl_assert(git_fs_path_exists("typechanges/c"));
cl_assert(git_fs_path_exists("typechanges/d"));
cl_assert(git_fs_path_exists("typechanges/e"));
} else {
cl_assert(git_path_isdir("typechanges"));
cl_assert(!git_path_exists("typechanges/a"));
cl_assert(!git_path_exists("typechanges/b"));
cl_assert(!git_path_exists("typechanges/c"));
cl_assert(!git_path_exists("typechanges/d"));
cl_assert(!git_path_exists("typechanges/e"));
cl_assert(git_fs_path_isdir("typechanges"));
cl_assert(!git_fs_path_exists("typechanges/a"));
cl_assert(!git_fs_path_exists("typechanges/b"));
cl_assert(!git_fs_path_exists("typechanges/c"));
cl_assert(!git_fs_path_exists("typechanges/d"));
cl_assert(!git_fs_path_exists("typechanges/e"));
}
}
}
@@ -226,31 +226,31 @@ static void force_create_file(const char *file)
static int make_submodule_dirty(git_submodule *sm, const char *name, void *payload)
{
git_buf submodulepath = GIT_BUF_INIT;
git_buf dirtypath = GIT_BUF_INIT;
git_str submodulepath = GIT_STR_INIT;
git_str dirtypath = GIT_STR_INIT;
git_repository *submodule_repo;
GIT_UNUSED(name);
GIT_UNUSED(payload);
/* remove submodule directory in preparation for init and repo_init */
cl_git_pass(git_buf_joinpath(
cl_git_pass(git_str_joinpath(
&submodulepath,
git_repository_workdir(g_repo),
git_submodule_path(sm)
));
git_futils_rmdir_r(git_buf_cstr(&submodulepath), NULL, GIT_RMDIR_REMOVE_FILES);
git_futils_rmdir_r(git_str_cstr(&submodulepath), NULL, GIT_RMDIR_REMOVE_FILES);
/* initialize submodule's repository */
cl_git_pass(git_submodule_repo_init(&submodule_repo, sm, 0));
/* create a file in the submodule workdir to make it dirty */
cl_git_pass(
git_buf_joinpath(&dirtypath, git_repository_workdir(submodule_repo), "dirty"));
force_create_file(git_buf_cstr(&dirtypath));
git_str_joinpath(&dirtypath, git_repository_workdir(submodule_repo), "dirty"));
force_create_file(git_str_cstr(&dirtypath));
git_buf_dispose(&dirtypath);
git_buf_dispose(&submodulepath);
git_str_dispose(&dirtypath);
git_str_dispose(&submodulepath);
git_repository_free(submodule_repo);
return 0;
@@ -293,12 +293,12 @@ void test_checkout_typechange__checkout_with_conflicts(void)
GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
memset(&cts, 0, sizeof(cts));
cl_assert(git_path_exists("typechanges/untracked"));
cl_assert(git_fs_path_exists("typechanges/untracked"));
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
cl_assert_equal_i(0, cts.conflicts);
cl_assert(!git_path_exists("typechanges/untracked"));
cl_assert(!git_fs_path_exists("typechanges/untracked"));
cl_git_pass(
git_repository_set_head_detached(g_repo, git_object_id(obj)));
@@ -319,7 +319,7 @@ void test_checkout_typechange__status_char(void)
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
char expected[8] = {'M', 'M', 'R', 'T', 'D', 'R', 'A', 'R'};
git_oid_fromstr(&oid, "9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a");
git_oid__fromstr(&oid, "9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
diffopts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
cl_git_pass(git_diff__commit(&diff, g_repo, commit, &diffopts));

View File

@@ -1,7 +1,6 @@
#include "clar.h"
#include "clar_libgit2.h"
#include "buffer.h"
#include "futils.h"
#include "git2/cherrypick.h"
@@ -33,10 +32,10 @@ void test_cherrypick_bare__automerge(void)
{ 0100644, "df6b290e0bd6a89b01d69f66687e8abf385283ca", 0, "file3.txt" },
};
git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
git_oid__fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
git_oid_fromstr(&cherry_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
git_oid__fromstr(&cherry_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL));
@@ -63,10 +62,10 @@ void test_cherrypick_bare__conflicts(void)
{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
};
git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
git_oid__fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
git_oid__fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL));
@@ -90,10 +89,10 @@ void test_cherrypick_bare__orphan(void)
{ 0100644, "9ccb9bf50c011fd58dcbaa65df917bf79539717f", 0, "orphan.txt" },
};
git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
git_oid__fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
git_oid_fromstr(&cherry_oid, "74f06b5bfec6d33d7264f73606b57a7c0b963819");
git_oid__fromstr(&cherry_oid, "74f06b5bfec6d33d7264f73606b57a7c0b963819", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick_commit(&index, repo, commit, head, 0, NULL));

View File

@@ -1,7 +1,6 @@
#include "clar.h"
#include "clar_libgit2.h"
#include "buffer.h"
#include "futils.h"
#include "git2/cherrypick.h"
@@ -58,7 +57,7 @@ void test_cherrypick_workdir__automerge(void)
cl_git_pass(git_signature_new(&signature, "Picker", "picker@example.org", time(NULL), 0));
git_oid_fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e");
git_oid__fromstr(&head_oid, "d3d77487660ee3c0194ee01dc5eaf478782b1c7e", GIT_OID_SHA1);
for (i = 0; i < 3; ++i) {
git_commit *head = NULL, *commit = NULL;
@@ -68,17 +67,17 @@ void test_cherrypick_workdir__automerge(void)
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, cherrypick_oids[i]);
git_oid__fromstr(&cherry_oid, cherrypick_oids[i], GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, NULL));
cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_git_pass(git_index_write_tree(&cherrypicked_tree_oid, repo_index));
cl_git_pass(git_tree_lookup(&cherrypicked_tree, repo, &cherrypicked_tree_oid));
cl_git_pass(git_commit_create(&cherrypicked_oid, repo, "HEAD", signature, signature, NULL,
"Cherry picked!", cherrypicked_tree, 1, (const git_commit **)&head));
"Cherry picked!", cherrypicked_tree, 1, &head));
cl_assert(merge_test_index(repo_index, merge_index_entries + i * 3, 3));
@@ -111,16 +110,16 @@ void test_cherrypick_workdir__empty_result(void)
cl_git_pass(git_signature_new(&signature, "Picker", "picker@example.org", time(NULL), 0));
git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1);
/* Create an untracked file that should not conflict */
cl_git_mkfile(TEST_REPO_PATH "/file4.txt", "");
cl_assert(git_path_exists(TEST_REPO_PATH "/file4.txt"));
cl_assert(git_fs_path_exists(TEST_REPO_PATH "/file4.txt"));
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, cherrypick_oid);
git_oid__fromstr(&cherry_oid, cherrypick_oid, GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, NULL));
@@ -140,7 +139,7 @@ void test_cherrypick_workdir__conflicts(void)
{
git_commit *head = NULL, *commit = NULL;
git_oid head_oid, cherry_oid;
git_buf conflicting_buf = GIT_BUF_INIT, mergemsg_buf = GIT_BUF_INIT;
git_str conflicting_buf = GIT_STR_INIT, mergemsg_buf = GIT_STR_INIT;
struct merge_index_entry merge_index_entries[] = {
{ 0100644, "242e7977ba73637822ffb265b46004b9b0e5153b", 0, "file1.txt" },
@@ -152,33 +151,33 @@ void test_cherrypick_workdir__conflicts(void)
{ 0100644, "e233b9ed408a95e9d4b65fec7fc34943a556deb2", 3, "file3.txt" },
};
git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
git_oid__fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
git_oid__fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, NULL));
cl_assert(git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(merge_test_index(repo_index, merge_index_entries, 7));
cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
cl_assert(strcmp(git_str_cstr(&mergemsg_buf),
"Change all files\n" \
"\n" \
"Conflicts:\n" \
"\tfile2.txt\n" \
"\tfile3.txt\n") == 0);
"#Conflicts:\n" \
"#\tfile2.txt\n" \
"#\tfile3.txt\n") == 0);
cl_git_pass(git_futils_readbuffer(&conflicting_buf,
TEST_REPO_PATH "/file2.txt"));
cl_assert(strcmp(git_buf_cstr(&conflicting_buf),
cl_assert(strcmp(git_str_cstr(&conflicting_buf),
"!File 2\n" \
"File 2\n" \
"File 2\n" \
@@ -204,7 +203,7 @@ void test_cherrypick_workdir__conflicts(void)
cl_git_pass(git_futils_readbuffer(&conflicting_buf,
TEST_REPO_PATH "/file3.txt"));
cl_assert(strcmp(git_buf_cstr(&conflicting_buf),
cl_assert(strcmp(git_str_cstr(&conflicting_buf),
"!File 3\n" \
"File 3\n" \
"File 3\n" \
@@ -228,8 +227,8 @@ void test_cherrypick_workdir__conflicts(void)
git_commit_free(commit);
git_commit_free(head);
git_buf_dispose(&mergemsg_buf);
git_buf_dispose(&conflicting_buf);
git_str_dispose(&mergemsg_buf);
git_str_dispose(&conflicting_buf);
}
/* git reset --hard bafbf6912c09505ac60575cd43d3f2aba3bd84d8
@@ -260,12 +259,12 @@ void test_cherrypick_workdir__conflict_use_ours(void)
/* leave the index in a conflicted state, but checkout "ours" to the workdir */
opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_USE_OURS;
git_oid_fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8");
git_oid__fromstr(&head_oid, "bafbf6912c09505ac60575cd43d3f2aba3bd84d8", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110");
git_oid__fromstr(&cherry_oid, "e9b63f3655b2ad80c0ff587389b5a9589a3a7110", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, &opts));
@@ -303,11 +302,11 @@ void test_cherrypick_workdir__rename(void)
opts.merge_opts.flags |= GIT_MERGE_FIND_RENAMES;
opts.merge_opts.rename_threshold = 50;
git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc");
git_oid__fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, &opts));
@@ -324,7 +323,7 @@ void test_cherrypick_workdir__both_renamed(void)
{
git_commit *head, *commit;
git_oid head_oid, cherry_oid;
git_buf mergemsg_buf = GIT_BUF_INIT;
git_str mergemsg_buf = GIT_STR_INIT;
git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
struct merge_index_entry merge_index_entries[] = {
@@ -338,11 +337,11 @@ void test_cherrypick_workdir__both_renamed(void)
opts.merge_opts.flags |= GIT_MERGE_FIND_RENAMES;
opts.merge_opts.rename_threshold = 50;
git_oid_fromstr(&head_oid, "44cd2ed2052c9c68f9a439d208e9614dc2a55c70");
git_oid__fromstr(&head_oid, "44cd2ed2052c9c68f9a439d208e9614dc2a55c70", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc");
git_oid__fromstr(&cherry_oid, "2a26c7e88b285613b302ba76712bc998863f3cbc", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, &opts));
@@ -350,15 +349,15 @@ void test_cherrypick_workdir__both_renamed(void)
cl_git_pass(git_futils_readbuffer(&mergemsg_buf,
TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(strcmp(git_buf_cstr(&mergemsg_buf),
cl_assert(strcmp(git_str_cstr(&mergemsg_buf),
"Renamed file3.txt -> file3.txt.renamed\n" \
"\n" \
"Conflicts:\n" \
"\tfile3.txt\n" \
"\tfile3.txt.renamed\n" \
"\tfile3.txt.renamed_on_branch\n") == 0);
"#Conflicts:\n" \
"#\tfile3.txt\n" \
"#\tfile3.txt.renamed\n" \
"#\tfile3.txt.renamed_on_branch\n") == 0);
git_buf_dispose(&mergemsg_buf);
git_str_dispose(&mergemsg_buf);
git_commit_free(commit);
git_commit_free(head);
}
@@ -374,8 +373,8 @@ void test_cherrypick_workdir__nonmerge_fails_mainline_specified(void)
opts.mainline = 1;
cl_must_fail(git_cherrypick(repo, commit, &opts));
cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
git_reference_free(head);
git_commit_free(commit);
@@ -389,16 +388,16 @@ void test_cherrypick_workdir__merge_fails_without_mainline_specified(void)
git_commit *head, *commit;
git_oid head_oid, cherry_oid;
git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
git_oid__fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_must_fail(git_cherrypick(repo, commit, NULL));
cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(!git_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/CHERRY_PICK_HEAD"));
cl_assert(!git_fs_path_exists(TEST_REPO_PATH "/.git/MERGE_MSG"));
git_commit_free(commit);
git_commit_free(head);
@@ -421,11 +420,11 @@ void test_cherrypick_workdir__merge_first_parent(void)
opts.mainline = 1;
git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
git_oid__fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, &opts));
@@ -453,11 +452,11 @@ void test_cherrypick_workdir__merge_second_parent(void)
opts.mainline = 2;
git_oid_fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15");
git_oid__fromstr(&head_oid, "cfc4f0999a8367568e049af4f72e452d40828a15", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&head, repo, &head_oid));
cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));
git_oid_fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff");
git_oid__fromstr(&cherry_oid, "abe4603bc7cd5b8167a267e0e2418fd2348f8cff", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, repo, &cherry_oid));
cl_git_pass(git_cherrypick(repo, commit, &opts));

View File

@@ -2,6 +2,7 @@
#include "git2/clone.h"
#include "repository.h"
#include "repo/repo_helpers.h"
static git_clone_options g_options;
static git_repository *g_repo;
@@ -22,6 +23,7 @@ void test_clone_empty__initialize(void)
void test_clone_empty__cleanup(void)
{
cl_fixture_cleanup("tmp_global_path");
cl_git_sandbox_cleanup();
}
@@ -66,6 +68,21 @@ void test_clone_empty__can_clone_an_empty_local_repo_barely(void)
expected_tracked_branch_name));
}
void test_clone_empty__respects_initialbranch_config(void)
{
git_buf buf = GIT_BUF_INIT;
create_tmp_global_config("tmp_global_path", "init.defaultbranch", "my_default_branch");
cl_set_cleanup(&cleanup_repository, "./empty");
g_options.bare = true;
cl_git_pass(git_clone(&g_repo_cloned, "./empty_bare.git", "./empty", &g_options));
cl_git_pass(git_branch_upstream_name(&buf, g_repo_cloned, "refs/heads/my_default_branch"));
cl_assert_equal_s("refs/remotes/origin/my_default_branch", buf.ptr);
git_buf_dispose(&buf);
}
void test_clone_empty__can_clone_an_empty_local_repo(void)
{
cl_set_cleanup(&cleanup_repository, "./empty");

View File

@@ -2,42 +2,41 @@
#include "git2/clone.h"
#include "clone.h"
#include "buffer.h"
#include "path.h"
#include "posix.h"
#include "futils.h"
static int file_url(git_buf *buf, const char *host, const char *path)
static int file_url(git_str *buf, const char *host, const char *path)
{
if (path[0] == '/')
path++;
git_buf_clear(buf);
return git_buf_printf(buf, "file://%s/%s", host, path);
git_str_clear(buf);
return git_str_printf(buf, "file://%s/%s", host, path);
}
#ifdef GIT_WIN32
static int git_style_unc_path(git_buf *buf, const char *host, const char *path)
static int git_style_unc_path(git_str *buf, const char *host, const char *path)
{
git_buf_clear(buf);
git_str_clear(buf);
if (host)
git_buf_printf(buf, "//%s/", host);
git_str_printf(buf, "//%s/", host);
if (path[0] == '/')
path++;
if (git__isalpha(path[0]) && path[1] == ':' && path[2] == '/') {
git_buf_printf(buf, "%c$/", path[0]);
git_str_printf(buf, "%c$/", path[0]);
path += 3;
}
git_buf_puts(buf, path);
git_str_puts(buf, path);
return git_buf_oom(buf) ? -1 : 0;
return git_str_oom(buf) ? -1 : 0;
}
static int unc_path(git_buf *buf, const char *host, const char *path)
static int unc_path(git_str *buf, const char *host, const char *path)
{
char *c;
@@ -54,7 +53,7 @@ static int unc_path(git_buf *buf, const char *host, const char *path)
void test_clone_local__should_clone_local(void)
{
git_buf buf = GIT_BUF_INIT;
git_str buf = GIT_STR_INIT;
/* we use a fixture path because it needs to exist for us to want to clone */
const char *path = cl_fixture("testrepo.git");
@@ -79,8 +78,8 @@ void test_clone_local__should_clone_local(void)
/* Ensure that file:/// urls are percent decoded: .git == %2e%67%69%74 */
cl_git_pass(file_url(&buf, "", path));
git_buf_shorten(&buf, 4);
cl_git_pass(git_buf_puts(&buf, "%2e%67%69%74"));
git_str_shorten(&buf, 4);
cl_git_pass(git_str_puts(&buf, "%2e%67%69%74"));
cl_assert_equal_i(0, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_AUTO));
cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL));
cl_assert_equal_i(1, git_clone__should_clone_local(buf.ptr, GIT_CLONE_LOCAL_NO_LINKS));
@@ -91,14 +90,14 @@ void test_clone_local__should_clone_local(void)
cl_assert_equal_i(1, git_clone__should_clone_local(path, GIT_CLONE_LOCAL_NO_LINKS));
cl_assert_equal_i(0, git_clone__should_clone_local(path, GIT_CLONE_NO_LOCAL));
git_buf_dispose(&buf);
git_str_dispose(&buf);
}
void test_clone_local__hardlinks(void)
{
git_repository *repo;
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
git_buf buf = GIT_BUF_INIT;
git_str buf = GIT_STR_INIT;
struct stat st;
/*
@@ -117,21 +116,21 @@ void test_clone_local__hardlinks(void)
cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone2.git", &opts));
#ifndef GIT_WIN32
git_buf_clear(&buf);
cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
git_str_clear(&buf);
cl_git_pass(git_str_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
cl_git_pass(p_stat(buf.ptr, &st));
cl_assert_equal_i(2, st.st_nlink);
#endif
git_repository_free(repo);
git_buf_clear(&buf);
git_str_clear(&buf);
opts.local = GIT_CLONE_LOCAL_NO_LINKS;
cl_git_pass(git_clone(&repo, cl_git_path_url("clone.git"), "./clone3.git", &opts));
git_buf_clear(&buf);
cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
git_str_clear(&buf);
cl_git_pass(git_str_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
cl_git_pass(p_stat(buf.ptr, &st));
cl_assert_equal_i(1, st.st_nlink);
@@ -142,14 +141,14 @@ void test_clone_local__hardlinks(void)
cl_git_pass(git_clone(&repo, "./clone.git", "./clone4.git", NULL));
#ifndef GIT_WIN32
git_buf_clear(&buf);
cl_git_pass(git_buf_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
git_str_clear(&buf);
cl_git_pass(git_str_join_n(&buf, '/', 4, git_repository_path(repo), "objects", "08", "b041783f40edfe12bb406c9c9a8a040177c125"));
cl_git_pass(p_stat(buf.ptr, &st));
cl_assert_equal_i(3, st.st_nlink);
#endif
git_buf_dispose(&buf);
git_str_dispose(&buf);
git_repository_free(repo);
cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
@@ -164,7 +163,7 @@ void test_clone_local__standard_unc_paths_are_written_git_style(void)
git_repository *repo;
git_remote *remote;
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
git_buf unc = GIT_BUF_INIT, git_unc = GIT_BUF_INIT;
git_str unc = GIT_STR_INIT, git_unc = GIT_STR_INIT;
/* we use a fixture path because it needs to exist for us to want to clone */
const char *path = cl_fixture("testrepo.git");
@@ -179,8 +178,8 @@ void test_clone_local__standard_unc_paths_are_written_git_style(void)
git_remote_free(remote);
git_repository_free(repo);
git_buf_dispose(&unc);
git_buf_dispose(&git_unc);
git_str_dispose(&unc);
git_str_dispose(&git_unc);
cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
#endif
@@ -192,7 +191,7 @@ void test_clone_local__git_style_unc_paths(void)
git_repository *repo;
git_remote *remote;
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
git_buf git_unc = GIT_BUF_INIT;
git_str git_unc = GIT_STR_INIT;
/* we use a fixture path because it needs to exist for us to want to clone */
const char *path = cl_fixture("testrepo.git");
@@ -206,7 +205,7 @@ void test_clone_local__git_style_unc_paths(void)
git_remote_free(remote);
git_repository_free(repo);
git_buf_dispose(&git_unc);
git_str_dispose(&git_unc);
cl_git_pass(git_futils_rmdir_r("./clone.git", NULL, GIT_RMDIR_REMOVE_FILES));
#endif

View File

@@ -5,6 +5,7 @@
#include "remote.h"
#include "futils.h"
#include "repository.h"
#include "index.h"
#define LIVE_REPO_URL "git://github.com/libgit2/TestGitRepository"
@@ -51,10 +52,10 @@ void test_clone_nonetwork__bad_urls(void)
{
/* Clone should clean up the mess if the URL isn't a git repository */
cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
cl_assert(!git_path_exists("./foo"));
cl_assert(!git_fs_path_exists("./foo"));
g_options.bare = true;
cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
cl_assert(!git_path_exists("./foo"));
cl_assert(!git_fs_path_exists("./foo"));
cl_git_fail(git_clone(&g_repo, "git://example.com:asdf", "./foo", &g_options));
cl_git_fail(git_clone(&g_repo, "https://example.com:asdf/foo", "./foo", &g_options));
@@ -70,12 +71,12 @@ void test_clone_nonetwork__do_not_clean_existing_directory(void)
* Should clean up entries it creates. */
p_mkdir("./foo", GIT_DIR_MODE);
cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
cl_assert(git_path_is_empty_dir("./foo"));
cl_assert(git_fs_path_is_empty_dir("./foo"));
/* Try again with a bare repository. */
g_options.bare = true;
cl_git_fail(git_clone(&g_repo, "not_a_repo", "./foo", &g_options));
cl_assert(git_path_is_empty_dir("./foo"));
cl_assert(git_fs_path_is_empty_dir("./foo"));
}
void test_clone_nonetwork__local(void)
@@ -109,7 +110,7 @@ void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(vo
cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
}
int custom_origin_name_remote_create(
static int custom_origin_name_remote_create(
git_remote **out,
git_repository *repo,
const char *name,
@@ -145,19 +146,21 @@ void test_clone_nonetwork__cope_with_already_existing_directory(void)
void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
g_options.checkout_opts.checkout_strategy = 0;
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&path)));
cl_git_pass(git_str_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
cl_assert_equal_i(false, git_fs_path_isfile(git_str_cstr(&path)));
git_buf_dispose(&path);
git_str_dispose(&path);
}
void test_clone_nonetwork__can_checkout_given_branch(void)
{
git_reference *remote_head;
g_options.checkout_branch = "test";
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
@@ -166,7 +169,13 @@ void test_clone_nonetwork__can_checkout_given_branch(void)
cl_git_pass(git_repository_head(&g_ref, g_repo));
cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test");
cl_assert(git_path_exists("foo/readme.txt"));
cl_assert(git_fs_path_exists("foo/readme.txt"));
cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD"));
cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head));
cl_assert_equal_s("refs/remotes/origin/master", git_reference_symbolic_target(remote_head));
git_reference_free(remote_head);
}
static int clone_cancel_fetch_transfer_progress_cb(
@@ -188,7 +197,7 @@ void test_clone_nonetwork__can_cancel_clone_in_fetch(void)
-54321);
cl_assert(!g_repo);
cl_assert(!git_path_exists("foo/readme.txt"));
cl_assert(!git_fs_path_exists("foo/readme.txt"));
}
static int clone_cancel_checkout_cb(
@@ -219,7 +228,7 @@ void test_clone_nonetwork__can_cancel_clone_in_checkout(void)
-12345);
cl_assert(!g_repo);
cl_assert(!git_path_exists("foo/readme.txt"));
cl_assert(!git_fs_path_exists("foo/readme.txt"));
}
void test_clone_nonetwork__can_detached_head(void)
@@ -263,7 +272,7 @@ void test_clone_nonetwork__clone_tag_to_tree(void)
stage = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_repository_odb(&odb, stage));
cl_git_pass(git_index_new(&index));
cl_git_pass(git_index__new(&index, GIT_OID_SHA1));
memset(&entry, 0, sizeof(git_index_entry));
entry.path = file_path;
@@ -296,9 +305,9 @@ static void assert_correct_reflog(const char *name)
{
git_reflog *log;
const git_reflog_entry *entry;
git_buf expected_message = GIT_BUF_INIT;
git_str expected_message = GIT_STR_INIT;
git_buf_printf(&expected_message,
git_str_printf(&expected_message,
"clone: from %s", cl_git_fixture_url("testrepo.git"));
cl_git_pass(git_reflog_read(&log, g_repo, name));
@@ -308,7 +317,7 @@ static void assert_correct_reflog(const char *name)
git_reflog_free(log);
git_buf_dispose(&expected_message);
git_str_dispose(&expected_message);
}
void test_clone_nonetwork__clone_updates_reflog_properly(void)

View File

@@ -26,21 +26,21 @@ void test_commit_commit__create_unexisting_update_ref(void)
git_signature *s;
git_reference *ref;
git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
git_oid__fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OID_SHA1);
cl_git_pass(git_tree_lookup(&tree, _repo, &oid));
cl_git_pass(git_signature_now(&s, "alice", "alice@example.com"));
cl_git_fail(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar"));
cl_git_pass(git_commit_create(&oid, _repo, "refs/heads/foo/bar", s, s,
NULL, "some msg", tree, 1, (const git_commit **) &commit));
NULL, "some msg", tree, 1, &commit));
/* fail because the parent isn't the tip of the branch anymore */
cl_git_fail(git_commit_create(&oid, _repo, "refs/heads/foo/bar", s, s,
NULL, "some msg", tree, 1, (const git_commit **) &commit));
NULL, "some msg", tree, 1, &commit));
cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/foo/bar"));
cl_assert_equal_oid(&oid, git_reference_target(ref));
@@ -59,10 +59,10 @@ void test_commit_commit__create_initial_commit(void)
git_signature *s;
git_reference *ref;
git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
git_oid__fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OID_SHA1);
cl_git_pass(git_tree_lookup(&tree, _repo, &oid));
cl_git_pass(git_signature_now(&s, "alice", "alice@example.com"));
@@ -89,10 +89,10 @@ void test_commit_commit__create_initial_commit_parent_not_current(void)
git_commit *commit;
git_signature *s;
git_oid_fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
git_oid__fromstr(&oid, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
git_oid_fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
git_oid__fromstr(&oid, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162", GIT_OID_SHA1);
cl_git_pass(git_tree_lookup(&tree, _repo, &oid));
cl_git_pass(git_signature_now(&s, "alice", "alice@example.com"));
@@ -111,7 +111,7 @@ void test_commit_commit__create_initial_commit_parent_not_current(void)
git_signature_free(s);
}
void assert_commit_summary(const char *expected, const char *given)
static void assert_commit_summary(const char *expected, const char *given)
{
git_commit *dummy;
@@ -123,7 +123,7 @@ void assert_commit_summary(const char *expected, const char *given)
git_commit__free(dummy);
}
void assert_commit_body(const char *expected, const char *given)
static void assert_commit_body(const char *expected, const char *given)
{
git_commit *dummy;
@@ -139,8 +139,11 @@ void test_commit_commit__summary(void)
{
assert_commit_summary("One-liner with no trailing newline", "One-liner with no trailing newline");
assert_commit_summary("One-liner with trailing newline", "One-liner with trailing newline\n");
assert_commit_summary("One-liner with trailing newline and space", "One-liner with trailing newline and space\n ");
assert_commit_summary("Trimmed leading&trailing newlines", "\n\nTrimmed leading&trailing newlines\n\n");
assert_commit_summary("First paragraph only", "\nFirst paragraph only\n\n(There are more!)");
assert_commit_summary("First paragraph only with space in the next line", "\nFirst paragraph only with space in the next line\n \n(There are more!)");
assert_commit_summary("First paragraph only with spaces in the next line", "\nFirst paragraph only with spaces in the next line\n \n(There are more!)");
assert_commit_summary("First paragraph with unwrapped trailing\tlines", "\nFirst paragraph\nwith unwrapped\ntrailing\tlines\n\n(Yes, unwrapped!)");
assert_commit_summary("\tLeading tabs", "\tLeading\n\ttabs\n\nare preserved"); /* tabs around newlines are collapsed down to a single space */
assert_commit_summary(" Leading Spaces", " Leading\n Spaces\n\nare preserved"); /* spaces around newlines are collapsed down to a single space */

View File

@@ -0,0 +1,112 @@
#include "clar_libgit2.h"
#include "repository.h"
/* Fixture setup */
static git_repository *g_repo;
static git_signature *g_author, *g_committer;
void test_commit_create__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo2");
cl_git_pass(git_signature_new(&g_author, "Edward Thomson", "ethomson@edwardthomson.com", 123456789, 60));
cl_git_pass(git_signature_new(&g_committer, "libgit2 user", "nobody@noreply.libgit2.org", 987654321, 90));
}
void test_commit_create__cleanup(void)
{
git_signature_free(g_committer);
git_signature_free(g_author);
cl_git_sandbox_cleanup();
}
void test_commit_create__from_stage_simple(void)
{
git_commit_create_options opts = GIT_COMMIT_CREATE_OPTIONS_INIT;
git_index *index;
git_oid commit_id;
git_tree *tree;
opts.author = g_author;
opts.committer = g_committer;
cl_git_rewritefile("testrepo2/newfile.txt", "This is a new file.\n");
cl_git_rewritefile("testrepo2/newfile2.txt", "This is a new file.\n");
cl_git_rewritefile("testrepo2/README", "hello, world.\n");
cl_git_rewritefile("testrepo2/new.txt", "hi there.\n");
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_add_bypath(index, "newfile2.txt"));
cl_git_pass(git_index_add_bypath(index, "README"));
cl_git_pass(git_index_write(index));
cl_git_pass(git_commit_create_from_stage(&commit_id, g_repo, "This is the message.", &opts));
cl_git_pass(git_repository_head_tree(&tree, g_repo));
cl_assert_equal_oidstr("241b5b04e847bc38dd7b4b9f49f21e55da40f3a6", &commit_id);
cl_assert_equal_oidstr("b27210772d0633870b4f486d04ed3eb5ebbef5e7", git_tree_id(tree));
git_index_free(index);
git_tree_free(tree);
}
void test_commit_create__from_stage_nochanges(void)
{
git_commit_create_options opts = GIT_COMMIT_CREATE_OPTIONS_INIT;
git_oid commit_id;
git_tree *tree;
opts.author = g_author;
opts.committer = g_committer;
cl_git_fail_with(GIT_EUNCHANGED, git_commit_create_from_stage(&commit_id, g_repo, "Message goes here.", &opts));
opts.allow_empty_commit = 1;
cl_git_pass(git_commit_create_from_stage(&commit_id, g_repo, "Message goes here.", &opts));
cl_git_pass(git_repository_head_tree(&tree, g_repo));
cl_assert_equal_oidstr("f776dc4c7fd8164b7127dc8e4f9b44421cb01b56", &commit_id);
cl_assert_equal_oidstr("c4dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b", git_tree_id(tree));
git_tree_free(tree);
}
void test_commit_create__from_stage_newrepo(void)
{
git_commit_create_options opts = GIT_COMMIT_CREATE_OPTIONS_INIT;
git_repository *newrepo;
git_index *index;
git_commit *commit;
git_tree *tree;
git_oid commit_id;
opts.author = g_author;
opts.committer = g_committer;
git_repository_init(&newrepo, "newrepo", false);
cl_git_pass(git_repository_index(&index, newrepo));
cl_git_rewritefile("newrepo/hello.txt", "hello, world.\n");
cl_git_rewritefile("newrepo/hi.txt", "hi there.\n");
cl_git_rewritefile("newrepo/foo.txt", "bar.\n");
cl_git_pass(git_index_add_bypath(index, "hello.txt"));
cl_git_pass(git_index_add_bypath(index, "foo.txt"));
cl_git_pass(git_index_write(index));
cl_git_pass(git_commit_create_from_stage(&commit_id, newrepo, "Initial commit.", &opts));
cl_git_pass(git_repository_head_commit(&commit, newrepo));
cl_git_pass(git_repository_head_tree(&tree, newrepo));
cl_assert_equal_oid(&commit_id, git_commit_id(commit));
cl_assert_equal_oidstr("b2fa96a4f191c76eb172437281c66aa29609dcaa", git_commit_tree_id(commit));
git_tree_free(tree);
git_commit_free(commit);
git_index_free(index);
git_repository_free(newrepo);
cl_fixture_cleanup("newrepo");
}

View File

@@ -9,7 +9,7 @@ void test_commit_parent__initialize(void)
cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
git_oid_fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
git_oid__fromstr(&oid, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644", GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, _repo, &oid));
}

View File

@@ -56,7 +56,8 @@ void test_commit_parse__header(void)
const char *line = testcase->line;
const char *line_end = line + strlen(line);
cl_git_pass(git_oid__parse(&oid, &line, line_end, testcase->header));
cl_git_pass(git_object__parse_oid_header(&oid,
&line, line_end, testcase->header, GIT_OID_SHA1));
cl_assert(line == line_end);
}
@@ -65,7 +66,8 @@ void test_commit_parse__header(void)
const char *line = testcase->line;
const char *line_end = line + strlen(line);
cl_git_fail(git_oid__parse(&oid, &line, line_end, testcase->header));
cl_git_fail(git_object__parse_oid_header(&oid,
&line, line_end, testcase->header, GIT_OID_SHA1));
}
}
@@ -285,7 +287,7 @@ static int parse_commit(git_commit **out, const char *buffer)
fake_odb_object.buffer = (char *)buffer;
fake_odb_object.cached.size = strlen(fake_odb_object.buffer);
error = git_commit__parse(commit, &fake_odb_object);
error = git_commit__parse(commit, &fake_odb_object, GIT_OID_SHA1);
*out = commit;
return error;
@@ -341,7 +343,7 @@ void test_commit_parse__details0(void) {
unsigned int parents, p;
git_commit *parent = NULL, *old_parent = NULL;
git_oid_fromstr(&id, commit_ids[i]);
git_oid__fromstr(&id, commit_ids[i], GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&commit, g_repo, &id));
@@ -445,15 +447,15 @@ cpxtDQQMGYFpXK/71stq\n\
cl_git_pass(git_commit_header_field(&buf, commit, "tree"));
cl_assert_equal_s("6b79e22d69bf46e289df0345a14ca059dfc9bdf6", buf.ptr);
git_buf_clear(&buf);
git_buf_dispose(&buf);
cl_git_pass(git_commit_header_field(&buf, commit, "parent"));
cl_assert_equal_s("34734e478d6cf50c27c9d69026d93974d052c454", buf.ptr);
git_buf_clear(&buf);
git_buf_dispose(&buf);
cl_git_pass(git_commit_header_field(&buf, commit, "gpgsig"));
cl_assert_equal_s(gpgsig, buf.ptr);
git_buf_clear(&buf);
git_buf_dispose(&buf);
cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "awesomeness"));
cl_git_fail_with(GIT_ENOTFOUND, git_commit_header_field(&buf, commit, "par"));
@@ -513,7 +515,6 @@ committer Some User <someuser@gmail.com> 1454537944 -0700\n\
\n\
corrupt signature\n";
cl_git_pass(git_repository_odb__weakptr(&odb, g_repo));
cl_git_pass(git_odb_write(&commit_id, odb, passing_commit_cases[4], strlen(passing_commit_cases[4]), GIT_OBJECT_COMMIT));
@@ -521,15 +522,18 @@ corrupt signature\n";
cl_assert_equal_s(gpgsig, signature.ptr);
cl_assert_equal_s(data, signed_data.ptr);
git_buf_clear(&signature);
git_buf_clear(&signed_data);
git_buf_dispose(&signature);
git_buf_dispose(&signed_data);
cl_git_pass(git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, "gpgsig"));
cl_assert_equal_s(gpgsig, signature.ptr);
cl_assert_equal_s(data, signed_data.ptr);
git_buf_dispose(&signature);
git_buf_dispose(&signed_data);
/* Try to parse a tree */
cl_git_pass(git_oid_fromstr(&commit_id, "45dd856fdd4d89b884c340ba0e047752d9b085d6"));
cl_git_pass(git_oid__fromstr(&commit_id, "45dd856fdd4d89b884c340ba0e047752d9b085d6", GIT_OID_SHA1));
cl_git_fail_with(GIT_ENOTFOUND, git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, NULL));
cl_assert_equal_i(GIT_ERROR_INVALID, git_error_last()->klass);
@@ -539,15 +543,11 @@ corrupt signature\n";
cl_assert_equal_i(GIT_ERROR_OBJECT, git_error_last()->klass);
/* Parse the commit with a single-line signature */
git_buf_clear(&signature);
git_buf_clear(&signed_data);
cl_git_pass(git_odb_write(&commit_id, odb, oneline_signature, strlen(oneline_signature), GIT_OBJECT_COMMIT));
cl_git_pass(git_commit_extract_signature(&signature, &signed_data, g_repo, &commit_id, NULL));
cl_assert_equal_s("bad", signature.ptr);
cl_assert_equal_s(oneline_data, signed_data.ptr);
git_buf_dispose(&signature);
git_buf_dispose(&signed_data);
}

View File

@@ -36,10 +36,17 @@ void test_commit_signature__leading_and_trailing_spaces_are_trimmed(void)
assert_name_and_email("nulltoken", "emeric.fermas@gmail.com", " \t nulltoken \n", " \n emeric.fermas@gmail.com \n");
}
void test_commit_signature__leading_and_trailing_dots_are_supported(void)
{
assert_name_and_email(".nulltoken", ".emeric.fermas@gmail.com", ".nulltoken", ".emeric.fermas@gmail.com");
assert_name_and_email("nulltoken.", "emeric.fermas@gmail.com.", "nulltoken.", "emeric.fermas@gmail.com.");
assert_name_and_email(".nulltoken.", ".emeric.fermas@gmail.com.", ".nulltoken.", ".emeric.fermas@gmail.com.");
}
void test_commit_signature__leading_and_trailing_crud_is_trimmed(void)
{
assert_name_and_email("nulltoken", "emeric.fermas@gmail.com", "\"nulltoken\"", "\"emeric.fermas@gmail.com\"");
assert_name_and_email("nulltoken w", "emeric.fermas@gmail.com", "nulltoken w.", "emeric.fermas@gmail.com");
assert_name_and_email("nulltoken w", "emeric.fermas@gmail.com", "nulltoken w;", "emeric.fermas@gmail.com");
assert_name_and_email("nulltoken \xe2\x98\xba", "emeric.fermas@gmail.com", "nulltoken \xe2\x98\xba", "emeric.fermas@gmail.com");
}

View File

@@ -51,10 +51,10 @@ void test_commit_write__from_memory(void)
git_commit *parent;
git_tree *tree;
git_oid_fromstr(&tree_id, tree_id_str);
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
git_oid_fromstr(&parent_id, parent_id_str);
git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id));
/* create signatures */
@@ -107,18 +107,18 @@ void test_commit_write__into_buf(void)
git_oid parent_id;
git_buf commit = GIT_BUF_INIT;
git_oid_fromstr(&tree_id, tree_id_str);
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
/* create signatures */
cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
git_oid_fromstr(&parent_id, parent_id_str);
git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1);
cl_git_pass(git_commit_lookup(&parent, g_repo, &parent_id));
cl_git_pass(git_commit_create_buffer(&commit, g_repo, author, committer,
NULL, root_commit_message, tree, 1, (const git_commit **) &parent));
NULL, root_commit_message, tree, 1, &parent));
cl_assert_equal_s(commit.ptr,
"tree 1810dff58d8a660512d4832e740f692884338ccd\n\
@@ -148,14 +148,14 @@ void test_commit_write__root(void)
git_reflog *log;
const git_reflog_entry *entry;
git_oid_fromstr(&tree_id, tree_id_str);
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
/* create signatures */
cl_git_pass(git_signature_new(&committer, committer_name, committer_email, 123456789, 60));
cl_git_pass(git_signature_new(&author, committer_name, committer_email, 987654321, 90));
/* First we need to update HEAD so it points to our non-existant branch */
/* First we need to update HEAD so it points to our non-existent branch */
cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
cl_assert(git_reference_type(head) == GIT_REFERENCE_SYMBOLIC);
head_old = git__strdup(git_reference_symbolic_target(head));
@@ -242,34 +242,34 @@ void test_commit_write__can_write_invalid_objects(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 0));
/* this is a valid tree and parent */
git_oid_fromstr(&tree_id, tree_id_str);
git_oid_fromstr(&parent_id, parent_id_str);
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1);
git_oid_fromstr(&expected_id, "c8571bbec3a72c4bcad31648902e5a453f1adece");
git_oid__fromstr(&expected_id, "c8571bbec3a72c4bcad31648902e5a453f1adece", GIT_OID_SHA1);
cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
cl_assert_equal_oid(&expected_id, &commit_id);
/* this is a wholly invented tree id */
git_oid_fromstr(&tree_id, "1234567890123456789012345678901234567890");
git_oid_fromstr(&parent_id, parent_id_str);
git_oid__fromstr(&tree_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1);
git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1);
git_oid_fromstr(&expected_id, "996008340b8e68d69bf3c28d7c57fb7ec3c8e202");
git_oid__fromstr(&expected_id, "996008340b8e68d69bf3c28d7c57fb7ec3c8e202", GIT_OID_SHA1);
cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
cl_assert_equal_oid(&expected_id, &commit_id);
/* this is a wholly invented parent id */
git_oid_fromstr(&tree_id, tree_id_str);
git_oid_fromstr(&parent_id, "1234567890123456789012345678901234567890");
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
git_oid__fromstr(&parent_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1);
git_oid_fromstr(&expected_id, "d78f660cab89d9791ca6714b57978bf2a7e709fd");
git_oid__fromstr(&expected_id, "d78f660cab89d9791ca6714b57978bf2a7e709fd", GIT_OID_SHA1);
cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
cl_assert_equal_oid(&expected_id, &commit_id);
/* these are legitimate objects, but of the wrong type */
git_oid_fromstr(&tree_id, parent_id_str);
git_oid_fromstr(&parent_id, tree_id_str);
git_oid__fromstr(&tree_id, parent_id_str, GIT_OID_SHA1);
git_oid__fromstr(&parent_id, tree_id_str, GIT_OID_SHA1);
git_oid_fromstr(&expected_id, "5d80c07414e3f18792949699dfcacadf7748f361");
git_oid__fromstr(&expected_id, "5d80c07414e3f18792949699dfcacadf7748f361", GIT_OID_SHA1);
cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
cl_assert_equal_oid(&expected_id, &commit_id);
}
@@ -279,23 +279,23 @@ void test_commit_write__can_validate_objects(void)
git_oid tree_id, parent_id, commit_id;
/* this is a valid tree and parent */
git_oid_fromstr(&tree_id, tree_id_str);
git_oid_fromstr(&parent_id, parent_id_str);
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1);
cl_git_pass(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
/* this is a wholly invented tree id */
git_oid_fromstr(&tree_id, "1234567890123456789012345678901234567890");
git_oid_fromstr(&parent_id, parent_id_str);
git_oid__fromstr(&tree_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1);
git_oid__fromstr(&parent_id, parent_id_str, GIT_OID_SHA1);
cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
/* this is a wholly invented parent id */
git_oid_fromstr(&tree_id, tree_id_str);
git_oid_fromstr(&parent_id, "1234567890123456789012345678901234567890");
git_oid__fromstr(&tree_id, tree_id_str, GIT_OID_SHA1);
git_oid__fromstr(&parent_id, "1234567890123456789012345678901234567890", GIT_OID_SHA1);
cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
/* these are legitimate objects, but of the wrong type */
git_oid_fromstr(&tree_id, parent_id_str);
git_oid_fromstr(&parent_id, tree_id_str);
git_oid__fromstr(&tree_id, parent_id_str, GIT_OID_SHA1);
git_oid__fromstr(&parent_id, tree_id_str, GIT_OID_SHA1);
cl_git_fail(create_commit_from_ids(&commit_id, &tree_id, &parent_id));
}

View File

@@ -1,5 +1,4 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "futils.h"
#include "repository.h"
@@ -23,43 +22,46 @@ void test_config_conditionals__cleanup(void)
static void assert_condition_includes(const char *keyword, const char *path, bool expected)
{
git_buf buf = GIT_BUF_INIT;
git_buf value = GIT_BUF_INIT;
git_str buf = GIT_STR_INIT;
git_config *cfg;
cl_git_pass(git_buf_printf(&buf, "[includeIf \"%s:%s\"]\n", keyword, path));
cl_git_pass(git_buf_puts(&buf, "path = other\n"));
cl_git_pass(git_str_printf(&buf, "[includeIf \"%s:%s\"]\n", keyword, path));
cl_git_pass(git_str_puts(&buf, "path = other\n"));
cl_git_mkfile("empty_standard_repo/.git/config", buf.ptr);
cl_git_mkfile("empty_standard_repo/.git/other", "[foo]\nbar=baz\n");
_repo = cl_git_sandbox_reopen();
git_str_dispose(&buf);
cl_git_pass(git_repository_config(&cfg, _repo));
if (expected) {
git_buf_clear(&buf);
cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar"));
cl_assert_equal_s("baz", git_buf_cstr(&buf));
cl_git_pass(git_config_get_string_buf(&value, cfg, "foo.bar"));
cl_assert_equal_s("baz", value.ptr);
} else {
cl_git_fail_with(GIT_ENOTFOUND,
git_config_get_string_buf(&buf, cfg, "foo.bar"));
git_config_get_string_buf(&value, cfg, "foo.bar"));
}
git_buf_dispose(&buf);
git_str_dispose(&buf);
git_buf_dispose(&value);
git_config_free(cfg);
}
static char *sandbox_path(git_buf *buf, const char *suffix)
static char *sandbox_path(git_str *buf, const char *suffix)
{
char *path = p_realpath(clar_sandbox_path(), NULL);
cl_assert(path);
cl_git_pass(git_buf_attach(buf, path, 0));
cl_git_pass(git_buf_joinpath(buf, buf->ptr, suffix));
cl_git_pass(git_str_attach(buf, path, 0));
cl_git_pass(git_str_joinpath(buf, buf->ptr, suffix));
return buf->ptr;
}
void test_config_conditionals__gitdir(void)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
assert_condition_includes("gitdir", ROOT_PREFIX "/", true);
assert_condition_includes("gitdir", "empty_stand", false);
@@ -90,17 +92,17 @@ void test_config_conditionals__gitdir(void)
assert_condition_includes("gitdir", sandbox_path(&path, "Empty_Standard_Repo"), false);
assert_condition_includes("gitdir", sandbox_path(&path, "Empty_Standard_Repo/"), false);
git_buf_dispose(&path);
git_str_dispose(&path);
}
void test_config_conditionals__gitdir_i(void)
{
git_buf path = GIT_BUF_INIT;
git_str path = GIT_STR_INIT;
assert_condition_includes("gitdir/i", sandbox_path(&path, "empty_standard_repo/"), true);
assert_condition_includes("gitdir/i", sandbox_path(&path, "EMPTY_STANDARD_REPO/"), true);
git_buf_dispose(&path);
git_str_dispose(&path);
}
void test_config_conditionals__invalid_conditional_fails(void)
@@ -146,3 +148,28 @@ void test_config_conditionals__onbranch(void)
assert_condition_includes("onbranch", "dir*", false);
assert_condition_includes("onbranch", "dir/*", false);
}
void test_config_conditionals__empty(void)
{
git_buf value = GIT_BUF_INIT;
git_str buf = GIT_STR_INIT;
git_config *cfg;
cl_git_pass(git_str_puts(&buf, "[includeIf]\n"));
cl_git_pass(git_str_puts(&buf, "path = other\n"));
cl_git_mkfile("empty_standard_repo/.git/config", buf.ptr);
cl_git_mkfile("empty_standard_repo/.git/other", "[foo]\nbar=baz\n");
_repo = cl_git_sandbox_reopen();
git_str_dispose(&buf);
cl_git_pass(git_repository_config(&cfg, _repo));
cl_git_fail_with(GIT_ENOTFOUND,
git_config_get_string_buf(&value, cfg, "foo.bar"));
git_str_dispose(&buf);
git_buf_dispose(&value);
git_config_free(cfg);
}

Some files were not shown because too many files have changed in this diff Show More