Giter Site home page Giter Site logo

testable-ui's Introduction

Testable UI components

Make UI components that are pure state machines, then we can reuse the state logic with any render function, or without a render function.

Good

  • decouple component state from render function
  • automated testing (no browser necessary)
  • serializable events

Bad

  • Need to expose and document a larger interface โ€” the actions used by your component

example

MyInput

An input for a form.

API

Input.emitAction(data) -- return an emitter function.
var emitAction = Input.emitAction(Input()());
emitAction({
  type: 'change-value',
  value: 'example'
});
Actions
{
  type: 'change-value',
  value: ''
}
Input.value(data) -- return value in input.
var value = Input.value(Input()());

Input.js

var struct = require('observ-struct');
var value = require('observ');
var EE = require('events').EventEmitter;

module.exports = Input;

function Input(opts) {
  var bus = new EE();
  var emitAction = bus.emit.bind(bus, 'action');
  var onAction = bus.on.bind(bus, 'action');

  var state = struct({
    value: value(opts.value || ''),
    emitAction: value(emitAction)
  });

  onAction(function(action) {
    if (action.type === 'change-value') {
      state.value.set(action.value);
      console.log('value change', action);
    }
  });

  return state;
}

Input.value = function(data) {
  return data.value;
};

Input.emitAction = function(data) {
  return data.emitAction;
};

Input.render = function(h, state) {
  return h('label', [
    'my input',
    h('input', {
      name: 'test',
      type: 'text',
      value: state.value,
      oninput: function(ev) {
        var val = ev.target.value;
        state.emitAction({
          type: 'change-value',
          value: val
        });
      }
    })
  ]);
};

browser.js

var Loop = require('main-loop');
var vdom = require('virtual-dom');
var h = vdom.h;
var Input = require('./');

var appState = Input({ value: 'test value' });

var loop = Loop(appState(), render.bind(null, h), vdom);
appState(loop.update);
document.body.appendChild(loop.target);

function render(h, state) {
  return Input.render(h, state);
}

test.js

var test = require('tape');
var Input = require('./');

test('change value', function (t) {
  t.plan(2);

  var state = Input({ value: 'test' });
  var emitAction = Input.emitAction(state());
  t.equal(Input.value(state()), 'test');

  state(function onChange(data) {
    t.equal(Input.value(data), 'different value');
  });

  emitAction({
    type: 'change-value',
    value: 'different value'
  });

});

testable-ui's People

Contributors

nichoth avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.