RSSPAPER/docs/index.html
GitHub Action 1e9fd086c0 2021-07-18
2021-07-18 09:54:25 +00:00

501 lines
24 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RSSPaper</title>
<link rel="icon" type="image/png" href="favicon.png">
<meta name="theme-color" content="#3c790a">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
<meta name="author" content="Tu nombre">
<meta name="generator" content="RSSpaper">
<meta name="keywords" content="html, css, javascript">
<meta name="description" content="My news">
<meta property="og:image" content="img/screenshot.png">
<meta property="og:title" content="The Rock">
<meta property="og:type" content="website">
<meta property="og:url" content="">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@cuenta">
<meta name="twitter:creator" content="@cuenta">
<meta property="og:image:secure_url" content="https://...">
<meta property="og:image:type" content="image/jpeg">
<meta property="og:image:width" content="400">
<meta property="og:image:height" content="300">
<meta property="og:image:alt" content="">
<!-- Normalize -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<!-- End Normalize -->
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<!-- End Fonts -->
<!-- CSS -->
<style>
/* Global */
:root {
--color-black: black;
--color-gray: gray;
--height-img: 10rem;
}
body {
margin: 0;
padding: 0;
font-family: 'Newsreader', serif;
color: var(--color-black);
}
img {
object-fit: cover;
object-position: center;
}
img, video, iframe {
width: 100%;
}
a {
color: var(--color-black);
text-decoration: none;
}
pre {
overflow-x: auto;
}
.container {
max-width: 62rem;
margin: 0 auto;
padding: 1rem;
}
.header {
margin-bottom: 2rem;
}
.title {
text-align: center;
font-size: 4rem;
font-weight: normal;
margin-bottom: 0;
margin-top: 1rem;
}
.subtitle {
display: flex;
justify-content: center;
align-items: center;
margin-top: -1rem;
font-weight: normal;
font-size: 1.5rem;
}
.subtitle__separator {
font-size: 3rem;
font-weight: bold;
}
.separator {
border: 0;
background: var(--color-black);
height: 1px;
}
.footer__text {
text-align: center;
padding: 1rem 0;
}
.footer__link {
font-weight: bold;
}
.footer__heard {
display: inline-block;
margin-left: .3rem;
}
.article__title, .article__feed {
font-weight: normal;
}
.article__header-img > a > img {
height: var(--height-img);
object-position: center;
object-fit: contain;
}
.article__random-background {
height: var(--height-img);
width: 100%;
}
</style>
<style media="all and (max-width: 600px)">
/* Mobile */
</style>
<style media="all and (min-width: 601px)">
/* Desktop */
.main {
display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(12, 1fr);
}
/* First column. */
.feed__article:nth-child(3n-2){
grid-column: 9 / 13;
}
/* Second column */
.feed__article:nth-child(3n+2){
grid-column: 1 / 5;
}
/* Third column */
.feed__article:nth-child(3n+3) {
grid-column: 5 / 9;
}
.article__title {
font-size: 1.5rem;
}
.article__feed {
font-size: 1rem;
}
.article__date {
font-size: .9rem;
color: var(--color-gray);
}
.feed__article:nth-child(1) .article__title {
font-size: 2rem;
}
.feed__article:nth-child(1) .article__feed {
font-size: 1rem;
}
.feed__article:nth-child(1) {
grid-column: 1 / 9;
grid-row: 1 / 4;
text-align: center;
}
.feed__article:nth-child(2) {
grid-column: 9 / 13;
grid-row: 1 / 2;
}
.feed__article:nth-child(3) {
grid-column: 9 / 13;
grid-row: 2 / 3;
}
.feed__article:nth-child(4) {
grid-column: 9 / 13;
grid-row: 3 / 4;
}
.feed__article:nth-child(2) .article__header,
.feed__article:nth-child(3) .article__header,
.feed__article:nth-child(4) .article__header
{
display: flex;
justify-content: space-between;
flex-direction: row-reverse;
grid-gap: 1rem;
}
.article__header > p {
margin: 0;
}
.article__header-img > img {
height: var(--height-img);
}
.feed__article:nth-child(1) .article__header-img > img,
.feed__article:nth-child(2) .article__header-img > img,
.feed__article:nth-child(3) .article__header-img > img,
.feed__article:nth-child(4) .article__header-img > img
{
height: initial;
}
.feed__article:nth-child(2) .article__titles,
.feed__article:nth-child(3) .article__titles,
.feed__article:nth-child(4) .article__titles,
.feed__article:nth-child(2) .article__header-img,
.feed__article:nth-child(3) .article__header-img,
.feed__article:nth-child(4) .article__header-img
{
width: 50%;
}
.feed__article:nth-child(2) .article__title,
.feed__article:nth-child(3) .article__title,
.feed__article:nth-child(4) .article__title
{
font-size: 1.2rem;
}
.feed__article:nth-child(2) .article__feed,
.feed__article:nth-child(3) .article__feed,
.feed__article:nth-child(4) .article__feed
{
font-size: 1rem;
}
.article__main {
position: fixed;
left: -100%;
top: 0;
bottom: 0;
overflow-y: auto;
}
.feed__article:nth-child(1) .article__random-background {
height: initial;
}
</style>
<!-- End CSS -->
</head>
<body>
<div class="container">
<header class="header">
<h1 class="title">RSSPaper</h1>
<h2 class="subtitle"><span class="subtitle__separator">~</span> <span class="subtitle__text">My static generate newspaper</span> <span class="subtitle__separator">~</span></h2>
<hr class="separator">
</header>
<main class="main">
<article class="feed__article article">
<header class="article__header">
<p class="article__header-img">
<a target="_blank" href="https://programadorwebvalencia.com/aprende-a-estructurar-un-test/">
<img loading="lazy" src="https://programadorwebvalencia.com/img/blog/2021/07/testing.png" alt="Aprende a estructurar un test">
</a>
</p>
<div class="article__titles">
<h1 class="article__title">
<a target="_blank" href="https://programadorwebvalencia.com/aprende-a-estructurar-un-test/">Aprende a estructurar un test</a>
</h1>
<h2 class="article__feed"><a target="_blank" href="https://programadorwebvalencia.com/">Programador Web Valencia</a> <span class="article__date">15 07 2021</span></h2>
</div>
</header>
<main class="container article__main">
<p><img src="https://programadorwebvalencia.com/img/blog/2021/07/testing.png" alt="Comisión" /></p>
<p>Usar un flujo de testing de algún tipo (TDD, BDD, E2E…) es una buena <strong>medida de calidad</strong>. No porque te asegure que la función u objeto funcione como esperas, sino porque indica que el proyecto posee una <strong>buena arquitectura</strong> y detrás hay buenos desarrolladores.</p>
<p>Hacer testing <strong>no trata solo sobre crear código</strong> que compruebe otro código, sino una <strong>metodología de trabajo profesional</strong> que amplia la visión del código. Escribes un preciso guión de que buscas, dejando claro como debe comportarse y de que manera reaccionará en casos extraordinarios. Todo ello sin tan siquiera escribir la funcionalidad. Además, de manera indirecta, dejas documentado el funcionamiento.</p>
<p>Suele decirse que hacer testing es artesanal, que todos los casos son únicos. No es cierto, disponemos de <strong>patrones o plantillas que nos ayudan</strong> a empezar y estructurar. Y entre las más sencillas y conocidos son encontramos con <strong>Given-When-Then</strong>.</p>
<h2 id="plantilla-given-when-then">Plantilla Given-When-Then</h2>
<p>Creado por Daniel Terhorst-North y Chris Matts como parte de <strong>BDD</strong> (Behavior-Driven Development), son sugieren un patrón de <strong>3 bloques informales de comentarios</strong> para dividir el código.</p>
<ol>
<li><strong>Given</strong> (Dado): Preparas el escenario del test, como la base de datos, variables o condiciones propicias.</li>
<li><strong>When</strong> (Cuando): Condiciones que transformarán el contenido.</li>
<li><strong>Then</strong> (Entonces): Verificas el resultado final, que se ha cumplido todo lo que esperabas o los casos propuestos.</li>
</ol>
<p>Pongamos sobre la mesa un ejemplo en prosa. Vamos a escribir un test para el cuento de “los 3 cerditos”. El objetivo es comprobar que están a salvo del lobo.</p>
<p><strong>Dado</strong> 3 casas, [paja, madera, ladrillos]…</p>
<p><strong>Cuando</strong> sople el lobo sobre cada una…</p>
<p><strong>Entonces</strong> debe existir 1 o más casas en pie.</p>
<p>Ahora vamos a crear un <strong>ejemplo real en JavaScript</strong> pero muy simple. Queremos una función que nos informe si una anchura y una altura de una imagen iguales. Tal solo indicaremos cuanto es la anchura y altura, devolviendo un <code class="highlighter-rouge">true</code>, <code class="highlighter-rouge">false</code> o <code class="highlighter-rouge">null</code> dependiendo la situación.</p>
<p>Primero definimos la función, pero sin contenido, en <code class="highlighter-rouge">imagenes.js</code>. Podrías considerar que estas documentando.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// imagenes.js</span>
<span class="cm">/**
* Comprueba si es una medida cuadrada o contiene la misma anchura y altura
* @param float anchura
* @param float altura
* @return boolean, en caso de no disponer de argumentos con el tipo correcto devolverá un null
*/</span>
<span class="kd">function</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura</span><span class="p">,</span> <span class="nx">altura</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="c1">// Exportamos para que pueda ser invocado desde otros lugares</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">esAnchuraYAlturaCuadrada</span>
<span class="p">};</span>
</code></pre></div></div>
<p>Ahora hacemos uso de <strong>Jest</strong> para hace el test. Creamos siguiente archivo <code class="highlighter-rouge">imagenes.test.js</code>.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// imagenes.test.js</span>
<span class="kd">const</span> <span class="p">{</span><span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">./imagenes</span><span class="dl">'</span><span class="p">);</span>
<span class="cm">/* Given */</span>
<span class="nx">anchura_1</span> <span class="o">=</span> <span class="mi">500</span><span class="p">;</span>
<span class="nx">altura_1</span> <span class="o">=</span> <span class="mi">250</span><span class="p">;</span>
<span class="nx">anchura_2</span> <span class="o">=</span> <span class="mi">400</span><span class="p">;</span>
<span class="nx">altura_2</span> <span class="o">=</span> <span class="mi">400</span><span class="p">;</span>
<span class="nx">anchura_3</span> <span class="o">=</span> <span class="mf">400.2</span><span class="p">;</span>
<span class="nx">altura_3</span> <span class="o">=</span> <span class="mi">400</span><span class="p">;</span>
<span class="nx">anchura_4</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">altura_4</span> <span class="o">=</span> <span class="mi">150</span><span class="p">;</span>
<span class="nx">anchura_5</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="nx">altura_5</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">boo</span><span class="dl">"</span><span class="p">;</span>
<span class="cm">/* When */</span>
<span class="nx">resultados_1</span> <span class="o">=</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura_1</span><span class="p">,</span> <span class="nx">altura_1</span><span class="p">);</span>
<span class="nx">resultados_2</span> <span class="o">=</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura_2</span><span class="p">,</span> <span class="nx">altura_2</span><span class="p">);</span>
<span class="nx">resultados_3</span> <span class="o">=</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura_3</span><span class="p">,</span> <span class="nx">altura_3</span><span class="p">);</span>
<span class="nx">resultados_4</span> <span class="o">=</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura_4</span><span class="p">,</span> <span class="nx">altura_4</span><span class="p">);</span>
<span class="nx">resultados_5</span> <span class="o">=</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura_5</span><span class="p">,</span> <span class="nx">altura_5</span><span class="p">);</span>
<span class="cm">/* Then */</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">No son iguales</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">resultados_1</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">Son iguales</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">resultados_2</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">No son iguales</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">resultados_3</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">No se puede comparar un texto con un número</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">resultados_4</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">No se puede comparar un boolean con un texto</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">resultados_5</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Instalamos la librería <strong>Jest</strong> que será la encargada de realizar los test.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install</span> <span class="nt">--save-dev</span> jest
</code></pre></div></div>
<p>Y lo ejecutamos.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./node_modules/jest/bin/jest.js
</code></pre></div></div>
<p>Obviamente fallarán todas.</p>
<p>Ya sabemos que buscamos, y que debe devolver. Es hora de definir la función.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// imagenes.js</span>
<span class="cm">/**
* Comprueba si es una medida cuadrada o contiene la misma anchura y altura
* @param float anchura
* @param float altura
* @return boolean, en caso de no disponer de argumentos con el tipo correcto devolverá un null
*/</span>
<span class="kd">function</span> <span class="nx">esAnchuraYAlturaCuadrada</span><span class="p">(</span><span class="nx">anchura</span><span class="p">,</span> <span class="nx">altura</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Es un número?</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">anchura</span> <span class="o">===</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">anchura</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nx">altura</span> <span class="o">===</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">altura</span><span class="p">))</span> <span class="p">{</span>
<span class="c1">// Es igual?</span>
<span class="k">return</span> <span class="nx">anchura</span> <span class="o">==</span> <span class="nx">altura</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Exportamos para que pueda ser invocado desde otros lugares</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">esAnchuraYAlturaCuadrada</span>
<span class="p">};</span>
</code></pre></div></div>
<p>Cuando se vuelva a testear comprobarás que pasa todos los casos.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> PASS ./imagenes.test.js
✓ No son iguales <span class="o">(</span>2 ms<span class="o">)</span>
✓ Son iguales <span class="o">(</span>1 ms<span class="o">)</span>
✓ No son iguales
✓ No se puede comparar un texto con un número <span class="o">(</span>1 ms<span class="o">)</span>
✓ No se puede comparar un boolean con un texto
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 0.317 s, estimated 1 s
Ran all <span class="nb">test </span>suites.
</code></pre></div></div>
<p>Has sido testigo de todos los pasos típicos en un desarrollo con la metodología TDD.</p>
<ol>
<li>Documentar.</li>
<li>Crear test.</li>
<li>Ejecutar el test, recibiendo que falla.</li>
<li>Crear la funcionalidad.</li>
<li>Volver a ejecutar, recibiendo un éxito.</li>
</ol>
<p>Si quieres profundizar, puedes explorar mi <a href="/cursos/testing/introducción/">curso gratuito de testing</a> donde podrás conocer otras técnicas e implementaciones en otros lenguajes.</p>
</main>
</article>
<article class="feed__article article">
<header class="article__header">
<p class="article__header-img">
<a target="_blank" href="https://diarioestoico.com/memento-mori-estoicismo/">
<img loading="lazy" src="https://diarioestoico.com/wp-content/uploads/2020/03/cropped-logo-estoico-footer-150x150-1-32x32.png" alt="MEMENTO MORI">
</a>
</p>
<div class="article__titles">
<h1 class="article__title">
<a target="_blank" href="https://diarioestoico.com/memento-mori-estoicismo/">MEMENTO MORI</a>
</h1>
<h2 class="article__feed"><a target="_blank" href="https://diarioestoico.com">Diario Estoico</a> <span class="article__date">11 07 2021</span></h2>
</div>
</header>
<main class="container article__main">
Se hacen bromas sobre la muerte, «me muero de risa», «esta comida está de muerte» , «hace un calor para morirse» pero cuando la tenemos de cerca se acaban las bromas. El trato hacia la muerte es algo cultural, y depende del lugar del mundo, se percibe de una manera o de otra, la muerte [&#8230;]
</main>
</article>
</main>
</div>
<footer class="footer">
<hr class="separator">
<p class="footer__text">
Generated with <a class="footer__link" href="https://github.com/tanrax/RSSpaper">RSSpaper</a> and a lot of <span class="footer__heard">❤️</span>
</p>
</footer>
<script defer>
function getRandomNumber(min, max) {
return Math.random() * (max - min) + min;
}
function getRandomHexColor() {
return '#'.concat(Math.floor(Math.random() * 16777215).toString(16));
}
// Random background
document.querySelectorAll('.article__random-background').forEach((canvas) => {
canvas.style.backgroundImage = `linear-gradient(${getRandomNumber(0, 360)}deg, ${getRandomHexColor()}, ${getRandomHexColor()})`;
});
</script>
</body>
</html>