Skip to content

katafrakt/difftastic-elixir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Difftastic

This library, inspired by difftastic-ruby, provides integration with Difftastic - a next-level diffing tool based on tree-sitter.

ExUnit's default diffs are great for Elixir data structures, but when you have a big chunk of data, for example a HTML file (renderd email or LiveView component), it falls a bit short.

With Difftastic we can regain control and have much nicer, easier to reason about, diffs.

It also works nice with Elixir data structures, although the benefit is not as obvious as with HTML.

Installation

The package can be installed by adding difftastic to your list of dependencies in mix.exs:

def deps do
  [
    {:difftastic, "~> 0.1.0"}
  ]
end

Usage

This library relies on Difftastic being installed on your machine. It won't download or install it for you (unlike the Ruby counterpart). Refer to your system or distribution package manager to see how to install it. Tested examples:

  • In Arch Linux: pacman -S difftastic
  • In MacOS: brew install difftastic

Having the difft executable available and in PATH, you can run difftastic like this:

Difftastic.diff(html_1, html_2, "html")

The library also provides integration with ExUnit via importing Difftastic.Assertions module.

defmodule UuidGeneratorTest do
  use ExUnit.Case
  import Difftastic.Assertions

  test "diff html" do
    re1 = Req.get!("https://www.uuidgenerator.net/").body
    re2 = Req.get!("https://www.uuidgenerator.net/").body

    difft_assert_equal(re1, re2)
  end
end

Warning

Using difft_assert_equal brings a certain performance penalty. Difftastic is a CLI tool and using it from Elixir involves creating a files in temporary dir and running a system command against them. On my machine it can be as much as 300x slower than a regular assert on simple values. Make sure to use it when it really makes sense - for example for comparing large outputs - but not for everything.

Snapshot Testing

The library also provides snapshot testing functionality, which is useful for comparing complex outputs against saved references. This is particularly valuable for HTML, JSON, or other structured outputs that change infrequently but need visual inspection when they do.

defmodule EmailTemplateTest do
  use ExUnit.Case
  use Difftastic.SnapshotTest, dir: "test/snapshots"

  test "welcome email renders correctly" do
    html = EmailRenderer.render_template(:welcome, user: user)
    assert_snapshot_match("welcome_email.html", html)
  end
end

The first time the test runs, it will create the snapshot file. On subsequent runs, it will compare the current output with the saved snapshot, showing a visual diff using Difftastic if they don't match.

To update snapshots when the expected output intentionally changes, run:

UPDATE_SNAPSHOTS=1 mix test

State of development

This is a very early version, expect potential large changes in the future, including breaking ones. Note that this library does not use SemVer, but rather something closer to BreakVer.

About

diffing on steroids, now in Elixir

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages