Repository: infernojs/inferno (js)
Issue: Inferno 3.5.0 and controlled checkboxes and radio
Controlled inputs like type='checkbox' or type='radio' generate the onClick events but do not fire onChange events. This is my fault also, I checked the onClick only in https://github.com/AlgoTrader/inferno-controls. 

Pull request description: Fixed change checked attribute for checkbox and radio after click
The Pull request close #1136 and #1146 

It is blocking issues for us. Will be nice to release new version of inferno.
I have also patch for master if needed 

@Havunen Please take a look.

Patch:
diff --git a/packages/inferno/src/DOM/wrappers/InputWrapper.ts b/packages/inferno/src/DOM/wrappers/InputWrapper.ts
index ee85f17f3..324d7d5a0 100644
--- a/packages/inferno/src/DOM/wrappers/InputWrapper.ts
+++ b/packages/inferno/src/DOM/wrappers/InputWrapper.ts
@@ -11,9 +11,9 @@ export function isCheckedType(type) {
 
 const onTextInputChange = createWrappedFunction("onInput", applyValue);
 
-const wrappedOnChange = createWrappedFunction("onChange");
+const wrappedOnChange = createWrappedFunction("onChange", applyValue);
 
-const onCheckboxChange = createWrappedFunction("onClick", applyValue);
+const onCheckboxChange = createWrappedFunction("onClick");
 
 export function processInput(
   vNode,
@@ -28,12 +28,12 @@ export function processInput(
 
     if (mounting) {
       if (isCheckedType(nextPropsOrEmpty.type)) {
-        dom.onclick = onCheckboxChange;
+        dom.onchange = wrappedOnChange;
       } else {
         dom.oninput = onTextInputChange;
       }
-      if (nextPropsOrEmpty.onChange) {
-        dom.onchange = wrappedOnChange;
+      if (nextPropsOrEmpty.onClick) {
+        dom.onclick = onCheckboxChange;
       }
     }
   }


Test patch:
diff --git a/packages/inferno/__tests__/input.spec.js b/packages/inferno/__tests__/input.spec.js
new file mode 100644
index 000000000..804632835
--- /dev/null
+++ b/packages/inferno/__tests__/input.spec.js
@@ -0,0 +1,105 @@
+import { render } from "inferno";
+import { innerHTML, triggerEvent } from "inferno-utils";
+
+describe("Input type checkbox", () => {
+  let container;
+
+  beforeEach(function() {
+    container = document.createElement("div");
+    document.body.appendChild(container);
+  });
+
+  afterEach(function() {
+    render(null, container);
+    container.innerHTML = "";
+    document.body.removeChild(container);
+  });
+
+  it("Checked attribute should be false", function() {
+    render(<input type="checkbox" checked={false} />, container);
+    const input = container.firstChild;
+
+    expect(input.checked).toBe(false);
+  });
+
+  it("Checked attribute after Click", function() {
+    let clickChecked = null;
+    let changeChecked = null;
+
+    render(
+      <input
+        type="checkbox"
+        checked={false}
+        onclick={e => {
+          clickChecked = e.target.checked;
+        }}
+        onchange={e => {
+          changeChecked = e.target.checked;
+        }}
+      />,
+      container
+    );
+    const input = container.firstChild;
+
+    triggerEvent("click", input);
+
+    expect(input.checked).toBe(false);
+    expect(clickChecked).toBe(true);
+    expect(changeChecked).toBe(true);
+  });
+});
+
+describe("Input type Radio", () => {
+  let container;
+
+  beforeEach(function() {
+    container = document.createElement("div");
+    document.body.appendChild(container);
+  });
+
+  afterEach(function() {
+    render(null, container);
+    container.innerHTML = "";
+    document.body.removeChild(container);
+  });
+
+  it("Controlled radio, checked=false", function() {
+    render(<input type="radio" checked={false} value="magic" />, container);
+    const input = container.firstChild;
+
+    expect(input.checked).toBe(false);
+  });
+
+  it("Checked attribute after Click", function() {
+    let clickChecked = null;
+    let changeChecked = null;
+
+    render(
+      <input
+        type="radio"
+        checked={false}
+        value="magic"
+        onclick={e => {
+          clickChecked = e.target.checked;
+        }}
+        onchange={e => {
+          changeChecked = e.target.checked;
+        }}
+      />,
+      container
+    );
+    const input = container.firstChild;
+
+    triggerEvent("click", input);
+
+    expect(clickChecked).toBe(true);
+	// check is jsdom
+    if (window.name === 'nodejs') {
+        expect(input.checked).toBe(true);
+        expect(changeChecked).toBe(null);
+    } else {
+        expect(input.checked).toBe(false);
+        expect(changeChecked).toBe(true);
+    }
+  });
+});
\ No newline at end of file