If Heruku fails to build and complains about:

Compiled slug size: 500.3M is too large (max is 500M)

you may Google and find the ThoughtBot article which suggests:

# This…

Photo by Antoine Dautry on Unsplash


I have been playing with Vue recently and wonder how to write component tests for components.

If you are a Vue newbie like me, you would find the steps helpful to quickly get tests running.

My goals is to follow Vue / Jest conventions (e.g., naming test files, and test file locations), so that we start testing a new Vue project in the right way.

Context: I have an existing Vue app and want to add tests

If you are like me, I followed a bunch of Vue tutorials and used vue-cli to create a project.

Note: If the skeleton project that vue-cli created comes with the stub files and _any conventional…


Recently I have been playing with Vue (2.x) and using it to build a search bar. The UI looks a bit like this:

My goal is to render the search results in different tabs. Each tab is a different representation of the same results (tables, charts, etc.). This mandates that tabs share the same set of search results.

When users search a new keyboard in the global search bar, all tabs are updated with the new results.

To reuse the same search results, I need to store the results in a shared state, which leads me to Vuex.

To build…

Photo by Emile Perron on Unsplash


This post talks about how I implemented an accessible combobox widget, and all the hoops I jumped through.

The biggest hoop was the W3C ARIA community screws up on ARIA 1.1 combobox specs. ARIA 1.2 has a fix, but it is still in working draft.

Without knowing this, I went ahead to implement 1.1 combobox. It was costly to realize that screen readers have poor support for ARIA 1.1 comboboxes and I later had to switch to ARIA 1.2.

If you are building combobox / autocomplete like widgets and care about accessibility, this post can help you learn what’s ahead.

Many UI widgets have problems if you reason it from the angle of web accessibility.

Hover-and-expand menu is one example. Because the top level element is a link, users expect link behaviours. But we also have a submenu to fly out when users hover the mouse.

Essentially, we are mixing a link and a menu button. Because of this, it’s awkward for keyboard and screen reader (e.g., NVDA) users. Do you expect to activate a link or see a submenu when you press Enter or Space?

There are some workarounds, but we should avoid such a design in the first…

Why I write this post?

If you are fixing the accessibility (aka. a11y) issues of an existing site, and seeing a widget like below:

(Image source: https://ca.puma.com/)

Now answer this question: Which design pattern is this widget using?

Why is the question important? Because different widgets has different requirements on keyboard interactions, tag properties, states, etc.!

For example, you should be able to use the Space key to activate a dropdown if it is a menu, but there is no such key requirement for a listbox.

Another example: If a menu has submenu, your implementation should support left / right arrow keys to navigate to…


Zapier supports most activity triggers for Pivotal Tracker, but not enough types of actions. A little Python code to call Pivotal API helps me get past the limit.

Who is the post for?

Before using it, I found it hard to know the boundary of no-code tools like Zapier. You need to know what’s possible as is, and what it takes to extend the existing functionality.

This post documents our experience and the limitations. It helps you if:

  • you are new to Zapier or evaluating whether to use Zapier, and
  • your workflow involves Pivotal Tracker and you want to automate (parts of) the workflow

The use case


For a text field, we can’t allow users to enter emojis in the text because that field is later ingested in a MySQL database doesn’t have utf8mb4 support yet.

As a result, we need to add a validation rule to detect emoji and sends an error message.

I ended up using a whitelist approach based on the unicode categories:


With this, you can compose your own validation rules.

Because Salesforce REGEX formula requires escaping backslashes and other quirks, it’s tricky to compose the regex for emoji. For example, the validation file looks like:

<ValidationRule> <fullName>My_Field_Validation</fullName> <active>true</active> <description>My_Field validation rule</description>…

Source: undraw.co

Default to current timestamp (It works in Postgres and MySQL)

create table t (
id int,
created_at timestamp default current_timestamp
insert into t(id) values(1);


select * from t; id |         created_at         
1 | 2020-05-18 23:28:27.121457
(1 row)

Postgres specific syntax

create table t (
id int,
created_at timestamp default now()

This is because Postgres supports both function or constant as default values. So both now() and current_timestamp are legit values. But MySQL doesn’t.

Auto increment


Postgres has a speical type serial for this purpose:

create table t (
id serial,
created_at timestamp default now()


MySQL requires auto_increment to be a key:

create table t( id int auto_increment, created_at timestamp default…

If you were like me, I was constantly confused by LEFT / RIGHT / INNER / OUTER JOINs in SQL. The Internet even has this hilarious meme:

A front end developer eats alone because he doesn’t know how to join tables

I found the best visual from StackOverflow:

Image source: StackOverflow

My Notes

To help my tiny working memory, I like to summarize things in FAQ style notes.

Note: Below are short explanations only. If you want concrete examples, StackOverflow has plenty.


They are the same thing. JOIN is shorthand for INNER JOIN.


They are the same thing. …

Junji Zhi

Senior Software Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store