Notice: file_put_contents(): Write of 5134 bytes failed with errno=28 No space left on device in /var/www/group-telegram/post.php on line 50

Warning: file_put_contents(): Only 12288 of 17422 bytes written, possibly out of free disk space in /var/www/group-telegram/post.php on line 50
C++95 | Telegram Webview: cxx95/106 -
Telegram Group & Telegram Channel
#compiler

Простые тесты для C++ кода на Python 🍄🍄🍄🍄🍄

Часто хочется покрыть тестами код на C++ в проекте - не логику, которую описывает код, а сам исходный код. Сейчас для этого есть приличное количество чекеров в clang-tidy. Можно написать свой чекер, который все равно будут ревьюить много месяцев и КПД всего этого занятия близок к нулю. Для специфических проверок надо что-то колхозить самому.

Примерных проверок может быть много:
1️⃣ Запрет на использование typeid(x).name(), потому что он дает mangled имя, с советом использовать костыль, который отдаст demangled имя.
2️⃣ Запрет на использование старого API в новом коде во время масштабного рефакторинга.
3️⃣ Проверка, что в начале каждого файла находится копипаста лицензии проекта.

Можно придумать проверку на примере лямбд 😊 Пусть у нас есть такой код:
    int counter = 15;
const auto addEvent = [&counter](int number) {
if (counter > 0) {
// do something...
--counter;
}
};
// ... call the lambda
addEvent(1337);
В этом примере лямбда использует внешнюю переменную, которая влияет на логику.
Если переменная используется только внутри лямбды, то ее можно вкостылить прямо в capture list. Тогда вместо двух верхних строк примера будет такая строка, дающая аналогичный результат:
    auto addEvent = [counter = 15](int number) mutable {
Такой же подход работает для переменных любых типов. Если интересно, что происходит внутри лямбд, то можно почитать целую книгу про них.

Попробуем сделать тест на такие кейсы 😁 Если мы для этого используем библиотеки clang, то логика такая:
1️⃣ Получаем AST (Abstract Syntax Tree) из исходного кода.
2️⃣ Лямбды в AST это вершины LambdaExpr.
3️⃣ "Объявление переменной" в AST это вершина VarDecl.
4️⃣ "Использование переменной" (в каком-то месте) это вершина DeclRefExpr.
5️⃣ Если все "использования переменной" находятся внутри какого-то одного и того же LambdaExpr, а "объявление переменной" находится вне этого LambdaExpr, то тест должен упасть, потому что данную переменную можно всунуть в capture list лямбды.
6️⃣ Делаем рекурсивный обход AST с корня и держанием указателя на "текущую лямбду", и делаем проверку на пункт 5.

Этот тест можно сделать на 👩‍💻 C++: вкостылить новый чекер в локальной сборке clang-tidy или просто сделать программу на libclang. Но можно сделать то же самое на 👩‍💻 Python и кода будет меньше в несколько раз, и это делается быстрее - менее муторно. Python хорошо подходит для быстрого написания разных тестов.

Поддерживается libclang в Python, и после просмотра примеров можно поставить его себе:
    pip install pytest
pip install clang
pip install libclang
и сделать такой простой тест, где реализуется описанная проверка для лямбд. Можно в директории рядом сохранить тестовый файл source.cpp и проверить, что тест падает:
    python3 -m pytest test.py

Вывод:
E           Failed: These variables can be declared in lambda capture: 
E "counter" (at source.cpp:3:44), to lambda at source.cpp:4:88

libclang на Python выглядит нормально, но неприятно то, что для понятия "нода AST" не к месту придумали новый термин "курсор".
Также не хватает некоторых очевидных фичей, например получения родительской ноды: в курсорах есть пара ссылок на другие курсоры (типа родительские, двух видов), но они работают неправильно.

Кроме тестов можно писать другие тулзы, например "кодогенераторы" - которые сгенерируют какой-нибудь исходник на основе существующего кода. Про кодогенераторы можно почитать лонгрид.

Еще можно делать "исправляторы" исходников - которые берут AST, что-то туда дописывают и сохраняют в другой файл, а компилятор имеет дело с уже поправленным AST (то есть с этим другим файлом).
Please open Telegram to view this post
VIEW IN TELEGRAM



group-telegram.com/cxx95/106
Create:
Last Update:

#compiler

Простые тесты для C++ кода на Python 🍄🍄🍄🍄🍄

Часто хочется покрыть тестами код на C++ в проекте - не логику, которую описывает код, а сам исходный код. Сейчас для этого есть приличное количество чекеров в clang-tidy. Можно написать свой чекер, который все равно будут ревьюить много месяцев и КПД всего этого занятия близок к нулю. Для специфических проверок надо что-то колхозить самому.

Примерных проверок может быть много:
1️⃣ Запрет на использование typeid(x).name(), потому что он дает mangled имя, с советом использовать костыль, который отдаст demangled имя.
2️⃣ Запрет на использование старого API в новом коде во время масштабного рефакторинга.
3️⃣ Проверка, что в начале каждого файла находится копипаста лицензии проекта.

Можно придумать проверку на примере лямбд 😊 Пусть у нас есть такой код:

    int counter = 15;
const auto addEvent = [&counter](int number) {
if (counter > 0) {
// do something...
--counter;
}
};
// ... call the lambda
addEvent(1337);
В этом примере лямбда использует внешнюю переменную, которая влияет на логику.
Если переменная используется только внутри лямбды, то ее можно вкостылить прямо в capture list. Тогда вместо двух верхних строк примера будет такая строка, дающая аналогичный результат:
    auto addEvent = [counter = 15](int number) mutable {
Такой же подход работает для переменных любых типов. Если интересно, что происходит внутри лямбд, то можно почитать целую книгу про них.

Попробуем сделать тест на такие кейсы 😁 Если мы для этого используем библиотеки clang, то логика такая:
1️⃣ Получаем AST (Abstract Syntax Tree) из исходного кода.
2️⃣ Лямбды в AST это вершины LambdaExpr.
3️⃣ "Объявление переменной" в AST это вершина VarDecl.
4️⃣ "Использование переменной" (в каком-то месте) это вершина DeclRefExpr.
5️⃣ Если все "использования переменной" находятся внутри какого-то одного и того же LambdaExpr, а "объявление переменной" находится вне этого LambdaExpr, то тест должен упасть, потому что данную переменную можно всунуть в capture list лямбды.
6️⃣ Делаем рекурсивный обход AST с корня и держанием указателя на "текущую лямбду", и делаем проверку на пункт 5.

Этот тест можно сделать на 👩‍💻 C++: вкостылить новый чекер в локальной сборке clang-tidy или просто сделать программу на libclang. Но можно сделать то же самое на 👩‍💻 Python и кода будет меньше в несколько раз, и это делается быстрее - менее муторно. Python хорошо подходит для быстрого написания разных тестов.

Поддерживается libclang в Python, и после просмотра примеров можно поставить его себе:
    pip install pytest
pip install clang
pip install libclang
и сделать такой простой тест, где реализуется описанная проверка для лямбд. Можно в директории рядом сохранить тестовый файл source.cpp и проверить, что тест падает:
    python3 -m pytest test.py

Вывод:
E           Failed: These variables can be declared in lambda capture: 
E "counter" (at source.cpp:3:44), to lambda at source.cpp:4:88

libclang на Python выглядит нормально, но неприятно то, что для понятия "нода AST" не к месту придумали новый термин "курсор".
Также не хватает некоторых очевидных фичей, например получения родительской ноды: в курсорах есть пара ссылок на другие курсоры (типа родительские, двух видов), но они работают неправильно.

Кроме тестов можно писать другие тулзы, например "кодогенераторы" - которые сгенерируют какой-нибудь исходник на основе существующего кода. Про кодогенераторы можно почитать лонгрид.

Еще можно делать "исправляторы" исходников - которые берут AST, что-то туда дописывают и сохраняют в другой файл, а компилятор имеет дело с уже поправленным AST (то есть с этим другим файлом).

BY C++95


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/cxx95/106

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

Two days after Russia invaded Ukraine, an account on the Telegram messaging platform posing as President Volodymyr Zelenskiy urged his armed forces to surrender. In February 2014, the Ukrainian people ousted pro-Russian president Viktor Yanukovych, prompting Russia to invade and annex the Crimean peninsula. By the start of April, Pavel Durov had given his notice, with TechCrunch saying at the time that the CEO had resisted pressure to suppress pages criticizing the Russian government. The perpetrators use various names to carry out the investment scams. They may also impersonate or clone licensed capital market intermediaries by using the names, logos, credentials, websites and other details of the legitimate entities to promote the illegal schemes. Recently, Durav wrote on his Telegram channel that users' right to privacy, in light of the war in Ukraine, is "sacred, now more than ever." On Telegram’s website, it says that Pavel Durov “supports Telegram financially and ideologically while Nikolai (Duvov)’s input is technological.” Currently, the Telegram team is based in Dubai, having moved around from Berlin, London and Singapore after departing Russia. Meanwhile, the company which owns Telegram is registered in the British Virgin Islands.
from in


Telegram C++95
FROM American