Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .cmake-format.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
format:
line_width: 100
tab_size: 4
use_tabchars: false
max_subgroups_hwrap: 3
max_pargs_hwrap: 3
dangle_parens: true
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @Coding-Cuddles/kata-maintainers
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
30 changes: 9 additions & 21 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,22 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/checkout@v7

- name: Check formatting
run: make format-check

test:
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}

env:
GTEST_COLOR: "1"

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install Ninja, GTest, and GMock
run: |
sudo apt-get update
sudo apt-get install \
google-mock \
googletest \
libgmock-dev \
libgtest-dev \
ninja-build

- name: Build
run: make build

- name: Run main
run: make run
- uses: actions/checkout@v7

- name: Test
run: make test
41 changes: 31 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
cmake_minimum_required(VERSION 3.19)
cmake_minimum_required(VERSION 3.24)
project(hyper-optimized-telemetry-cpp-kata CXX)
enable_testing()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_COLOR_DIAGNOSTICS ON)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

include(FetchGTest)
fetch_gtest()

find_package(GTest REQUIRED)
include(GoogleTest)

enable_testing()

add_executable(main main.cpp)
add_custom_target(
run
COMMAND $<TARGET_FILE:main>
DEPENDS main
COMMENT "Running the example executable"
)

file(GLOB tests test_*.cpp)
foreach(test ${tests})
get_filename_component(name ${test} NAME_WE)
add_executable(${name} ${test})
add_test(${name} ${name})
target_link_libraries(${name} PRIVATE GTest::gmock_main)

gtest_discover_tests(${name})
endforeach()

add_custom_target(
copy-compile-commands ALL
${CMAKE_COMMAND} -E copy_if_different
${CMAKE_BINARY_DIR}/compile_commands.json
${CMAKE_CURRENT_LIST_DIR}
)
if(UNIX)
add_custom_target(
copy-compile-commands ALL
${CMAKE_COMMAND}
-E
copy_if_different
${CMAKE_BINARY_DIR}/compile_commands.json
${CMAKE_CURRENT_LIST_DIR}
COMMENT "Copying compile commands to the source directory"
)
endif()
46 changes: 30 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
all: build test
COLOR_CYAN := \033[36m
COLOR_RESET := \033[0m

export CXX := clang++
export GTEST_COLOR := 1
CLICOLOR ?= 1
GTEST_COLOR ?= 1
export CLICOLOR GTEST_COLOR

BUILDDIR ?= build
SRCS := $(shell git ls-files *.cpp *.h)
BUILDCONFIG ?= Debug
SRCS := $(shell git ls-files '*.cpp' '*.h' '*.hpp')

.DEFAULT_GOAL := help

.PHONY: all
all: test ## Build and run tests

.PHONY: help
help: ## Show this help message
@awk 'BEGIN {FS = ":.*##"; printf "Usage: make [options] $(COLOR_CYAN)[target] ...$(COLOR_RESET)\n\n"} \
/^[a-zA-Z_-]+:.*##/ {printf " $(COLOR_CYAN)%-20s$(COLOR_RESET) %s\n", $$1, $$2}' \
$(MAKEFILE_LIST)

.PHONY: build
build:
cmake -B ${BUILDDIR} -G Ninja .
cmake --build ${BUILDDIR}
build: ## Configure and build
cmake -S . -B ${BUILDDIR} -DCMAKE_BUILD_TYPE=${BUILDCONFIG}
cmake --build ${BUILDDIR} --config ${BUILDCONFIG}

.PHONY: run
run:
cd ${BUILDDIR} && ./main
run: build ## Build and run the example executable
cmake --build ${BUILDDIR} --config ${BUILDCONFIG} --target run

.PHONY: test
test:
ctest --output-on-failure --test-dir ${BUILDDIR}
test: build ## Build and run tests
ctest --test-dir ${BUILDDIR} --build-config ${BUILDCONFIG} --output-on-failure

.PHONY: format
format:
format: ## Format C++ sources in place
clang-format -i -style=file $(SRCS)

.PHONY: format-check
format-check:
format-check: ## Fail if C++ sources require formatting
clang-format -style=file --dry-run -Werror $(SRCS) \
|| (echo "Some files require formatting. Run 'make format' to fix." && exit 1)

.PHONY: clean
clean:
rm -rf ${BUILDDIR}
clean: ## Remove generated build artifacts
rm -rf ${BUILDDIR} compile_commands.json

ifndef VERBOSE
ifneq ($(VERBOSE),1)
.SILENT:
endif
110 changes: 98 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Hyper-optimized telemetry kata in C++

[![CI](https://github.com/Coding-Cuddles/hyper-optimized-telemetry-cpp-kata/actions/workflows/main.yml/badge.svg)](https://github.com/Coding-Cuddles/hyper-optimized-telemetry-cpp-kata/actions/workflows/main.yml)
[![C++17](https://img.shields.io/badge/C%2B%2B-17-blue.svg)](https://en.cppreference.com/w/cpp/17)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Replit](https://img.shields.io/badge/Try%20with%20Replit-black?logo=replit)](https://replit.com/new/github/Coding-Cuddles/hyper-optimized-telemetry-cpp-kata)

## Overview
Expand Down Expand Up @@ -98,35 +100,119 @@ type as allocated by the system:
| `unsigned int` | 32 bit | 0 | +4'294'967'295 |
| `unsigned long` | 64 bit | 0 | +18'446'744'073'709'551'615 |

## Usage
This is a C++17 kata using GoogleTest. Setup is complete when CTest reports
`100% tests passed`.

You can import this project into [Replit](https://replit.com), and it will
handle all dependencies automatically.
## Prerequisites

### Prerequisites
Required:

* [CMake 3.19+](https://cmake.org)
* [Ninja](https://ninja-build.org)
* [GTest](https://github.com/google/googletest)
- [Git](https://git-scm.com/downloads)
- A compiler with C++17 support. Choose one:
- [GCC](https://gcc.gnu.org/) 10+ on Linux
- [LLVM Clang](https://llvm.org/) 14+ on Linux
- [Apple Clang](https://developer.apple.com/xcode/) 17+ on macOS
- [MSVC](https://visualstudio.microsoft.com/) 2022 on Windows
- [CMake 3.24 or later](https://cmake.org)

### Build
Optional:

- [GNU Make](https://www.gnu.org/software/make/), for shorter commands. Every
required task also has direct CMake and CTest commands. Make may be
unavailable on Windows.

You do not need to install GoogleTest separately. CMake finds an installed
copy or downloads the pinned release when needed.

## Set up the kata

The tracked Replit configuration and badge are retained. The local setup below
is the validated development path.

1. Clone the repository:

```console
git clone https://github.com/Coding-Cuddles/hyper-optimized-telemetry-cpp-kata.git
```

2. Enter the repository directory:

```console
cd hyper-optimized-telemetry-cpp-kata
```

3. Build and run the tests. Use Make when it is installed:

```console
make test
```

Otherwise, use CMake and CTest directly:

```console
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --config Debug
ctest --test-dir build --build-config Debug --output-on-failure
```

The first run may download and build GoogleTest. CTest should report
`100% tests passed`. If a command reports a missing compiler or CMake, install
that prerequisite and run the setup commands again. Setup is complete when
CTest reports `100% tests passed`.

## Work on the kata

Work through the two exercises in order. Add one test at a time, then implement
enough code to make the test pass. Keep the protocol, constraints, and expected
results above as the target behavior.

After each change, use Make when it is installed:

```console
make test
```

Otherwise, use CMake and CTest directly:

```console
make build
cmake --build build --config Debug
ctest --test-dir build --build-config Debug --output-on-failure
```

### Run main
Continue when CTest reports `100% tests passed`.

## Run the example

Use Make when it is installed:

```console
make run
```

### Run tests
Otherwise, use the CMake run target:

```console
make test
cmake --build build --config Debug --target run
```

The executable prints `Hello World!`.

## Make command reference

Make is optional. Run `make` or `make help` to list these commands in the
terminal.

| Command | Result |
| ------------------- | ----------------------------------------- |
| `make all` | Build and run the test suite |
| `make help` | List public Make targets |
| `make build` | Configure and build without running tests |
| `make run` | Build and run the example executable |
| `make test` | Build and run the test suite |
| `make format` | Format tracked C++ and header files |
| `make format-check` | Check formatting without changing files |
| `make clean` | Remove generated build artifacts |

## Credits and references

* <https://exercism.org/tracks/csharp/exercises/hyper-optimized-telemetry>
31 changes: 31 additions & 0 deletions cmake/FetchGTest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
include(FetchContent)

# Find an installed GoogleTest package or fetch and verify the pinned release
function(fetch_gtest)
string(
CONCAT
gtest_url
"https://github.com/google/googletest/releases/download/"
"v1.17.0/googletest-1.17.0.tar.gz"
)
set(
gtest_sha256
65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c
)

FetchContent_Declare(
googletest
URL ${gtest_url}
URL_HASH SHA256=${gtest_sha256}
DOWNLOAD_EXTRACT_TIMESTAMP
FALSE
FIND_PACKAGE_ARGS
NAMES
GTest
)

# Prevent overriding parent project's compiler/linker settings on Windows
# cmake-lint: disable=C0103
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
endfunction()
2 changes: 1 addition & 1 deletion test_bit_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ INSTANTIATE_TEST_SUITE_P(
Int32ToBytesTestParam{-1048576, {0x00, 0x00, 0xF0, 0xFF}},
Int32ToBytesTestParam{1000000000, {0x00, 0xCA, 0x9A, 0x3B}},
Int32ToBytesTestParam{-1000000000, {0x00, 0x36, 0x65, 0xC4}},
Int32ToBytesTestParam{-2147483648, {0x00, 0x00, 0x00, 0x80}},
Int32ToBytesTestParam{INT32_MIN, {0x00, 0x00, 0x00, 0x80}},
Int32ToBytesTestParam{2147483647, {0xFF, 0xFF, 0xFF, 0x7F}}
)
);
Expand Down