Notice: file_put_contents(): Write of 1038 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 16384 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: |

Stocks closed in the red Friday as investors weighed upbeat remarks from Russian President Vladimir Putin about diplomatic discussions with Ukraine against a weaker-than-expected print on U.S. consumer sentiment. And indeed, volatility has been a hallmark of the market environment so far in 2022, with the S&P 500 still down more than 10% for the year-to-date after first sliding into a correction last month. The CBOE Volatility Index, or VIX, has held at a lofty level of more than 30. Friday’s performance was part of a larger shift. For the week, the Dow, S&P 500 and Nasdaq fell 2%, 2.9%, and 3.5%, respectively. Either way, Durov says that he withdrew his resignation but that he was ousted from his company anyway. Subsequently, control of the company was reportedly handed to oligarchs Alisher Usmanov and Igor Sechin, both allegedly close associates of Russian leader Vladimir Putin. Given the pro-privacy stance of the platform, it’s taken as a given that it’ll be used for a number of reasons, not all of them good. And Telegram has been attached to a fair few scandals related to terrorism, sexual exploitation and crime. Back in 2015, Vox described Telegram as “ISIS’ app of choice,” saying that the platform’s real use is the ability to use channels to distribute material to large groups at once. Telegram has acted to remove public channels affiliated with terrorism, but Pavel Durov reiterated that he had no business snooping on private conversations.
from us


Telegram C++95
FROM American