diff --git a/README.md b/README.md
index b08a36a..a356fb9 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ you will need to refactor it back into a regular template.
1. If a value is not updating correctly after a `wrapper.setProps` call, follow these steps to add a `nextTick()`, which will cause Vue to update the value:
1. If it's not already imported, add `import { nextTick } from "vue"`
2. Add `async` to the test arrow function.
- 3. Add `await nextTick()` between the `setProps` and the assertion.
+ 3. Add `await nextTick()` between the `setProps` and the assertion, or simply prepend the setProps command with `await`. (Example: `await wrapper.setProps({ show: true })`)
1. Refer to the [vue-test-utils migration guide](https://test-utils.vuejs.org/migration/) for other breaking changes.
1. Running the tests will produce a snapshot file. Compare it to the original snapshot file. If there are no substantial changes, commit it. If there are substantial changes, make any necessary changes.
diff --git a/src/components/LuxInputRadio.vue b/src/components/LuxInputRadio.vue
new file mode 100644
index 0000000..fb926c6
--- /dev/null
+++ b/src/components/LuxInputRadio.vue
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
{{ errormessage }}
+
+
+
+
+
+
+
+
+ ```jsx
+
+
+
+
+ ```
+
diff --git a/src/components/index.js b/src/components/index.js
index 4dbc5e4..0f32179 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,6 +1,7 @@
export * from "./icons"
import LuxInputButton from "./LuxInputButton.vue"
import LuxInputCheckbox from "./LuxInputCheckbox.vue"
+import LuxInputRadio from "./LuxInputRadio.vue"
import LuxInputSelect from "./LuxInputSelect.vue"
import LuxInputText from "./LuxInputText.vue"
import _LuxCardContent from "./_LuxCardContent.vue"
@@ -36,6 +37,7 @@ import LuxTag from "./LuxTag.vue"
export {
LuxInputButton,
LuxInputCheckbox,
+ LuxInputRadio,
LuxInputSelect,
LuxInputText,
_LuxCardContent,
diff --git a/tests/unit/specs/components/__snapshots__/luxInputRadio.spec.js.snap b/tests/unit/specs/components/__snapshots__/luxInputRadio.spec.js.snap
new file mode 100644
index 0000000..24e31f4
--- /dev/null
+++ b/tests/unit/specs/components/__snapshots__/luxInputRadio.spec.js.snap
@@ -0,0 +1,42 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`LuxInputRadio.vue has the expected html structure 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/tests/unit/specs/components/luxInputRadio.spec.js b/tests/unit/specs/components/luxInputRadio.spec.js
new file mode 100644
index 0000000..d39b4c4
--- /dev/null
+++ b/tests/unit/specs/components/luxInputRadio.spec.js
@@ -0,0 +1,123 @@
+import { createLocalVue, mount } from "@vue/test-utils"
+import { nextTick } from "vue"
+import LuxInputRadio from "@/components/LuxInputRadio.vue"
+
+describe("LuxInputRadio.vue", () => {
+ let wrapper
+
+ beforeEach(() => {
+ wrapper = mount(LuxInputRadio, {
+ slots: {
+ default: "Apply Changes.",
+ },
+ propsData: {
+ id: "foo",
+ options: [
+ {
+ name: "opt 1",
+ value: "one",
+ id: "radio-opt1",
+ checked: true,
+ },
+ {
+ name: "opt 2",
+ value: "two",
+ id: "radio-opt2",
+ checked: false,
+ },
+ ],
+ },
+ })
+ })
+
+ it("should emit a change event with the correct value when clicked", () => {
+ wrapper.findAll("input").at(1).trigger("change")
+ expect(wrapper.emitted().change[0]).toEqual(["two"])
+ })
+
+ it("should emit an inputblur event with the correct value when focus is blurred", () => {
+ const radio = wrapper.findAll("input").at(1)
+ radio.trigger("focus")
+ radio.trigger("blur")
+ const emitted = wrapper.emitted()
+ expect(Object.prototype.hasOwnProperty.call(emitted, "inputblur")).toBe(true)
+ })
+
+ it("should have a label for the correct id", () => {
+ const label = wrapper.findAll("label").at(1)
+ expect(label.text()).toBe("two")
+ expect(label.attributes().for).toBe("radio-opt2")
+ })
+
+ it("should stack if vertical is true", async () => {
+ const radio = wrapper.findAll(".lux-radio").at(0)
+ expect(radio.classes()).toContain("lux-inline")
+ await wrapper.setProps({ vertical: true })
+ expect(radio.classes()).not.toContain("lux-inline")
+ })
+
+ it("should display an errormessage with the proper role when passed in as a prop", async () => {
+ expect(wrapper.find(".lux-error").exists()).toBe(false)
+ await wrapper.setProps({ errormessage: "Something went wrong." })
+ expect(wrapper.find(".lux-error").exists()).toBe(true)
+ expect(wrapper.find(".lux-error").attributes().role).toBe("alert")
+ })
+
+ it("should display a legend if groupLabel is passed in as a prop", async () => {
+ expect(wrapper.find("legend").exists()).toBe(false)
+ await wrapper.setProps({ groupLabel: "Multiple choice:" })
+ expect(wrapper.find("legend").exists()).toBe(true)
+ })
+
+ it("should have the id that is passed in as a prop", () => {
+ const radio = wrapper.findAll("input").at(1)
+ expect(radio.attributes().id).toBe("radio-opt2")
+ })
+
+ it("should have a fieldset wrapper if groupLabel is passed in as a prop", async () => {
+ const fieldset = wrapper.find("fieldset")
+ expect(fieldset.exists()).toBe(false)
+ // can't setProps here because the component must be regenerated to change its wrapper
+ const wrapper2 = mount(LuxInputRadio, {
+ slots: {
+ default: "Apply Changes.",
+ },
+ propsData: {
+ id: "bar",
+ groupLabel: "Multiple choice:",
+ options: [
+ {
+ name: "opt 1",
+ value: "one",
+ id: "radio-opt1",
+ checked: true,
+ },
+ ],
+ },
+ })
+ const fieldset2 = wrapper2.find("fieldset")
+ expect(fieldset2.exists()).toBe(true)
+ })
+
+ // checked and disabled are not showing up in snapshots
+ // cannot seem to test
+ //
+ // it("should not be clickable if disabled", () => {
+ // wrapper.setProps({ options: [
+ // {
+ // name: "opt 1",
+ // value: "one",
+ // id: "radio-opt1",
+ // disabled: true,
+ // checked: false
+ // }
+ // ] })
+ // const radio = wrapper.findAll(".radio").at(0)
+ // radio.trigger("click")
+ // expect(radio.attributes().checked).toBe(false)
+ // })
+
+ it("has the expected html structure", () => {
+ expect(wrapper.element).toMatchSnapshot()
+ })
+})