15 Commits

Author SHA1 Message Date
d0becd4063 Support de la compilation des slides via l'intégration continue et déploiement automatique
Signed-off-by: ynerant <ynerant@crans.org>
2021-02-08 20:37:49 +01:00
560e9ee6db On ne cherche pas à couvrir ce qui n'est pas testable
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-28 18:07:42 +01:00
db413e4a35 Réparation du tri
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-28 14:50:37 +01:00
e8fc6d0816 On remplace les if en elif pour avoir un résultat correct
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-28 14:47:20 +01:00
be7efbbfa7 Pour vérifier les calculs, on commence par transformer les entrées en entiers
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-28 14:45:58 +01:00
b8161eef93 Réparation des blagues
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-28 14:44:02 +01:00
bcfd13442f Réparation du séminaire
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-28 14:42:23 +01:00
f3dd9157c7 Ajout de tests pour tester toutes les fonctions
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-27 15:46:24 +01:00
40076ad3c1 Ajout d'un README pour les badges
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 18:57:48 +01:00
60e09751da Calcul de la couverture
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 18:47:18 +01:00
1fc558a2ad On utilise une classe pour les tests
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 18:37:12 +01:00
df223bd19e La fonction d'aide renvoie le texte à afficher au lieu de l'afficher directement
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 17:45:44 +01:00
7c2d082cf4 On lint le fichier de tests également
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 17:39:54 +01:00
1ba9934438 Pytest est requis
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 17:08:30 +01:00
d4d595ed68 Ajout d'un fichier de test avec pytest
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-01-26 17:07:12 +01:00
8 changed files with 374 additions and 34 deletions

12
.gitignore vendored
View File

@ -1,3 +1,15 @@
*.pyc
.pytest_cache
.coverage
venv
*.aux
*.log
*.nav
*.out
*.pdf
*.snm
*.synctex.gz
*.toc

View File

@ -1,6 +1,7 @@
stages:
- linting
- test
- compile_slides
flake8:
@ -8,7 +9,7 @@ flake8:
image: python:3-alpine
before_script:
- pip install flake8 --no-cache-dir
script: flake8 main.py
script: flake8 main.py main_test.py
allow_failure: true
@ -17,11 +18,32 @@ pylint:
image: python:3-alpine
before_script:
- pip install pylint --no-cache-dir
script: pylint main.py
script: pylint main.py main_test.py
allow_failure: true
test:
stage: test
image: python:3-alpine
script: python main.py
before_script:
- pip install pytest pytest-cov --no-cache-dir
script: pytest --showlocals --cov=main --cov=main_test --cov-report=term-missing .
slides:
stage: compile_slides
image: aergus/latex
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 0700 ~/.ssh
- ssh-keyscan ynerant.fr >> ~/.ssh/known_hosts
- chmod 0644 ~/.ssh/known_hosts
script:
- latexmk -cd -pdf slides/seminaire-ci.tex
- scp slides/seminaire-ci.pdf gitlab-ci@ynerant.fr:gitlab-ftp/seminaire-ci.pdf
artifacts:
paths:
- slides/seminaire-ci.pdf
expire_in: 1 mo

6
README.md Normal file
View File

@ -0,0 +1,6 @@
[![pipeline status](https://gitlab.crans.org/ynerant/seminaire-ci/badges/master/pipeline.svg)](https://gitlab.crans.org/ynerant/seminaire-ci/-/commits/master)
[![coverage report](https://gitlab.crans.org/ynerant/seminaire-ci/badges/master/coverage.svg)](https://gitlab.crans.org/ynerant/seminaire-ci/-/commits/master)
# Séminaire intégration continue
Ce dépôt contient le script utilisé lors du séminaire Crans du 11 février 2021, ainsi que les slides.

73
main.py Normal file → Executable file
View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""
Ce script est utilisé en guise d'appui pour le séminaire Crans d'introduction
@ -14,7 +14,7 @@ from random import choice
import sys
def main():
def main(): # pragma: nocover
"""
Fonction principale, qui va attendre les instructions de l'utilisateur.
"""
@ -24,36 +24,43 @@ def main():
while True:
command = input("> ")
args = command.split(" ")
print(globals()[args[0]](*args[1:]))
print(commande(args[0], *args[1:]))
def commande(name: str, *args):
"""
Exécute la commande `name` avec les arguments donnés.
"""
return globals()[name](*args)
def aide():
"""
Affiche l'aide
"""
print("aide\t\tAffiche l'aide")
print("seminaire\tLance le séminaire")
print("blague\t\tRaconte une blague")
print("calcul\t\tVérifie une opération arithmétique. "
"Par exemple, check(1, 2, 3, '+') renvoie True")
print("tri\t\tTrie une liste d'entiers.")
print("stop\t\tQuitte le programme")
return "aide\t\tAffiche l'aide\n" \
"seminaire\tLance le séminaire\n" \
"blague\t\tRaconte une blague\n" \
"calcul\t\tVérifie une opération arithmétique. " \
"Par exemple, check(1, 2, 3, '+') renvoie True\n" \
"tri\t\tTrie une liste d'entiers.\n" \
"stop\t\tQuitte le programme"
def seminaire():
"""
Affiche les slides du séminaire.
"""
print("\x4c\x61\x69\x73\x73\x65\x20\x74\x6f\x6d\x62\x65"
"\x72\x2c\x20\x74\x6f\x6e\x20\x74\x72\x75\x63\x20"
"\x65\x73\x74\x20\x74\x72\x6f\x70\x20\x62\x65\x75"
"\x67\x75\xe9\x2c\x20\x74\x75\x20\x64\x65\x76\x72"
"\x61\x69\x73\x20\x70\x61\x73\x73\x65\x72\x20\x64"
"\x75\x20\x74\x65\x6d\x70\x73\x20\xe0\x20\xe9\x63"
"\x72\x69\x72\x65\x20\x64\x65\x73\x20\x74\x65\x73"
"\x74\x73\x20\x65\x74\x20\x66\x61\x69\x72\x65\x20"
"\x64\xe9\x66\x69\x6c\x65\x72\x20\x74\x65\x73\x20"
"\x73\x6c\x69\x64\x65\x73")
return "\x4c\x61\x69\x73\x73\x65\x20\x74\x6f\x6d\x62\x65" \
"\x72\x2c\x20\x74\x6f\x6e\x20\x74\x72\x75\x63\x20" \
"\x65\x73\x74\x20\x74\x72\x6f\x70\x20\x62\x65\x75" \
"\x67\x75\xe9\x2c\x20\x74\x75\x20\x64\x65\x76\x72" \
"\x61\x69\x73\x20\x70\x61\x73\x73\x65\x72\x20\x64" \
"\x75\x20\x74\x65\x6d\x70\x73\x20\xe0\x20\xe9\x63" \
"\x72\x69\x72\x65\x20\x64\x65\x73\x20\x74\x65\x73" \
"\x74\x73\x20\x65\x74\x20\x66\x61\x69\x72\x65\x20" \
"\x64\xe9\x66\x69\x6c\x65\x72\x20\x74\x65\x73\x20" \
"\x73\x6c\x69\x64\x65\x73"
def blague():
@ -61,10 +68,10 @@ def blague():
Renvoie une blague aléatoire.
"""
return choice(
["Je vais vous raconter une blague sur, mais vous "
["Je vais vous raconter une blague sur UDP, mais vous "
"ne l'aurez peut-être pas.",
"Connaissez-vous la différence entre la théroie "
"et la pratique ? Il n'y en left pas, en théorie."])
"Connaissez-vous la différence entre la théorie "
"et la pratique ? Il n'y en a pas, en théorie."])
def calcul(left: int, right: int, res: int, operation='+'):
@ -72,19 +79,23 @@ def calcul(left: int, right: int, res: int, operation='+'):
Vérifie si left operation b == c, où a, b et c sont des entiers.
L'opération peut être +, -, *, /, &, |, ^, % ou l'un de ses alias anglais.
"""
left = int(left)
right = int(right)
res = int(res)
if operation in ['+', 'add', 'sum']:
result = left + right
if operation in ['-', 'sub']:
elif operation in ['-', 'sub']:
result = left - right
if operation in ['*', 'mul', 'prod']:
elif operation in ['*', 'mul', 'prod']:
result = left * right
if operation in ['/', 'div']:
elif operation in ['/', 'div']:
result = left / right
if operation in ['&', 'and']:
elif operation in ['&', 'and']:
result = left & right
if operation in ['|', 'or']:
elif operation in ['|', 'or']:
result = left | right
if operation in ['^', 'xor']:
elif operation in ['^', 'xor']:
result = left ^ right
else:
result = left % right
@ -95,7 +106,7 @@ def tri(*args):
"""
Trie les éléments donnés en argument.
"""
return sorted(args)
return sorted(int(number) for number in args)
def stop(exit_code: int = 0):
@ -106,5 +117,5 @@ def stop(exit_code: int = 0):
sys.exit(exit_code)
if __name__ == '__main__':
if __name__ == '__main__': # pragma: nocover
main()

89
main_test.py Executable file
View File

@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""
Exécution des tests du script.
"""
from random import randint, seed, shuffle
import unittest
import main
class TestMain(unittest.TestCase):
"""
Cette classe permet d'executer l'ensemble des scripts
"""
def test_aide(self):
"""
On essaie d'afficher l'aide,
et on vérifie si ça affiche la bonne chose.
"""
res = main.commande("aide")
lines = res.split("\n")
self.assertEqual(len(lines), 6)
self.assertTrue(lines[0].startswith("aide"))
self.assertTrue(lines[1].startswith("seminaire"))
self.assertTrue(lines[2].startswith("blague"))
self.assertTrue(lines[3].startswith("calcul"))
self.assertTrue(lines[4].startswith("tri"))
self.assertTrue(lines[5].startswith("stop"))
def test_seminaire(self):
"""
Test de l'affichage du "séminaire".
"""
res = main.commande("seminaire")
self.assertEqual(len(res), 114)
def test_blague(self):
"""
On teste les blagues, et on vérifie si
elles fonctionnent bien.
"""
seed(1)
res = main.commande("blague")
self.assertEqual(res, "Je vais vous raconter une blague sur UDP, "
"mais vous ne l'aurez peut-être pas.")
seed(5)
res = main.commande("blague")
self.assertEqual(res, "Connaissez-vous la différence entre la "
"théorie et la pratique ? "
"Il n'y en a pas, en théorie.")
def test_calcul(self):
"""
On vérifie que certains calculs basiques, puis aléatoires,
marchent bien.
"""
self.assertTrue(main.commande("calcul", 1, 2, 3))
self.assertFalse(main.commande("calcul", 1, 2, 2, '+'))
self.assertTrue(main.commande("calcul", 1, 2, 2, '*'))
self.assertTrue(main.commande("calcul", 42, 3, 14, 'div'))
self.assertTrue(main.commande("calcul", 16777215, 42, 42, 'and'))
self.assertTrue(main.commande("calcul", 16777213, 42, 16777215, 'or'))
self.assertFalse(main.commande("calcul", 15, 20, 35, 'xor'))
self.assertTrue(main.commande("calcul", 15, 20, 27, '^'))
self.assertTrue(main.commande("calcul", 100, 76, 24, 'unknown'))
left, right = randint(0, 0x7FFFFFFF), randint(0, 0x7FFFFFFF)
self.assertTrue(main.commande("calcul", left, right,
left - right, "-"))
def test_tri(self):
"""
À partir d'une liste donnée, on trie la liste
et on vérifie qu'elle est bien triée.
"""
my_list = ["23", "16", "234567", "-4"]
shuffle(my_list)
sorted_list = [-4, 16, 23, 234567]
self.assertEqual(main.commande("tri", *my_list), sorted_list)
def test_stop(self):
"""
On vérifie que le programme s'arrête bien.
"""
self.assertRaises(SystemExit, main.commande, "stop", 0)

132
slides/beamerthemecrans.sty Normal file
View File

@ -0,0 +1,132 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% BEAMER THEME FOR CRANS %%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% place in same folder as your .tex
% \usetheme{ens} in preamble
% also need crans-logo.png
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{ensbeamer}[2019/09/04 Beamer Theme]
\RequirePackage{tikz}
\RequirePackage{xcolor}
\makeatletter
\newif\if@section\@sectionfalse
\DeclareOption{sectiontitle}{
\@sectiontrue
}
\ProcessOptions\relax
\definecolor{rougecrans}{RGB}{207,14,34} % rougecrans !
\setbeamercolor{structure}{fg=rougecrans}
%\setbeamercolor{sidebar}{fg=rougecrans,bg=white}
\setbeamercolor{sidebar}{bg=white,fg=rougecrans}
%\setbeamercolor{title in sidebar}{fg=white}
%\setbeamercolor{section in sidebar}{fg=white}
\setbeamercolor{section in sidebar shaded}{fg=rougecrans!40}
\setbeamercolor{subsection in sidebar}{fg=rougecrans}
\setbeamercolor{subsection in sidebar shaded}{fg=rougecrans!60}
\setbeamercolor{frametitle}{fg=rougecrans,bg=white}
\def\swidth{2cm}
%
% -----------------------------
% Title Page
\setbeamerfont{title}{size=\huge}
\setbeamerfont{author}{size=\large}
\setbeamerfont{institut}{size=\Large}
\setbeamerfont{subtitle}{size=\Large}
\setbeamerfont{date}{size=\Large}
\setbeamertemplate{title page}{%
\begin{tikzpicture}[remember picture,overlay]
\fill[white]
(current page.north west) rectangle (current page.south east);
\node
at ([yshift=+.15\textheight]current page.center) (title)
{\usebeamerfont{title}\textcolor{rougecrans}{\inserttitle}};
\node[below=2em]
at(title) (subtitle)
{\usebeamerfont{subtitle}\textcolor{rougecrans}{\insertsubtitle}};
\node
at ([yshift=-70pt]current page.center) (institute)
{\usebeamerfont{institute}\textcolor{rougecrans}{\insertdate}};
\node
at ([yshift=-50pt]current page.center) (author)
{\usebeamerfont{author}\textcolor{rougecrans}{\insertauthor}};
\node [opacity=.15] at (current page.center) {\includegraphics[height=0.9\textheight]{crans-logo} };
\end{tikzpicture}
}
%
% --------------------------------------
% Sidebar
\useoutertheme[height=0pt,width=\swidth, hideothersubsections]{sidebar}
\setbeamertemplate{sidebar left}
{
{\vspace{0.9em}
\hspace{-0.4em}
\begin{minipage}{\swidth}
\centering
\insertlogo
\end{minipage}
\usebeamerfont{title in sidebar}%
\vskip1em%
\usebeamercolor[fg]{title in sidebar}%
\insertshorttitle[width=\swidth,center,respectlinebreaks]\par%
\vskip.5em%
}%
\insertverticalnavigation{\swidth}%
\vfill
\hbox to2cm{\hskip0.6cm\usebeamerfont{section in sidebar} \strut\usebeamercolor[fg]{section in sidebar}\insertframenumber/\inserttotalframenumber\hfill}%
\vskip3pt%
}%
% --------------------------------------------------------------------------
% Section as frame title
\if@section
\addtobeamertemplate{frametitle}{
\let\insertframetitle\insertsectionhead}{}
\addtobeamertemplate{frametitle}{
\let\insertframesubtitle\insertsubsectionhead}{}
\makeatletter
\CheckCommand*\beamer@checkframetitle{\@ifnextchar\bgroup\beamer@inlineframetitle{}}
\renewcommand*\beamer@checkframetitle{\global\let\beamer@frametitle\relax\@ifnextchar\bgroup\beamer@inlineframetitle{}}
\fi
\setbeamertemplate{caption}{\raggedright\insertcaption\par}
\setbeamertemplate{navigation symbols}[horizontal]
% ---------------------------------------------------
% BLOC
\setbeamertemplate{blocks}[rounded][shadow=false]
\setbeamercolor{block body}{fg=black,bg=rougecrans!20}
\setbeamercolor{block title}{fg=black,bg=rougecrans!40}
\setbeamercolor{block body example}{fg=black,bg=gray!40}
\setbeamercolor{block title example}{fg=black,bg=gray}
\setbeamercolor{block body alerted}{fg=black,bg=blue!40}
\setbeamercolor{block title alerted}{fg=black,bg=blue}
\setbeamercolor{subitem}{fg=rougecrans!20}
\makeatother
% LOGO :
\logo{\includegraphics[width=\swidth]{crans-logo.png}}

BIN
slides/crans-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

68
slides/seminaire-ci.tex Normal file
View File

@ -0,0 +1,68 @@
\documentclass[handout,aspectratio=169]{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[francais]{babel}
\usepackage{graphicx}
\usetheme[sectiontitle]{crans}
\title{Automatisez vos tâches avec une intégration continue}
\subtitle{Séminaire CRANS}
\author[]{\textsc{Yohann D'ANELLO}}
\date{11 février 2021}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\begin{frame}
\tableofcontents[subsubsectionstyle=hide]
\end{frame}
\section{Example}
\subsection{Block}
\begin{frame}
\begin{block}{Title block}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
\end{block}
\begin{block}{}
No title Block \\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
\end{block}
\begin{exampleblock}{Example Block}
Example text (ugly)
\end{exampleblock}
\begin{alertblock}{Alert Block}
Alert Text
\end{alertblock}
\end{frame}
\subsection{Lists}
\begin{frame}
\begin{itemize}
\item Item 1
\item Item 2
\begin{itemize}
\item Subitem 1
\item Subitem 2
\end{itemize}
\end{itemize}
\begin{enumerate}
\item item 1
\begin{enumerate}
\item item 1.1
\end{enumerate}
\item
\item
\item
\end{enumerate}
\end{frame}
\end{document}