Content-Length: 11283 | pFad | http://github.com/cp-algorithms/cp-algorithms/pull/1464.diff
thub.com diff --git a/test/.gitignore b/test/.gitignore index d4c66e876..edddd2e40 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1 +1,2 @@ -/*.h +include/snippets/ +build/ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..fe94c63e3 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.30 FATAL_ERROR) + +project(cp-algorithms LANGUAGES CXX) + +# generating snippets +set(SNIPPETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/snippets) +find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter) +execute_process( + COMMAND + ${Python3_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/extract_snippets.py" + --src-dir=${CMAKE_CURRENT_SOURCE_DIR}/../src + --target-dir=${SNIPPETS_DIR} + --remove-prev-target-dir + COMMAND_ERROR_IS_FATAL ANY +) + +# loading googletest +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.17.0 +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +include(GoogleTest) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +file(GLOB_RECURSE SNIPPETS_SOURCES CONFIGURE_DEPENDS ${SNIPPETS_DIR}/*.h) +file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS src/test_*.cpp) + +add_executable(main ${TEST_SOURCES} ${SNIPPETS_SOURCES}) +target_link_libraries(main PRIVATE GTest::gtest_main GTest::gtest GTest::gmock) +target_include_directories(main PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) + +enable_testing() +gtest_discover_tests(main) diff --git a/test/extract_snippets.py b/test/extract_snippets.py deleted file mode 100755 index 69e796678..000000000 --- a/test/extract_snippets.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python3 -import re -import os - -def write_snippet(name, lines): - file_name = '{}.h'.format(name) - with open(file_name, 'w') as f: - for line in lines: - f.write(line) - -def extract_tests(filepath): - filepath_short = os.path.basename(filepath) - article_name = filepath_short.split('.')[0] - - snippet_start = re.compile(r"^```\{.cpp\s+file=(\S+)\}$") - snippet_end = re.compile(r"^```$") - - with open(filepath) as f: - in_snippet = False; - for line in f: - m_start = snippet_start.match(line) - m_end = snippet_end.match(line) - - if in_snippet and m_end: - in_snippet = False - write_snippet(snippet_name, lines) - - if in_snippet: - lines.append(line) - elif m_start: - snippet_name = m_start.group(1) - lines = [] - in_snippet = True - - -if __name__ == '__main__': - for subdir, dirs, files in os.walk('../src/'): - for filename in files: - if filename.endswith(".md"): - extract_tests(os.path.join(subdir, filename)) diff --git a/test/scripts/extract_snippets.py b/test/scripts/extract_snippets.py new file mode 100644 index 000000000..5a701ea65 --- /dev/null +++ b/test/scripts/extract_snippets.py @@ -0,0 +1,128 @@ +import argparse +import re +import os +import sys +import shutil +import logging +from typing import List, Optional +from dataclasses import dataclass + + +@dataclass +class Snippet: + name: str + lines: List[str] + + +def write_snippet(target_dir: os.PathLike, snippet: Snippet): + assert os.path.exists(target_dir) and os.path.isdir(target_dir) + + file_name = f'{snippet.name}.h' + with open(os.path.join(target_dir, file_name), 'w', encoding='utf-8') as f: + f.writelines(snippet.lines) + + +def extract_snippets(filepath: os.PathLike) -> List[Snippet]: + with open(filepath, 'r', encoding='utf-8') as f: + lines = f.readlines() + + snippets = [] + + snippet_start = re.compile(r"^```\{.cpp\s+file=(\S+)\}$") + snippet_end = re.compile(r"^```$") + + snippet_start_line: Optional[int] = None + snippet_name: Optional[str] = None + + for line_idx, line in enumerate(lines): + match_snippet_start = snippet_start.match(line) + match_snippet_end = snippet_end.match(line) + assert not (match_snippet_start and match_snippet_end) + + if match_snippet_start: + assert snippet_start_line is None + assert snippet_name is None + + snippet_start_line = line_idx + snippet_name = match_snippet_start.group(1) + elif match_snippet_end: + if snippet_start_line is not None: + assert snippet_start_line is not None + assert snippet_name is not None + + snippet = lines[snippet_start_line + 1: line_idx] + + snippets.append(Snippet(name=snippet_name, lines=snippet)) + + snippet_start_line = None + snippet_name = None + + return snippets + + +def main(args: argparse.Namespace) -> None: + src_dir = args.src_dir + target_dir = args.target_dir + + logging.info(f'--src-dir="{src_dir}"') + logging.info(f'--target-dir="{target_dir}"') + + assert os.path.isdir(src_dir) + + if args.remove_prev_target_dir and os.path.exists(target_dir): + logging.info(f'Script launched with --remove-prev-target-dir flag') + logging.info(f'Removing --target-dir="{target_dir}"') + shutil.rmtree(target_dir) + + if not os.path.exists(target_dir): + logging.info( + f'--target-dir="{target_dir}" does not exist, creating') + os.makedirs(target_dir, exist_ok=False) + assert os.path.isdir( + target_dir), f'Failed to create --target-dir: "{target_dir}"' + + snippets = [] + + for subdir, _, files in os.walk(src_dir): + for filename in files: + if filename.lower().endswith('.md'): + filepath = os.path.join(subdir, filename) + logging.debug(f'Extracting snippets from {filename}') + snippets.extend(extract_snippets(filepath)) + + n_snippets = len(snippets) + for snippet_idx, snippet in enumerate(snippets, start=1): + logging.debug( + f'({snippet_idx}/{n_snippets}) writing snippet {snippet.name} to "{target_dir}"') + write_snippet(target_dir, snippet) + + logging.info( + f'All done, {n_snippets} snippets have been written to "{target_dir}"') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Recursively extracts specially annotation cpp code snippets from src dir with .md files') + + parser.add_argument('--src-dir', type=str, required=True, + help='path to the directory with .md source to recursively look for cpp snippets with {.cpp file=...} annotation') + parser.add_argument('--target-dir', type=str, required=True, + help='path to the resulting directory with .h snippets extracted from src-dir') + parser.add_argument('--remove-prev-target-dir', action='store_true', + help='remove --target-dir prior to generating snippets') + + logging_level_names = list(logging.getLevelNamesMapping().keys()) + assert 'INFO' in logging_level_names + parser.add_argument('--logging-level', type=str, choices=logging_level_names, + default='INFO', help='script logging level') + + args = parser.parse_args() + + logging.basicConfig( + stream=sys.stdout, + format='%(asctime)s %(module)-15s - [%(levelname)-6s] - %(message)s', + datefmt='%H:%M:%S', + level=args.logging_level + ) + + main(args) diff --git a/test/src/test_2sat_new.cpp b/test/src/test_2sat_new.cpp new file mode 100644 index 000000000..bcf6af421 --- /dev/null +++ b/test/src/test_2sat_new.cpp @@ -0,0 +1,53 @@ +#includeFetched URL: http://github.com/cp-algorithms/cp-algorithms/pull/1464.diff
Alternative Proxies: