[
{"fn": "initialFormState", "name": "a sign-up form starts empty, untouched and unsubmitted", "args": [{"email": "", "password": "", "name": ""}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "starting values are kept, and are what reset returns to", "args": [{"email": "ada@example.com", "name": "Ada"}], "expect": {"values": {"email": "ada@example.com", "name": "Ada"}, "initial": {"email": "ada@example.com", "name": "Ada"}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "the fields keep the order given, not alphabetical", "args": [{"surname": "", "given": "", "dob": ""}], "expect": {"values": {"surname": "", "given": "", "dob": ""}, "initial": {"surname": "", "given": "", "dob": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "a form with no fields is allowed", "args": [{}], "expect": {"values": {}, "initial": {}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "a checkbox group's value is its checked options joined by commas", "args": [{"contact": "email,sms", "terms": ""}], "expect": {"values": {"contact": "email,sms", "terms": ""}, "initial": {"contact": "email,sms", "terms": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "values are kept exactly, spaces and all (normalising is the validator's job)", "args": [{"email": " Ada@Example.COM "}], "expect": {"values": {"email": " Ada@Example.COM "}, "initial": {"email": " Ada@Example.COM "}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "a single field", "args": [{"q": "caps"}], "expect": {"values": {"q": "caps"}, "initial": {"q": "caps"}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "a dotted field name is just a name", "args": [{"address.line1": "1 High St", "address.postcode": "SW1A 1AA"}], "expect": {"values": {"address.line1": "1 High St", "address.postcode": "SW1A 1AA"}, "initial": {"address.line1": "1 High St", "address.postcode": "SW1A 1AA"}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "initialFormState", "name": "an empty field name is refused", "args": [{"": "x"}], "expectError": "a field name must not be empty"},
{"fn": "formReducer", "name": "change sets one value and leaves the rest", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "change", "name": "email", "value": "ada@example.com"}], "expect": {"values": {"email": "ada@example.com", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "formReducer", "name": "change does not touch the field or clear its error (validated does that)", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email"], "errors": {"email": "Enter an email address"}, "submitCount": 1, "status": "editing"}, {"type": "change", "name": "email", "value": "a"}], "expect": {"values": {"email": "a", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email"], "errors": {"email": "Enter an email address"}, "submitCount": 1, "status": "editing"}},
{"fn": "formReducer", "name": "change to an empty value clears a field", "args": [{"values": {"email": "ada@example.com", "password": "", "name": ""}, "initial": {"email": "ada@example.com", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "change", "name": "email", "value": ""}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "ada@example.com", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "formReducer", "name": "editing after a successful submit returns the form to editing", "args": [{"values": {"email": "a@b.co", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitted"}, {"type": "change", "name": "name", "value": "Ada"}], "expect": {"values": {"email": "a@b.co", "password": "", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "editing"}},
{"fn": "formReducer", "name": "blur marks the field touched, kept in the form's order", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["name"], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "blur", "name": "email"}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "name"], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "formReducer", "name": "blurring a touched field again changes nothing", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email"], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "blur", "name": "email"}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email"], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "formReducer", "name": "validated replaces the errors with a validator's fields", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {"name": "Enter your name"}, "submitCount": 0, "status": "editing"}, {"type": "validated", "errors": {"email": "Enter an email address", "password": "Use at least 15 characters."}}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {"email": "Enter an email address", "password": "Use at least 15 characters."}, "submitCount": 0, "status": "editing"}},
{"fn": "formReducer", "name": "validated with no fields clears every error", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"email": "Enter an email address"}, "submitCount": 1, "status": "editing"}, {"type": "validated", "errors": {}}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "editing"}},
{"fn": "formReducer", "name": "submit with errors counts the attempt and touches every field, but does not submit", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["password"], "errors": {"email": "Enter an email address"}, "submitCount": 0, "status": "editing"}, {"type": "submit"}], "expect": {"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"email": "Enter an email address"}, "submitCount": 1, "status": "editing"}},
{"fn": "formReducer", "name": "submit with no errors starts submitting", "args": [{"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 2, "status": "editing"}, {"type": "submit"}], "expect": {"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 3, "status": "submitting"}},
{"fn": "formReducer", "name": "a second submit while one is in flight changes nothing (a double click)", "args": [{"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitting"}, {"type": "submit"}], "expect": {"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitting"}},
{"fn": "formReducer", "name": "submitted ends a submit that succeeded", "args": [{"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitting"}, {"type": "submitted"}], "expect": {"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitted"}},
{"fn": "formReducer", "name": "failed ends the submit with the server's errors, a form-wide one included", "args": [{"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitting"}, {"type": "failed", "errors": {"email": "An account with this email already exists"}}], "expect": {"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"email": "An account with this email already exists"}, "submitCount": 1, "status": "editing"}},
{"fn": "formReducer", "name": "failed without errors (the network dropped) just ends the submit", "args": [{"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitting"}, {"type": "failed"}], "expect": {"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "editing"}},
{"fn": "formReducer", "name": "reset returns to the initial values and forgets everything else", "args": [{"values": {"email": "x", "password": "y", "name": "z"}, "initial": {"email": "", "password": "", "name": "Ada"}, "touched": ["email", "password", "name"], "errors": {"email": "Enter a valid email"}, "submitCount": 4, "status": "submitted"}, {"type": "reset"}], "expect": {"values": {"email": "", "password": "", "name": "Ada"}, "initial": {"email": "", "password": "", "name": "Ada"}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}},
{"fn": "formReducer", "name": "an unknown action type is refused", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "submitt"}], "expectError": "unknown form action type \"submitt\""},
{"fn": "formReducer", "name": "a change without a name is refused", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "change", "value": "x"}], "expectError": "a change action needs a name"},
{"fn": "formReducer", "name": "a blur without a name is refused", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "blur"}], "expectError": "a blur action needs a name"},
{"fn": "formReducer", "name": "a change to a field the form does not have is refused (a typo)", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "change", "name": "emial", "value": "x"}], "expectError": "unknown field \"emial\""},
{"fn": "formReducer", "name": "a change without a value is refused", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "change", "name": "email"}], "expectError": "a change action needs a value"},
{"fn": "formReducer", "name": "validated without errors is refused", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "validated"}], "expectError": "a validated action needs errors"},
{"fn": "formReducer", "name": "submitted with no submit in flight is refused", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}, {"type": "submitted"}], "expectError": "no submit is in progress"},
{"fn": "visibleErrors", "name": "nothing shows before the first submit, even for a touched field", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "name"], "errors": {"name": "Enter your name", "email": "Enter an email address"}, "submitCount": 0, "status": "editing"}], "expect": {}},
{"fn": "visibleErrors", "name": "after a submit every error shows, in the form's order, not the validator's", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"name": "Enter your name", "email": "Enter an email address"}, "submitCount": 1, "status": "editing"}], "expect": {"email": "Enter an email address", "name": "Enter your name"}},
{"fn": "visibleErrors", "name": "no errors after a submit shows nothing", "args": [{"values": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "initial": {"email": "ada@example.com", "password": "correct horse battery staple", "name": "Ada"}, "touched": ["email", "password", "name"], "errors": {}, "submitCount": 1, "status": "submitting"}], "expect": {}},
{"fn": "visibleErrors", "name": "a fixed field's error goes once validated clears it", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"name": "Enter your name"}, "submitCount": 2, "status": "editing"}], "expect": {"name": "Enter your name"}},
{"fn": "visibleErrors", "name": "a server error for a name that is not a field comes after the fields", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"form": "Sorry, there is a problem with the service", "password": "Use at least 15 characters."}, "submitCount": 1, "status": "editing"}], "expect": {"password": "Use at least 15 characters.", "form": "Sorry, there is a problem with the service"}},
{"fn": "visibleErrors", "name": "an empty message is no error", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email", "password", "name"], "errors": {"email": "", "name": "Enter your name"}, "submitCount": 1, "status": "editing"}], "expect": {"name": "Enter your name"}},
{"fn": "visibleErrors", "name": "after reset nothing shows", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": [], "errors": {}, "submitCount": 0, "status": "editing"}], "expect": {}},
{"fn": "visibleErrors", "name": "after a submit only touched fields show, should a state leave one untouched", "args": [{"values": {"email": "", "password": "", "name": ""}, "initial": {"email": "", "password": "", "name": ""}, "touched": ["email"], "errors": {"name": "Enter your name", "email": "Enter an email address"}, "submitCount": 1, "status": "editing"}], "expect": {"email": "Enter an email address"}},
{"fn": "visibleErrors", "name": "a form with no fields shows its form-wide error after a submit", "args": [{"values": {}, "initial": {}, "touched": [], "errors": {"form": "Try again later"}, "submitCount": 1, "status": "editing"}], "expect": {"form": "Try again later"}}
]