Come testare i propri controller in isolamento: un esempio reale con CanCan
Nella stragrande maggioranza dei progetti ci si ritrova a dover gestire autorizzazioni e ruoli per gli utenti. La gemma più popolare per questo compito è senza dubbio CanCan. Mi sembra questo un ottimo esempio concreto da sfruttare per la trattazione.
Nella Wiki del progetto su Github, il buon Ryan Bates elenca un paio di possibili suggerimenti per approcciarsi al problema dei test funzionali. Nei passati progetti ho cercato di seguirli diligentemente, ma la verità è che sono esempi pessimi se seguiti nel mondo reale.
Partiamo con l'analizzare meglio i problemi.
Ottimizzare la leggibilità del proprio sito con Compass /3
Bene, dopo una sfarinatura su come mantenere un ritmo verticale tramite
Compass, su come impostare una scala tipografica, su come gestire in
maniera ottimale i font-size mediante em, arriviamo all'ultimo
passaggio: come scegliere in maniera ottimale line-height e font-size
per il tag <body>, ovvero le dimensioni che saranno di riferimento per l'intero sito?
La soluzione non è ovviamente farina del mio sacco, ma si rifà al concetto di Golden Ratio Typography, ideato da Chris Pearson.
L'impianto della trattazione si basa su due evidenze provabili empiricamente da chiunque:
- Le proprietà
font-sizeeline-heightsono legate linearmente: per mantenere un testo leggibile, se una aumenta l'altra dovrà aumentare proporzionalmente; - Similmente, larghezza del corpo del testo (da qui in poi
line-width) eline-heightsono legate linearmente: più la larghezza aumenta, più difficile diventa per l'occhio umano seguire le linee di testo, e dunque diventa necessario aumentare anche l'interlinea.
Chris Pearson si è spinto oltre, cercando di legare numericamente queste grandezze, facendo uso del famoso rapporto aureo:


Quindi, è sufficiente scegliere il font-size di riferimento, per
esempio 16px, e line-height e line-width verranno da sè:
1 $phi-const: 1.61803399
2 $base-font-size: 15px
3 $base-line-height: $base-font-size * $phi-const
4 $base-line-width: $base-line-height * $base-line-height
In linea teorica, il concetto termina qui. Dal punto di vista pratico
però, i nostri schermi lavorano su un'unità di misura non
"spezzabile": il pixel. Il calcolo riportato
porterebbe ad una interlinea di 24.27px, ovviamente non realizzabile.
Occorrerebbe portarlo a 24px, ma non sarebbe l'arrotondamento
ottimale.
Matematicamente parlando, ciò che bisogna realizzare è un
"minimizzatore" di errore, in grado di ricercare il minimo locale.
Trovare dunque la combinazione di pixel "interi" per font-size,
line-height e line-width che globalmente più si avvicinano ai valori aurei.
Non si tratta di calcoli piacevolissimi, e fortunatamente Chris Pearson
ha creato il Golden Ratio Typography Calculator,
che fa tutto il lavoro sporco per noi. Possiamo fissare sul calcolatore il font-size
prescelto, o piuttosto la larghezza del contenuto, o entrambi. Il buon
calcolatore ci restituirà il line-height ottimale, oltre a suggerirci
eventuali cambiamenti di dimensioni che potrebbero ulteriormente
migliorare la resa.
Niente. Dovrei aver finito, siete pronti per rendere i vostri blog super-leggibili. La mia parentesi tipografica si chiude temporaneamente.
Per un po' ritornerò a parlare di codice, tante cose bollono in pentola!
Ottimizzare la leggibilità del proprio sito con Compass /2
Al termine del post precedente, abbiamo visto come mantenere tutte le interlinee multiple tra di loro permetta una maggiore leggibilità del testo. Per essere più chiari, ecco un esempio di ciò di cui stiamo parlando.
Nel mondo web, l'unità base di spazio verticale è rappresentata dalla regola CSS
line-height.

Una line-height rimane costante nella pagina fino a quando non
intervengono cambi di font-size, margin, padding o border.
A questo punto tipicamente il flusso si spezza producendo interlinee
non multiple.
Riuscire a impostare dimensioni di margin, padding e border tali
da preservare il flusso verticale in tutta la pagina richiede una serie
di calcoli non particolarmente complessi, ma sicuramente poco divertenti.
Fortunatamente Compass include un modulo poco documentato ma ottimo in grado di alleviare di molto questo problema.
Vertical Rythm con Compass
Una volta importato il modulo tramite la direttiva
1 @import "compass/typography/vertical_rhythm"
siamo pronti a partire specificando il font-size e la line-height che abbiamo scelto
per il corpo principale del testo:
1 $base-line-height: 25px
2 $base-font-size: 15px
3
4 +establish-baseline
Il mixin +establish-baseline si occupa proprio di impostare questi due valori
sul selettore body (utilizzando come unità di misura l'em per
evitare problemi di resize su browser legacy).
Supponiamo di voler stilizzare il tag h1, portando il font-size a 24px,
e aggiungendo del margine in basso. Non possiamo più fare:
1 h1
2 font-size: 24px
3 margin-bottom: 15px
Ma dovremo invece scrivere qualcosa come:
1 h1
2 +adjust-font-size-to(24px, 2)
3 +padding-trailer(3, 24px)
Il primo mixin utilizzato, +adjust-font-size-to, oltre ad impostare il nuovo font-size,
modificherà la line-height dell'elemento in modo tale da preservare l'interlinea originaria
di 25px, od un suo multiplo. Il secondo parametro, impostato nell'esempio a 2,
imposterà un line-height effettivo di 25px * 2 = 50px.
Il mixin +padding-trailer, similmente, imposterà un padding-bottom in em pari
esattamente a 26px * 3 = 75px. Esistono ovviamente tutta una serie di mixin analoghi
per gestire allo stesso modo margini, padding e bordi superiori e inferiori.
E' importante ricordare di utilizzare numeri interi come parametri per tali mixin, a meno che la somma totale non risulti comunque essere un intero:
1 h1
2 +adjust-font-size-to(24px, 1.5)
3 +padding-leader(0.5, 24px)
4 +padding-trailer(1, 24px)
Questo esempio è comunque valido in quanto 1.5 + 0.5 + 1 = 3, che
continua ad essere un numero intero.
Ci fermiamo anche oggi
Nel prossimo post andremo ad analizzare l'ultima questione fondamentale
per la leggibilità: in base a quali parametri dovremo andare a scegliere
il $base-line-height e $base-line-height ottimale per la nostra pagina.
Referenze
- Compose to a Vertical Rhythm, Richard Rutter
- Scale & Rhythm, Iain Lamb
- Vertical Rythm Module, Compass Documentation
Ottimizzare la leggibilità del proprio sito con Compass /1
Nel recente restyling di questo blog mi sono concentrato sul rendere la lettura di ogni pagina il più piacevole possibile. Era un campo inesplorato per me, e sono talmente eccitato delle scoperte fatte e del risultato ottenuto che non posso non riassumervi qualcosa.
Innanzitutto, non stiamo parlando di tematiche specifiche per il web. I tipografi si occupano di questa materia da centinaia d'anni, ed è proprio dalle loro regole d'oro che bisogna partire.
In questa prima parte inizierò col descrivere le regole teoriche, nel prossimo post vedremo come applicarle in assoluta semplicità grazie ai vari mixin di Compass.
Non comporre mai una pagina senza una scala tipografica
Una delle regole fondamentali è questa: ogni variazione di font-size
che si desidera introdurre nella pagina deve seguire una scala
predefinita e regolare.
Non esiste una sola scala possibile; esistono differenti scale celebri e riconosciute come "naturali e piacevoli alla vista" in campo tipografico:
- Le successioni di Fibonacci;
- Il celebre Modulor di Le Corbusier;
- Il rapporto aureo;
- La storica e tradizionale "scala tipografica";
La scelta di una di queste scale va fatta a seconda del contesto e del
proprio gusto personale. Per quanto mi riguarda, ho deciso di utilizzare
la scala tipografica, con un'unica differenza, ovvero quella di scegliere
un font-size di 15px (invece che 16px come consigliato) per il contenuto
principale della pagina (il corpo del post). Sul perchè di questa scelta
ci torneremo nel prossimo post.

Tutti gli altri font-size seguono la medesima scala: nel mio
caso ho scelto 18px per gli h3, 21px per gli h2 e gli 24px per gli h1.
Mantieni un unico ritmo verticale nella pagina
Il concetto astratto di leggibilità si posa in gran parte sul concetto ben più materiale di interlinea (in inglese, leading): è lo spazio fra la linea di base di una riga e quella della successiva.
Conservare l'interlinea immutata nel flusso dell'intera pagina aiuta immensamente a renderla più piacevole e coerente.
Piccola digressione sull'em
L'em è una unità di misura relativa: il suo valore in pixel dipende
direttamente dal font-size assegnato all'elemento stesso.
1 body
2 font-size: 16px
3 line-height: 1.5em
Nell'esempio, l'interlinea varrà 16px * 1.5 = 24px, e mi permetterà
quindi di ottenere uno spazio vuoto tra le righe di testo pari a 24px -
16px = 8px.
Altra cosa fondamentale da ricordare è che la direttiva line-height viene
ereditata dagli elementi del DOM sottostanti:
1 body
2 font-size: 16px
3 line-height: 1.5em
4
5 h1
6 font-size: 18px
In questo caso, il tag h1 avrà anch'esso un line-height pari a
1.5em, ma questa si tradurrà in una interlinea pari a 18px * 1.5 =
27px.
Ultima cosa da ricordare riguardo all'em:
1 body
2 font-size: 16px
3 line-height: 1.5em
4
5 h1
6 font-size: 1.5em
Se è proprio la direttiva font-size ad avere una misura espressa in
em, allora questa sarà una misura relativa al font-size
dell'elemento padre. Nel nostro caso, il font-size per l'elemento h1
sarà di 16px * 1.5 = 24px, con una interlinea pari a 24px * 1.5 = 36px.
Impostare tutte le grandezze in em ci permette dunque di far
discendere tutte le proporzioni direttamente da un'unico parametro, il
font-size che si stabilisce per il body.
Per oggi basta
Nel prossimo post vedremo:
- come arrivare matematicamente al un valore di interlinea ottimale per la propria pagina;
- come ruscire ad ottenere un ritmo verticale facendo uso degli em;
- come applicare tutta questa teoria ai nostri fogli di stile Sass con dei semplici mixin.
Aspetto i vostri commenti!
https://github.com/jimweirich/rspec-given
rspec-given: e se fosse la soluzione?
Tornando a bomba sui miei interrogativi passati, potrei aver trovato una soluzione in grado di permettere una maggiore descrittività ai test -- in stile Gherkin -- ma al tempo stesso "sicura" (ovvero che non utilizzi librerie TDD ancora in stato alpha).
La soluzione si chiama rspec-given è non è altro
che una leggera DSL sopra ad RSpec, che permette di utilizzare dei
blocchi Given, When e Then.
Esempio d'ordinanza:
1 describe Stack do
2
3 def stack_with(initial_contents)
4 stack = Stack.new
5 initial_contents.each { |item| stack.push(item) }
6 stack
7 end
8
9 Given(:stack) { stack_with(initial_contents) }
10
11 context "when empty" do
12 Given(:initial_contents) { [] }
13 Then { stack.depth.should == 0 }
14
15 context "when pushing" do
16 When { stack.push(:an_item) }
17
18 Then { stack.depth.should == 1 }
19 Then { stack.top.should == :an_item }
20 end
21 end
22
23 end
Direi che la cosa migliore è provarlo per trovarne eventuali lati negativi o brutture. Vi faccio sapere.