Extremely excited to check out the new Stacked Pull Requests feature of Tower 12! I have been manually managing a lot of stacked branches lately, and the ability to keep them updated automatically is going to save me so much time πŸ™Œ 😭 www.git-tower.com/features/…

Not a bad grouping for my first round of the season! #Archery

An archery target with 6 arrows in it, all of which hit the center-most β€œyellow” section of the target

Does your engineering team have a person or group of people that are responsible for the quality of the codebase itself – the build tools, tests, infrastructure, sharing patterns, etc? If so, what do you refer to those folks as?

True love is when your wife gets the terrible version of “Stand By Your Man” from GoldenEye stuck in your head but you forgive them anyway www.youtube.com/watch

The only good push notification #BirdBuddy

A screenshot of a push notification from BirdBuddy, an app that provides pictures of birds at your bird feeder. The notification is alerting me that a bird has stopped by for a snack!

If Apple was smart, they’d bring Balatro to iOS through Apple Arcade. This game has a ton of potential on mobile, and Apple has a chance to grab a winner before it launches

Testing ESLint Rules with Vitest

I recently needed to write a custom lint rule for a project that uses Vitest to run its tests. ESLint provides great tools for testing custom rules through the RuleTester class, but using it directly would mean that this project needed two different test runners to be run all of the tests. This got me thinking: is there a way to run the tests for the lint rule using Vitest?

Read More

Setting a Request ID in SvelteKit

I have been working on a full-stack application in SvelteKit recently. As the complexity of the application grew, it started getting harder to understand what was happening during each page render. I knew I needed something to help track down what was happening in my application during each request. The solution to my problem was a familiar one: request IDs!

Read More

Writing a local @types Package

I recently worked on a Node.js project in TypeScript that made use of my usual suite of tools: ava with ts-node for testing eslint for linting Good ol’ tsc to compile my TypeScript files into JavaScript This all worked great when there was little-to-no tsconfig.json customization present, but I ran into a situation that caused me some trouble. A third-party package with an npm scope (meaning the name looks something like @organization/package-name) did not come with type definitions, nor were they available from Definitely Typed.

Read More

Print GitHub CLI Pull Requests Without Paging

I am a big fan of the GitHub Command Line tool, gh. In particular, it’s a great way to list the pull-requests for a repository and then check one out locally for review. By default, this workflow is a little tricky. When you list your PRs you get a list that is passed automatically through your $PAGER program (probably less). By default, regardless of how much content there is, you have to actively dismiss less to go back to the command line.

Read More

Managing Specificity with CSS Variables

A recent project at work had me defining some shared button styles for us to use in conjunction with Tailwind CSS. The styling is much like you might expect; a base button class with some specific “types” of buttons in different styles. For the purpose of illustration, imagine something like this: .button { color: black; } .button.type-plain { color: blue; } To render a “plain” button, you use the classes together on an element:

Read More

Replace an Unused Dependency

I recently ran into a bit of an odd situation regarding a problematic npm dependency. Our app depended on an old version of d3, which had a dependency on an old version of jsdom, which itself depended on contextify. contextify is not supported on modern versions of Node and would fail to install. Upgrading d3 to a modern version without the dependency on jsdom was too hard, but we needed some way to move forward.

Read More

Verifying Changes

Recently, Movable Ink, the company where I work, released our configuration for Tailwind as an open-source project. While it’s only being used internally, making it Open Source has been a motivating factor to keep the code clean and be thoughtful about how we’re maintaining it. Using GitHub Actions has been key in helping us achieve that goal. In this series of posts, I’ll be covering all the ways we’re putting GitHub Actions to work for us.

Read More

Converging on a Condition in QUnit

While writing some acceptance tests recently I kept running into slight race conditions between the state my application and an assertion I wanted to make. For example, one of the tests looked something like this: test("creating a comment", async function (assert) { assert.equal(Task.comments.messages.length, 5, "Starts with correct number of comments"); await Task.comments.input.fillIn("A new comment"); await Task.comments.send(); assert.equal(Task.comments.message.length, 6, "Adds a new comment"); }); How does the test know that the right number of messages should be visible at the point that send() resolves?

Read More

Observables: A Brief Introduction

Lately I’ve been thinking a lot about “pull” and “push” with regard to the way functions interact with each other. Imagine two functions, a and b, where a depends on receiving a value from b. The value is pulled if a determines when the value is delivered; it is pushed if b determines the timing. Combined with the ability to produce either one or more than one value, you get a total of four possible categories:

Read More

Generate an Ember app with the Module Unification layout

Today at EmberConf, Matthew Beale spoke about the new Module Unification directory layout that will be coming to Ember in the near future. If you want to try it out now, you can install the canary version of the Ember CLI and generate a new application. Thanks to npx, you can do this with a single command: MODULE_UNIFICATION=true npx ember-cli/ember-cli new __name_of_app__ This avoids needing to globally install the canary version of the Ember CLI but still gives you access to the bleeding-edge features.

Read More

Generate Integration test data with Mirage

If you have an Ember component that requires an Ember Data model as an attribute, you might want to use Mirage to generate the models in the right shape. Thankfully, you can access Ember Data in your test to generate the data, then pass that into the component to test it. import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; import setupMirage from 'my-app/tests/helpers/setup-mirage'; import { find, render } from '@ember/test-helpers'; import { run } from '@ember/runloop'; module('Integration | Components | render-post', function(hooks) { setupRenderingTest(hooks); setupMirage(hooks); hooks.

Read More

Upgrading an Ember app to the new QUnit API

I recently upgraded a large Ember app to the new API and ran into a few problems along the way. Here’s a few tips for making your transition smoother than mine was. Update your dependencies To start off, update to the latest ember-cli-qunit yarn ember install ember-cli-qunit Additionally, ember-test-helpers can be removed from your dependencies if you have it listed there, since ember-cli-qunit will bring in ember-qunit, which in turn will bring in the new version of that package, @ember/test-helpers.

Read More

Checking Differences Between Commits in Github

Changes are you use some dependencies that have their source code hosted on Github. It’s useful to be able to check the differences between two commits to see what has changed, especially when determining what breaking changes there might be between two releases. git of course has this functionality, but accessing it through the Github UI is much more convenient. I couldn’t find a nice way to access this feature, though, so I started to do a little digging.

Read More

Maintaining aspect ratio in CSS

I had to use a bit of a hack this week to ensure that a box always appeared at a 1:1 aspect ratio. Basically, by doing something like: .box { width: 100%; padding-top: 100%; } You can force something to display with the same height and width, since the padding percentage is relative to the width. However, this is not true of flex children, which this box happened to be. Chrome rendered just fine, but FireFox had different behavior, as documented here (the FireFox behavior might actually be more correct, I have no idea).

Read More