package vdom

import (
	"strings"
	"testing"
)

// A boolean DOM property is a trap in HTML: the attribute's PRESENCE is what means
// true. checked="false" is a ticked checkbox — the value is not even read. So a false
// boolean prop must be omitted entirely, and a true one written bare.
func TestBoolPropSSR(t *testing.T) {
	ticked := RenderHTML(Input(Attr("type", "checkbox"), BoolProp("checked", true)))
	if !strings.Contains(ticked, " checked") {
		t.Errorf("a checked box did not render the attribute: %s", ticked)
	}
	if strings.Contains(ticked, `checked="`) {
		t.Errorf("a boolean attribute must be bare, not valued: %s", ticked)
	}

	unticked := RenderHTML(Input(Attr("type", "checkbox"), BoolProp("checked", false)))
	if strings.Contains(unticked, "checked") {
		t.Errorf(`an unchecked box must omit the attribute entirely — checked="false" renders as TICKED: %s`, unticked)
	}
}

// Non-boolean props keep their values: an input's value is a string, and dropping it
// when empty would be just as wrong as writing checked="false".
func TestValuePropSSRKeepsItsValue(t *testing.T) {
	got := RenderHTML(Input(Prop("value", "false")))
	if !strings.Contains(got, `value="false"`) {
		t.Errorf(`value="false" is a string, not a boolean, and must survive: %s`, got)
	}
}

func TestIsBoolProp(t *testing.T) {
	for _, k := range []string{"checked", "disabled", "selected", "open"} {
		if !IsBoolProp(k) {
			t.Errorf("%q should be known as a boolean property — the reconciler writes it as a string otherwise", k)
		}
	}
	for _, k := range []string{"value", "className", "id"} {
		if IsBoolProp(k) {
			t.Errorf("%q is not a boolean property", k)
		}
	}
}
