There's a lot going on in this PR, though it's all interdependent, so the only way I can see to break it up into smaller pieces would be serially.
1. I completely refactored the functions for managing cache headers. These have been added to `services/cache-headers.js`, and in some ways set the stage for the rest of this PR.
- There are ample higher-level test of the functionality via `request-handler`. Refactoring these tests was deferred. Cache headers were previously dealt with in three places:
- `request-handler.js`, for the dynamic badges. This function now calls `setCacheHeaders`.
- `base-static.js`, for the static badges. This method now calls the wordy `serverHasBeenUpSinceResourceCached` and `setCacheHeadersForStaticResource`.
- The bitFlip badge in `server.js`. 👈 This is what set all this in motion. This badge has been refactored to a new-style service based on a new `NoncachingBaseService` which does not use the Shields in-memory cache that the dynamic badges user.
- I'm open to clearer names for `NoncachingBaseService`, which is kind of terrible. Absent alternatives, I wrote a short essay of clarification in the docstring. 😝
2. In the process of writing `NoncachingBaseService`, I discovered it takes several lines of code to instantiate and invoke a service. These would be duplicated in three or four places in production code, and in lots and lots of tests. I kept the line that goes from regex to namedParams (for reasons) and moved the rest into a static method called `invoke()`, which instantiates and invokes the service. This _replaced_ the instance method `invokeHandler`.
- I gently reworked the unit tests to use `invoke` instead of `invokeHandler`– generally for the better.
- I made a small change to `BaseStatic`. Now it invokes `handle()` async as the dynamic badges do. This way it could use `BaseService.invoke()`.
3. There was logic in `request-handler` for processing environment variables, validating them, and setting defaults. This could have been lifted whole-hog to `services/cache-headers.js`, though I didn't do that. Instead I moved it to `server-config.js`. Ideally `server-config` is the only module that should access `process.env`. This puts the defaults and config validation in one place, decouples the config schema from the entire rest of the application, and significantly simplifies our ability to test different configs, particularly on small units of code. (We were doing this well enough before in `request-handler.spec`, though it required mutating the environment, which was kludgy.) Some of the `request-handler` tests could be rewritten at a higher level, with lower-level data-driven tests directly against `cache-headers`.
This picks up @RedSparr0w's work in #1802.
1. The handler for the static badge is moved into its own service with a synchronous handler. Avoiding an async call may make the static badges slightly faster, though it may be worth profiling this if it turns out we want asynchronous static badges in the future. If it doesn't make a performance difference we could make this handler `async` like the others.
2. Most of the custom static-badge logic is in a BaseStaticBadge base class.
3. Rewrite the static Gitter badge to use BaseStaticBadge.
4. A bit of minor cleanup in related functions.
This simplifies and further optimizes text-width computation by computing the entire width table in advance, and serializing it in the style of QuickTextMeasurer (#1390). This entirely removes the need for PDFKit at runtime. This has the advantage of fixing #1305 – more generally: producing the same result everywhere – without having to deploy a copy of Verdana.
The lifting is delegated to these three libraries, which are housed in a monorepo: https://github.com/metabolize/anafanafo
I'd be happy to move it into the badges org if folks want to collaborate on maintaining them.
QuickTextMeasurer took kerning pairs into account, whereas this implementation does not. I was thinking kerning would be a necessary refinement, though this seems to work well enough.
I dropped in a binary-search package to traverse the data structure, in part to conserve space. This causes a moderate performance regression, though there is ample room for improving on that: https://github.com/badges/shields/pull/2311#issuecomment-439182704
* move gh-badges files out of /lib
As far as possible, this is just moving files
around and updating paths however there are 2
functional changes in this commit:
- remove use of lib/register-chai-plugins.spec
in badge-cli.spec.js
- remove use of starRating()
in text-measurer.spec.js
* update service tests that use colorscheme.json
* split package.json in two
* clean up import
* don't hard-code path
* start a changelog
* put a license file in the package dir
* re-organise documentation 📚
* don't pack test files
* remove favicon from Makefile
* give package its own test command
* link the docs better in README
This is consistent with what we're pretty much already doing, and saves us from making the request during code review.
These were all autofixed and most of them seem easier to read. Some in the legacy services should be rewritten in more legible forms during refactor (ie using intermediate variables, or using request’s qs option). There are some in helper functions and elsewhere that should get rewritten separately. I don't want to change them in this PR because the changes will get lost in this diff, though we could identify them here and fix them before or just after.
I had to track down the right lint rule for this. We have no-useless-rename for destructuring and import/export. The one for object literals is object-shorthand.
We use arrow functions in most places; this enforces it.
Passing arrow functions to Mocha is discouraged: https://mochajs.org/#arrow-functions
This was a mix of autofixes and hand adjustments.
* add simple-icons
* handle undefined
* support logoColor param
* our icon > simple-icon
* dont crash ✅
* return false → undefined
* update test
* add test
* support logoColor on our logos
* cache as base64, pre-load-simple-icons, logo-helper
* add ?logoColor information
* and simple-icons reference, link to github master branch for our logos
* update simple-icons
update to 1.7.1
* Revert "and simple-icons reference, link to github master branch for our logos"
This reverts commit 5e99d5f8db.
* add link to simple-icons
* Add snapshot test
* support dash in place of space for logo name
* tell browsers and downstream caches to cache for
`env.BADGE_MAX_AGE_SECONDS`, default 0 for dev
* set Cache-Control: no-cache, no-store, must-revalidate if maxAge=0
* add servertime badge to help with cache header debugging
* if service category is 'debug', exclude from examples
* ignore maxAge GET param if less than `env.BADGE_MAX_AGE_SECONDS`
Make a clear distinction between programmer errors ("internal errors") and runtime errors, and allow configuring the server to let the programmer errors bubble up in development and unit testing. This saves a huge amount of time because it generates ordinary stack traces when things go wrong. And, if these errors occur in production, we'll catch them, and display **shields | internal error** which is the equivalent of a 500 error.
This merges the `node-8` branch. The heavy lift was by @Daniel15 with refactoring from me and a patch by @RedSparr0w.
* New API for registering services (#963)
* Disable Node 6 tests on node-8 branch (#1423)
* BaseService: Factor out methods _regex and _namedParamsForMatch (#1425)
- Adjust test grouping
- Rename data -> queryParams, text -> message
* BaseService tests: Use Chai (#1450)
* BaseService: make serviceData and badgeData explicit and declarative (#1451)
* fix isValidStyle test (#1544)
* Run tests in Node 9, not Node 6 (#1543)
Ref: #1379
This takes a naive approach to font-width computation, the most compute-intensive part of rendering badges.
1. Add the widths of the individual characters.
- These widths are measured on startup using PDFKit.
2. For each character pair, add a kerning adjustment
- The difference between the width of each character pair, and the sum of the characters' separate widths.
- These are computed for each character pair on startup using PDFKit.
3. For a string with characters outside the printable ASCII character set, fall back to PDFKit.
This branch averaged 0.041 ms in `makeBadge`, compared to 0.144 ms on master, a speedup of 73%. That was on a test of 10,000 consecutive requests (using the `benchmark-performance.sh` script, now checked in).
The speedup applies to badges containing exclusively printable ASCII characters. It wouldn't be as dramatic on non-ASCII text. Though, we could add some frequently used non-ASCII characters to the cached set.
I developed this for #820 to provide the correct cache behavior when a service wants to use custom parameters from the query string.
For safety, only the declared parameters (and the global parameters) are provided to the service. Consequently, failure to declare a parameter results in the parameter not working at all (undesirable, but easy to debug) rather than indeterminate behavior that depends on the cache state (undesirable, but hard to debug).
- Add tests to request-handler to prepare for some tweaks to caching for #820
- Clean up code in request-handler: renames, DRY, arrows, imports
- Allow for clean shutdown of `setInterval` code. This requires the ability to cancel autosaving.
- Upgrade to Mocha 4, and clean up so the process exits on its own (see mochajs/mocha#3044)
- Better encapsulate analytics