Category Archives: davidwalsh

Recursive Array.flat

There was much talk about Array.prototype.flat during its early stages, starting with the name alone. Many developers preferred the name flatten but the spec differed from MooTools’ implementation. MooTools would recursively flatten an array but the new, official flat implementation defaults one level of flattening,.

The current implementation of Array.prototype.flat is:

[1, 2, [3], [[4]]].flat(/* depth */);
// [1,2,3,[4]]

.flat only flattens arrays to one level by default, but what if you want a truly flattened array? You can use Infinity and flat‘s depth argument to make that happen:

read more

Using Array reduce

Every developer who specializes in any programming language will tell you there’s a powerful tool the language provides that they rarely use and wish they knew more about. For me, it’s Array.prototype.reduce. I quite enjoy the other Array methods like map, filter, and find, but reduce is one that I knew was powerful but never really had much use for.

It wasn’t until I was refactoring some of the Firefox DevTools Debugger code that I found a great use case for reduce — one I plan on using in the future.

Methods like forEach and map were created to avoid side effects, and reduce is no exception. In this case, however, reduce can return an Object other than an Array. Take this case for example:

// Samples sources
const sources = [
  {
    id: "server1.conn13.child1/39",
    url: "https://davidwalsh.name/"
  },
  {
    id: "server1.conn13.child1/37",
    url: "https://davidwalsh.name/util.js"
  }
];

// Return an object of sources with the keys being "id"
const sourcesMap = sources.reduce((map, source) => {
  map[source.id] = source
  return map;
}, {});

In the example above, we take an array of Source objects and return a single object literal with each Source‘s id as the key:

{
  "server1.conn13.child1/39": {
    "id": "server1.conn13.child1/39",
    "url": "https://davidwalsh.name/"
  },
  "server1.conn13.child1/37": {
    "id": "server1.conn13.child1/37",
    "url": "https://davidwalsh.name/util.js"
  }
}

read more

How to Patch Retry System into Super Mario ROMs

I find myself watching less TV lately and much more time enjoying gamers stream on Twitch. While I too much PUBG, and enjoy watching people like Shroud and ChocoTaco hit bangers, I get more enjoyment out of Grand Poo Bear, Barbarian, and others play ultra difficult Super Mario World ROM hacks.

I’ve written about how to patch ROM hacks to play the games, but I wanted to look at how ROM hack creators add features to their hack, like the super useful Retry system:

SMW Retry System

If you are creating a super difficult ROM hack, you want the player, who’s probably already suffering, to quickly be able to retry without needing to go to the level select screen each time. Let’s have a look at how you can add the features to your own ROM hacks!

read more

Awesome Visual Testing with Percy! (Sponsored)

The more complex the applications I work on, the more I rely on and invest in testing. Whether it’s flow typing, jest tests, unit tests, or selenium tests, I rely on all of them to enforce integrity and save me from myself.

One type of testing that’s incredibly important but often overlooked is visual testing. Functional testing is incredibly important but the truth is that users expect things to work but the first thing they’ll notice is things that look broken. Oftentimes your selenium and unit tests will pass despite a hideous visual regression. That’s where a service like Percy comes in — Percy makes visual regression testing easy!

Quick Hits

  • Functionality blemishes can be hidden — UI blemishes stick out
  • Most unit tests don’t detect visual regressions
  • Most web shops don’t have the resources or timeline to hire QA
  • Higher quality than current open source utilities
  • Integrates with CIs (Travis, Circle, etc.) and GitHub so you can catch problems before code is merged
  • It’s free to start!

Getting Started

After free sign up, Percy provides a sample app to show you how things work. Percy works off of a system of snapshots, comparing a desired/known snapshot with snapshots automated by CI or locally created snapshots.

There are a number of SDKs to work with:

You could also use Percy’s own PercyScript, an SDK for creating snapshots!

To use PercyScript, add Percy to your project using NPM:

$ npm install -D @percy/script

Next it’s time to create your first PercyScript to automate some actions and take a snapshot of the result:

// snapshots.js
const PercyScript = require('@percy/script');

// A script to navigate our app and take snapshots with Percy.
PercyScript.run(async (page, percySnapshot) => {
  await page.goto('http://localhost:8000');
  await percySnapshot('TodoMVC home page');

  // Enter a new to-do.
  await page.type('.new-todo', 'A really important todo');
  await page.keyboard.press('Enter');
  await percySnapshot('TodoMVC with a new todo', { widths: [768, 992, 1200] });
});

Since we live in a responsive design world, Percy takes snapshots at specified widths to ensure your desktop, tablet, and smart phone designs don’t regress. Next up you can run your script:

$ npx percy exec -- node snapshots.js
[percy] created build #1: https://percy.io/test/example-todomvc/builds/1738842
[percy] percy has started.
[percy] snapshot taken: 'TodoMVC home page'
[percy] snapshot taken: 'TodoMVC with a new todo'
[percy] stopping percy...
[percy] waiting for 2 snapshots to complete...
[percy] done.
[percy] finalized build #1: https://percy.io/test/example-todomvc/builds/1738842

read more