Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
corpo {
cor-fundo: #f4f6f8;
cor: #22303c;
margem: 48px;
tamanho-fonte: 18px;
altura-linha: 1.6;
}

titulo1 {
cor: #0e3a5f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
liquido.rotaGet(funcao(requisicao, resposta) {
resposta.lmht({
"nome": "mundo"
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<lmht>
<cabeça>
<meta nome="viewport" conteudo="width=device-width, initial-scale=1.0" />
<recurso tipo="stylesheet" destino="/css/principal.css" />
<titulo>Bem-vindo ao Liquido</titulo>
</cabeça>
<corpo>
<titulo1>Olá, {{nome}}!</titulo1>
<p>Sua aplicação MVC em Liquido está no ar.</p>
<p>Para começar:</p>
<p>— A rota desta página fica em rotas/inicial.delegua;</p>
<p>— Esta visão fica em visoes/inicial.lmht;</p>
<p>— O estilo fica em estilos/principal.foles, transpilado automaticamente para publico/css/principal.css.</p>
<p>Qualquer alteração nesses diretórios recarrega a aplicação automaticamente. Boa jornada!</p>
</corpo>
</lmht>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
corpo {
cor-fundo: #f4f6f8;
cor: #22303c;
margem: 48px;
tamanho-fonte: 18px;
altura-linha: 1.6;
}

titulo1 {
cor: #0e3a5f;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
funcao rota_inicial(requisicao, resposta):
resposta.lmht({"nome": "mundo"})

liquido.rotaGet(rota_inicial)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<lmht>
<cabeça>
<meta nome="viewport" conteudo="width=device-width, initial-scale=1.0" />
<recurso tipo="stylesheet" destino="/css/principal.css" />
<titulo>Bem-vindo ao Liquido</titulo>
</cabeça>
<corpo>
<titulo1>Olá, {{nome}}!</titulo1>
<p>Sua aplicação MVC em Liquido está no ar.</p>
<p>Para começar:</p>
<p>— A rota desta página fica em rotas/inicial.pitu;</p>
<p>— Esta visão fica em visoes/inicial.lmht;</p>
<p>— O estilo fica em estilos/principal.foles, transpilado automaticamente para publico/css/principal.css.</p>
<p>Qualquer alteração nesses diretórios recarrega a aplicação automaticamente. Boa jornada!</p>
</corpo>
</lmht>
82 changes: 82 additions & 0 deletions testes/interface-linha-comando/novo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as sistemaArquivos from 'fs';
import * as so from 'os';
import caminho from 'path';

import { copiarArquivosDeExemploParaNovoProjeto } from '../../fontes/interface-linha-comando/novo';

/**
* Testes de regressão para o achado A4 (issue #103):
* o scaffold MVC não pode gerar um projeto sem código executável.
* Todo template deve entregar, no mínimo, uma rota inicial, uma visão
* inicial e um estilo inicial, para que `npx liquido` responda com uma
* página de boas-vindas no primeiro boot.
*/
describe('Comando novo - cópia de arquivos de exemplo', () => {
let diretorioTemporario: string;

beforeEach(() => {
diretorioTemporario = sistemaArquivos.mkdtempSync(
caminho.join(so.tmpdir(), 'liquido-novo-')
);
});

afterEach(() => {
sistemaArquivos.rmSync(diretorioTemporario, { recursive: true, force: true });
});

const casosMvc: [string, string][] = [
['delegua', 'inicial.delegua'],
['pitugues', 'inicial.pitu']
];

it.each(casosMvc)(
'projeto MVC em %s deve conter rota, visão e estilo iniciais',
async (linguagem: string, arquivoRota: string) => {
await copiarArquivosDeExemploParaNovoProjeto(
'meu-projeto',
'mvc',
linguagem,
diretorioTemporario
);

const arquivosEsperados = [
caminho.join(diretorioTemporario, 'rotas', arquivoRota),
caminho.join(diretorioTemporario, 'visoes', 'inicial.lmht'),
caminho.join(diretorioTemporario, 'estilos', 'principal.foles'),
caminho.join(diretorioTemporario, 'configuracao.delprops')
];

for (const arquivoEsperado of arquivosEsperados) {
expect(sistemaArquivos.existsSync(arquivoEsperado)).toBe(true);
const conteudo = sistemaArquivos.readFileSync(arquivoEsperado, 'utf-8');
expect(conteudo.trim().length).toBeGreaterThan(0);
}

// A rota inicial deve renderizar a visão (padrão MVC), e não texto puro.
const conteudoRota = sistemaArquivos.readFileSync(
caminho.join(diretorioTemporario, 'rotas', arquivoRota),
'utf-8'
);
expect(conteudoRota).toContain('liquido.rotaGet');
expect(conteudoRota).toContain('resposta.lmht');
}
);

it.each([['delegua', 'inicial.delegua'], ['pitugues', 'inicial.pitu']])(
'projeto API REST em %s deve continuar contendo rota inicial',
async (linguagem: string, arquivoRota: string) => {
await copiarArquivosDeExemploParaNovoProjeto(
'meu-projeto',
'api-rest',
linguagem,
diretorioTemporario
);

expect(
sistemaArquivos.existsSync(
caminho.join(diretorioTemporario, 'rotas', arquivoRota)
)
).toBe(true);
}
);
});
Loading