Skip to content

Commit

Permalink
Move usage to its own document
Browse files Browse the repository at this point in the history
  • Loading branch information
angelikatyborska committed Aug 13, 2023
1 parent ce3cf98 commit 5f5f3d3
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 108 deletions.
107 changes: 8 additions & 99 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

An Elixir client for [the Nu HTML Checker (v.Nu)](https://validator.w3.org/nu/).

![Expected HTML document to be valid, but got 1 error. Attribute html-is-awesome not allowed on element body at this point.](https://raw.github.com/angelikatyborska/vnu-elixir/main/assets/overview.png)

[v.Nu](https://validator.w3.org/nu/) is a document validity checker used by the W3C.
It offers validating HTML, CSS, and SVG documents.

Expand All @@ -24,7 +26,7 @@ Follow their instructions on how to download it and [run it as a web server](htt

The easiest option is to use the Docker image, like this:
```bash
docker run -it --rm -p 8888:8888 ghcr.io/validator/validator:latest
docker run -d --rm -p 8888:8888 ghcr.io/validator/validator:latest
```

The command might require an additional `--platform linux/amd64` flag on M1 macs.
Expand All @@ -39,7 +41,7 @@ HTTP/1.1 200 OK

Make sure to read about the [prerequisites](#prerequisites) first.

Add Vnu as a dependency to your project's `mix.exs`. To use the built-in, Hackney-based HTTP client adapter, add `:hackney` too:
Add Vnu as a dependency to your project's `mix.exs`. To use the built-in, Hackney-based HTTP client adapter, also add `:hackney`:

```elixir
defp deps do
Expand All @@ -50,6 +52,8 @@ defp deps do
end
```

TODO: describe what to do when you don't want to use hackney.

And run:

```bash
Expand All @@ -58,106 +62,11 @@ $ mix deps.get

## Documentation

[Available on hexdocs.pm](https://hexdocs.pm/vnu/api-reference.html).
[Available on hexdocs.pm](https://hexdocs.pm/vnu).

## Usage

### ExUnit assertions

If you are building an application that generates HTML, CSS, or SVG files, you might want to use those validations in your tests.

- `Vnu.Assertions.assert_valid_html/2`
- `Vnu.Assertions.assert_valid_css/2`
- `Vnu.Assertions.assert_valid_svg/2`

#### Phoenix controller test example

```elixir
defmodule PhoenixAppWeb.PageControllerTest do
use PhoenixAppWeb.ConnCase
import Vnu.Assertions

test "GET /", %{conn: conn} do
vnu_opts = %{server_url: "http://localhost:8888", fail_on_warnings: true}
conn = get(conn, "/")

html_response =
conn
|> get("/")
|> html_response(200)
|> assert_valid_html(vnu_opts)

assert html_response =~ "Welcome to Phoenix!"
end
end
```

See [`examples/1_phoenix_app/test/phoenix_app_web/controllers/page_controller_test.exs`](https://github.com/angelikatyborska/vnu-elixir/blob/master/examples/1_phoenix_app/test/phoenix_app_web/controllers/page_controller_test.exs) for more.

![](examples/1_phoenix_app_failing_test.png)

### Mix task

If you have static HTML, CSS, or SVG files in your project, you might want to validate them with those mix tasks:

- `mix vnu.validate.html`
- `mix vnu.validate.css`
- `mix vnu.validate.svg`

#### Example

```bash
$ mix vnu.validate.css --server-url http://localhost:8888 assets/**/*.css
```

![](examples/1_phoenix_app_failing_mix_task.png)

### General purpose

If you need HTML, CSS, or SVG validation for something else, try one of those functions:

- `Vnu.validate_html/2`
- `Vnu.validate_css/2`
- `Vnu.validate_svg/2`

```elixir
iex> {:ok, result} = Vnu.validate_html("<!DOCTYPE html><html><head></head></html>",
server_url: "http://localhost:8888")
{:ok,
%Vnu.Result{
messages: [
%Vnu.Message{
extract: "tml><head></head></html",
first_column: 28,
first_line: 1,
hilite_length: 7,
hilite_start: 10,
last_column: 34,
last_line: 1,
message: "Element “head” is missing a required instance of child element “title”.",
offset: nil,
sub_type: nil,
type: :error
},
%Vnu.Message{
extract: "TYPE html><html><head>",
first_column: 16,
first_line: 1,
hilite_length: 6,
hilite_start: 10,
last_column: 21,
last_line: 1,
message: "Consider adding a “lang” attribute to the “html” start tag to declare the language of this document.",
offset: nil,
sub_type: :warning,
type: :info
}
]
}}

iex> Vnu.valid?(result)
false
```
See [the usage guide](guides/usage.md).

## Development

Expand Down
File renamed without changes
File renamed without changes
Binary file added assets/overview.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ defmodule PhoenixAppWeb.PageControllerTest do
html_response =
conn
|> html_response(200)
|> assert_valid_html(
fail_on_warnings: false,
filter: PhoenixAppWeb.VnuHTMLMessageFilter
)
|> assert_valid_html(fail_on_warnings: false)

assert html_response =~ "Peace of mind from prototype to production"
end
Expand Down
1 change: 1 addition & 0 deletions examples/1_phoenix_app/test/support/conn_case.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ defmodule PhoenixAppWeb.ConnCase do
def assert_valid_html(html, vnu_opts \\ []) do
default_vnu_opts = [
server_url: Application.get_env(:phoenix_app, :vnu_server_url),
filter: PhoenixAppWeb.VnuHTMLMessageFilter,
fail_on_warnings: true
]

Expand Down
4 changes: 2 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Take a look at file `1_phoenix_app/test/phoenix_app_web/controllers/page_control

Run `mix test` to see the tests failing for invalid HTML and CSS documents.

![](1_phoenix_app_failing_test.png)
![](../assets/controller_test.png)

You can change the Checker server URL in `1_phoenix_app/config/test.exs`:

Expand All @@ -18,4 +18,4 @@ You can change the Checker server URL in `1_phoenix_app/config/test.exs`:

Run `mix vnu.validate.css --server-url http://localhost:8888 assets/**/*.css` to test the mix task.

![](1_phoenix_app_failing_mix_task.png)
![](../assets/mix_task.png)
44 changes: 44 additions & 0 deletions guides/installation.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,46 @@
# Installation

## Prerequisites

While it is possible to use this library with the service run by W3C at [validator.w3.org/nu](https://validator.w3.org/nu/),
I would recommend running your own instance. You will eliminate a lot of network latency if it runs on the same machine as your code, and you will not hit any rate limits that might exist for [validator.w3.org/nu](https://validator.w3.org/nu/).

The source of the Checker can be found in the repository [validator/validator](https://github.com/validator/validator).
Follow their instructions on how to download it and [run it as a web server](https://github.com/validator/validator#standalone-web-server).

The easiest option is to use the Docker image, like this:
```bash
docker run -it --rm -p 8888:8888 ghcr.io/validator/validator:latest
```

The command might require an additional `--platform linux/amd64` flag on M1 macs.

Check if the server is running:
```bash
$ curl localhost:8888 -I
HTTP/1.1 200 OK
```

## Installation

Make sure to read about the [prerequisites](#prerequisites) first.

Add Vnu as a dependency to your project's `mix.exs`. To use the built-in, Hackney-based HTTP client adapter, also add `:hackney`:

```elixir
defp deps do
[
{:vnu, "~> 1.1", only: [:dev, :test], runtime: false},
{:hackney, "~> 1.17"}
]
end
```

TODO: describe what to do when you don't want to use hackney.

And run:

```bash
$ mix deps.get
```

15 changes: 15 additions & 0 deletions guides/overview.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
# Overview

[![angelikatyborska](https://circleci.com/gh/angelikatyborska/vnu-elixir.svg?style=shield)](https://circleci.com/gh/angelikatyborska/vnu-elixir)
![Hex.pm](https://img.shields.io/hexpm/v/vnu)
![Hex.pm](https://img.shields.io/hexpm/dt/vnu)
![Hex.pm](https://img.shields.io/hexpm/l/vnu)
[![Coverage Status](https://coveralls.io/repos/github/angelikatyborska/vnu-elixir/badge.svg?branch=master)](https://coveralls.io/github/angelikatyborska/vnu-elixir?branch=master)

An Elixir client for [the Nu HTML Checker (v.Nu)](https://validator.w3.org/nu/).

![Expected HTML document to be valid, but got 1 error. Attribute html-is-awesome not allowed on element body at this point.](https://raw.github.com/angelikatyborska/vnu-elixir/main/assets/overview.png)

[v.Nu](https://validator.w3.org/nu/) is a document validity checker used by the W3C.
It offers validating HTML, CSS, and SVG documents.

This library brings that functionality to Elixir by using the Checker's JSON API.
It offers ExUnit assertions for validating dynamic content in tests, Mix tasks for validating static content, and general purpose functions to fulfill other needs.
129 changes: 127 additions & 2 deletions guides/usage.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,136 @@
# Usage

There are 3 different ways of using this library:
- ExUnit assertions,
- mix tasks for your static assets,
- or generic function calls for all other needs.

## ExUnit assertions

### Phoenix controller tests
If you are building an application that generates HTML, CSS, or SVG files, you might want to use those validations in your tests.

- `Vnu.Assertions.assert_valid_html/2`
- `Vnu.Assertions.assert_valid_css/2`
- `Vnu.Assertions.assert_valid_svg/2`

### Phoenix example

I would recommend defining a local `assert_valid_html` function in your [`ConnCase`](https://hexdocs.pm/phoenix/testing.html#the-conncase) to have a single place to pass your default options.

```elixir
defmodule PhoenixAppWeb.ConnCase do
use ExUnit.CaseTemplate

using do
quote do
# ...
def assert_valid_html(html, vnu_opts \\ []) do
default_vnu_opts = [
server_url: "http://localhost:8888/",
filter: PhoenixAppWeb.VnuHTMLMessageFilter,
fail_on_warnings: true
]

Vnu.Assertions.assert_valid_html(html, Keyword.merge(default_vnu_opts, vnu_opts))
end
end
end
end
```

Then, you can use this function in your controller tests, LiveView tests, and integration tests.

#### Controller tests

```elixir
defmodule PhoenixAppWeb.PageControllerTest do
use PhoenixAppWeb.ConnCase

test "GET /", %{conn: conn} do
conn = get(conn, "/")

html_response =
conn
|> html_response(200)
|> assert_valid_html(fail_on_warnings: false)

assert html_response =~ "Peace of mind from prototype to production"
end
end
```

![](https://raw.github.com/angelikatyborska/vnu-elixir/main/assets/controller_test.png)

### Phoenix LiveView tests

#### LiveView tests

TODO: add to example phoenix app and describe

#### Hound integration tests

TODO: add to example phoenix app and describe

## Mix tasks

If you have static HTML, CSS, or SVG files in your project, you might want to validate them with those mix tasks:

- `mix vnu.validate.html`
- `mix vnu.validate.css`
- `mix vnu.validate.svg`
-
### Example

```bash
$ mix vnu.validate.css --server-url http://localhost:8888 assets/**/*.css
```

![](https://raw.github.com/angelikatyborska/vnu-elixir/main/assets/mix_task.png)

## Other needs

If you need HTML, CSS, or SVG validation for something else, try one of those functions:

- `Vnu.validate_html/2`
- `Vnu.validate_css/2`
- `Vnu.validate_svg/2`

### Example

```elixir
iex> {:ok, result} = Vnu.validate_html("<!DOCTYPE html><html><head></head></html>",
server_url: "http://localhost:8888")
{:ok,
%Vnu.Result{
messages: [
%Vnu.Message{
extract: "tml><head></head></html",
first_column: 28,
first_line: 1,
hilite_length: 7,
hilite_start: 10,
last_column: 34,
last_line: 1,
message: "Element “head” is missing a required instance of child element “title”.",
offset: nil,
sub_type: nil,
type: :error
},
%Vnu.Message{
extract: "TYPE html><html><head>",
first_column: 16,
first_line: 1,
hilite_length: 6,
hilite_start: 10,
last_column: 21,
last_line: 1,
message: "Consider adding a “lang” attribute to the “html” start tag to declare the language of this document.",
offset: nil,
sub_type: :warning,
type: :info
}
]
}}

iex> Vnu.valid?(result)
false
```
2 changes: 1 addition & 1 deletion lib/vnu/http_client/hackney.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule Vnu.HTTPClient.Hackney do
@moduledoc """
HTTPoison-based HTTP client adapter.
Hackney-based HTTP client adapter.
"""

@behaviour Vnu.HTTPClient
Expand Down
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ defmodule Vnu.MixProject do
defp docs do
[
main: "overview",
assets: "assets",
extras: [
"guides/overview.md",
"guides/installation.md",
Expand Down

0 comments on commit 5f5f3d3

Please sign in to comment.