defmodule Microprints.MicroprintTest do use ExUnit.Case, async: true alias Microprints.Microprint @fixture_path Path.expand("../support/fixtures/sample.ex", __DIR__) describe "generate/1" do test "returns microprint structure for valid file" do assert {:ok, microprint} = Microprint.generate(@fixture_path) assert is_map(microprint) assert is_list(microprint.lines) assert is_integer(microprint.line_count) assert microprint.line_count == length(microprint.lines) end test "returns error for missing file" do assert {:error, :enoent} = Microprint.generate("/nonexistent/file.ex") end test "all lines have color, indent, and length" do {:ok, microprint} = Microprint.generate(@fixture_path) Enum.each(microprint.lines, fn line_info -> assert is_map(line_info) assert String.starts_with?(line_info.color, "#"), "Expected hex color" assert String.length(line_info.color) == 7, "Expected 7-char hex color" assert is_integer(line_info.indent) assert line_info.indent >= 0 assert is_integer(line_info.length) assert line_info.length >= 0 end) end test "captures indentation levels" do {:ok, microprint} = Microprint.generate(@fixture_path) # First line (defmodule) should have 0 indent first_line = List.first(microprint.lines) assert first_line.indent == 0 # Find a line with indent (function body lines should be indented) indented_lines = Enum.filter(microprint.lines, &(&1.indent > 0)) assert length(indented_lines) > 0, "Expected some indented lines" end test "captures line lengths" do {:ok, microprint} = Microprint.generate(@fixture_path) # First line "defmodule Sample do" has content first_line = List.first(microprint.lines) assert first_line.length > 0 # Empty lines should have length 0 empty_lines = Enum.filter(microprint.lines, &(&1.length == 0)) assert length(empty_lines) > 0, "Expected some empty lines" # Lines vary in length lengths = Enum.map(microprint.lines, & &1.length) |> Enum.uniq() assert length(lengths) > 1, "Expected varying line lengths" end end describe "color classification for Elixir files" do test "module definitions get module color" do {:ok, microprint} = Microprint.generate(@fixture_path) # First line is "defmodule Sample do" first_line = List.first(microprint.lines) assert first_line.color == Microprint.color_for(:module) end test "function definitions get function_def color" do {:ok, microprint} = Microprint.generate(@fixture_path) colors = Enum.map(microprint.lines, & &1.color) assert Microprint.color_for(:function_def) in colors end test "comments get comment color" do {:ok, microprint} = Microprint.generate(@fixture_path) colors = Enum.map(microprint.lines, & &1.color) assert Microprint.color_for(:comment) in colors end test "atom-heavy lines get atom color" do {:ok, microprint} = Microprint.generate(@fixture_path) colors = Enum.map(microprint.lines, & &1.color) assert Microprint.color_for(:atom) in colors end end describe "color_for/1" do test "returns expected colors for known types" do assert Microprint.color_for(:keyword) == "#8B5CF6" assert Microprint.color_for(:string) == "#10B981" assert Microprint.color_for(:comment) == "#6B7280" assert Microprint.color_for(:function_def) == "#EF4444" assert Microprint.color_for(:atom) == "#F59E0B" assert Microprint.color_for(:number) == "#3B82F6" assert Microprint.color_for(:module) == "#EC4899" end test "returns default color for unknown types" do assert Microprint.color_for(:unknown) == "#D1D5DB" end end describe "color_legend/0" do test "returns list of label-color tuples" do legend = Microprint.color_legend() assert is_list(legend) assert length(legend) == 8 for {label, color} <- legend do assert is_binary(label) assert String.starts_with?(color, "#") end end test "includes key syntax types" do legend = Microprint.color_legend() labels = Enum.map(legend, fn {label, _} -> label end) assert "Function" in labels assert "Module" in labels assert "Keyword" in labels assert "String" in labels assert "Comment" in labels end end describe "non-Elixir files" do test "handles JavaScript-like files with generic colorization" do # Create a temp JS file tmp_path = Path.join(System.tmp_dir!(), "test_#{:rand.uniform(100_000)}.js") File.write!(tmp_path, """ // A comment function hello() { return "world"; } """) {:ok, microprint} = Microprint.generate(tmp_path) assert microprint.line_count == 5 # First line is a comment first_line = List.first(microprint.lines) assert first_line.color == Microprint.color_for(:comment) # Third line has indent (inside function) third_line = Enum.at(microprint.lines, 2) assert third_line.indent > 0 File.rm!(tmp_path) end end end