Skip to content

Instantly share code, notes, and snippets.

Avatar

Glen Mailer glenjamin

View GitHub Profile
@glenjamin
glenjamin / on-testing.md
Created Aug 7, 2021
Testing blogpost intro
View on-testing.md

How I do automated tests

There’s a lot of posts out there where people will tell you how to do something. How you must do something in a certain way. How you’re not a real developer unless you do things in this particular way. I hate that sort of post.

I strongly believe that there isn’t such a thing as a best practice. There are effective practices that work well in certain contexts, but might be less effective in other contexts - although I’m pretty confident that some practices aren’t effective in any context. I do, however, think there’s a lot of value to be found in taking a practice that’s successful in one context, and finding ways to adapt or generalise it into more contexts.

So with those caveats out of the way, here’s a post that tries to explain and justify how I personally write my automated tests. These approaches have been shaped over the years by my own experiences but also by the opinions of my colleagues and how well (or not) we’ve seen them work.

The techniques I’m writing about here

@glenjamin
glenjamin / routing.js
Last active Jan 13, 2017
Which of these do you prefer for a component-wrapping API? please comment below!
View routing.js
// The hypothetical <Routing /> component would pass extra props to <App /> to say which route is active
// 1. Wrapped component accepts component class and passes on props plus extras
<Routing
rootComponent={App}
propForApp="abc"
propForApp2="def"
/>
// 2. Wrapped component takes children and uses cloneElement to pass extra props
@glenjamin
glenjamin / file-open.js
Created Sep 22, 2016
Open a file dialog
View file-open.js
/**
* Get a promise for a user-selected File object
*/
export function chooseLocalFile(): Promise<File> {
const input = document.createElement("input");
input.type = "file";
input.accept = "application/json";
return new Promise((resolve) => {
input.addEventListener("change", () => {
const file = input.files[0];
@glenjamin
glenjamin / records.js
Last active May 4, 2020
Flow types for immutable records.
View records.js
/* @flow */
import * as I from "immutable";
/**
* Define an immutable record intended for holding reducer state
* @param spec - the keys and their default values
* @return a state record factory function
*/
export function defineRecord<T: Object>(
@glenjamin
glenjamin / confident-ui-dev.md
Last active Jun 13, 2016
Confident UI development through better feedback
View confident-ui-dev.md

Confident UI development through better feedback

Abstract

When you make a change to user-interface code, how do you know if it does what you expect? How long do you have to wait between typing some code, hitting refresh, and then seeing the result?

There are popular tools to speed up this refresh cycle, but what about user interaction or multiple component states? Even with auto-refresh or hot code reloading you'll usually still have to click on a button to check if your animations are working correctly.

I'll show you how you can get an even better level of immediate feedback from changes. One that lets you see the variety of possible states and interactions your components have all at the same time. This can vastly improve our experiences when building interactive web applications.

@glenjamin
glenjamin / elm-native-wrapper.js
Created Jun 10, 2016
A sketch of an approach for making it slightly easier to share elm native modules.
View elm-native-wrapper.js
(function ElmNativeWrapper(name, actualNativeModule) {
var initialised = false;
window[name] = {
init: function(appname) {
// Could use Object.keys(window) here to try and detect if the name is wrong
window[munge(appname) + "$Native_" + name] = actualNativeModule();
initialised = true;
}
}
@glenjamin
glenjamin / index.js
Last active Feb 19, 2016
Get Font Styles
View index.js
var getComputedStyle = require('computed-style');
var fontStyles = ['font-family', 'font-size', 'font-weight', 'font-style'];
module.exports = function getFontStyles(domElement) {
return {
element: domElement,
styles: extractFontStyles(domElement)
}
}
@glenjamin
glenjamin / github-pages.sh
Last active Feb 7, 2016
Script that automatically rebuilds a github pages branch
View github-pages.sh
#!/bin/sh
set -e
# !!!!
echo "*** REPLACE this with the line which builds docs"
# !!!!
echo "*** Docs built ***"
tmpdir=`mktemp -d /tmp/gh-pages-build.XXXXXX`
@glenjamin
glenjamin / example.js
Created Jan 15, 2016
Record Immutable is Map
View example.js
var Immutable = require('immutable');
var FooRecord = Immutable.Record({ a: 1, b: 2 }, 'foo');
Immutable.is(new FooRecord(), new Immutable.Map({a: 1, b: 2}));
// => true
@glenjamin
glenjamin / .kitchen.yml
Created Sep 28, 2015
Systemd in a container! Useful for testing services controlled by chef
View .kitchen.yml
---
driver:
name: docker
provision_command:
- yum -y swap -- remove systemd-container systemd-container-libs -- install systemd
- systemctl enable sshd.service
- curl -L https://www.opscode.com/chef/install.sh | bash
require_chef_omnibus: false
run_command: /usr/sbin/init
privileged: true