diff --git a/doc/TUTORIAL.md b/doc/TUTORIAL.md index 440e3ab160b1b..ad7935e8e8ff4 100644 --- a/doc/TUTORIAL.md +++ b/doc/TUTORIAL.md @@ -2,7 +2,7 @@ Tutorial on how to add a badge for a service ============================================ This tutorial should help you add a service to shields.io in form of a badge. -You will need to learn to use JavaScript, git and Github. +You will need to learn to use JavaScript, Git and GitHub. Please [improve the tutorial](https://github.com/badges/shields/edit/master/doc/TUTORIAL.md) while you read it. (1) Reading @@ -71,11 +71,11 @@ Each service has a directory for its files: Sometimes, code for a service can be re-used. This might be the case when you add a badge for an API which is already used by other badges. - + Imagine a service that lives at https://img.shields.io/example/some-param-here.svg. * For services with a single badge, the badge code will generally be stored in - `/services/example/example.service.js`. + `/services/example/example.service.js`. If you add a badge for a new API, create a new directory. Example: [wercker](https://github.com/badges/shields/tree/master/services/wercker) @@ -218,11 +218,11 @@ Description of the code: * [licenses.js](https://github.com/badges/shields/blob/master/lib/licenses.js) * [text-formatters.js](https://github.com/badges/shields/blob/master/lib/text-formatters.js) * [version.js](https://github.com/badges/shields/blob/master/lib/version.js) -4. We perform input validation by defining a schema which we expect the JSON we receive to conform to. This is done using [Joi](https://github.com/hapijs/joi). Defining a schema means we can ensure the JSON we receive meets our expectations and throw an error if we receive unexpected input without having to explicitly code validation checks. The schema also acts as a filter on the JSON object. Any properties we're going to reference need to be validated, otherwise they will be filtered out. In this case our schema declares that we expect to recieve an object which must have a property called 'status', which is a string. +4. We perform input validation by defining a schema which we expect the JSON we receive to conform to. This is done using [Joi](https://github.com/hapijs/joi). Defining a schema means we can ensure the JSON we receive meets our expectations and throw an error if we receive unexpected input without having to explicitly code validation checks. The schema also acts as a filter on the JSON object. Any properties we're going to reference need to be validated, otherwise they will be filtered out. In this case our schema declares that we expect to receive an object which must have a property called 'status', which is a string. 5. Our module exports a class which extends `BaseJsonService` 6. As with our previous badge, we need to declare a route. This time we will capture a variable called `gem`. 7. We can use `defaultBadgeData()` to set a default `color`, `logo` and/or `label`. If `handle()` doesn't return any of these keys, we'll use the default. Instead of explicitly setting the label text when we return a badge object, we'll use `defaultBadgeData()` here to define it declaratively. -8. Our bage must implement the `async handle()` function. Because our URL pattern captures a variable called `gem`, our function signature is `async handle({ gem })`. We usually separate the process of generating a badge into 2 stages or concerns: fetch and render. The `fetch()` function is responsible for calling an API endpoint to get data. The `render()` function formats the data for display. In a case where there is a lot of calculation or intermediate steps, this pattern may be thought of as fetch, transform, render and it might be necessary to define some helper functions to assist with the 'transform' step. +8. Our badge must implement the `async handle()` function. Because our URL pattern captures a variable called `gem`, our function signature is `async handle({ gem })`. We usually separate the process of generating a badge into 2 stages or concerns: fetch and render. The `fetch()` function is responsible for calling an API endpoint to get data. The `render()` function formats the data for display. In a case where there is a lot of calculation or intermediate steps, this pattern may be thought of as fetch, transform, render and it might be necessary to define some helper functions to assist with the 'transform' step. 9. The `async fetch()` method is responsible for calling an API endpoint to get data. Extending `BaseJsonService` gives us the helper function `_requestJson()`. Note here that we pass the schema we defined in step 4 as an argument. `_requestJson()` will deal with validating the response against the schema and throwing an error if necessary. * `_requestJson()` automatically adds an Accept header, checks the status code, parses the response as JSON, and returns the parsed response. * `_requestJson()` uses [request](https://github.com/request/request) to perform the HTTP request. Options can be passed to request, including method, query string, and headers. If headers are provided they will override the ones automatically set by `_requestJson()`. There is no need to specify json, as the JSON parsing is handled by `_requestJson()`. See the `request` docs for [supported options](https://github.com/request/request#requestoptions-callback). @@ -297,7 +297,7 @@ If you update `examples`, you don't have to restart the server. Run `npm run defs` in another terminal window and the frontend will update. ### (4.5) Write Tests -[write tests]: #45-write-tests +[write tests]: #45-write-tests When creating a badge for a new service or changing a badge's behavior, tests should be included. They serve several purposes: diff --git a/doc/service-tests.md b/doc/service-tests.md index 8d211b83eea0b..d32d2c7e10f63 100644 --- a/doc/service-tests.md +++ b/doc/service-tests.md @@ -65,7 +65,7 @@ t.create('Build status') Here's a [longer example][] and the complete [API guide][icedfrisby api]. 2. We use the `get()` method to request a badge. There are several points to consider here: - We need a real project to test against. In this case we have used [wercker/go-wercker-api](https://app.wercker.com/wercker/go-wercker-api/runs) but we could have chosen any stable project. - - Note that when we call our badge, we are allowing it to communicate with an external service without mocking the reponse. We write tests which interact with external services, which is unusual practice in unit testing. We do this because one of the purposes of service tests is to notify us if a badge has broken due to an upstream API change. For this reason it is important for at least one test to call the live API without mocking the interaction. + - Note that when we call our badge, we are allowing it to communicate with an external service without mocking the response. We write tests which interact with external services, which is unusual practice in unit testing. We do this because one of the purposes of service tests is to notify us if a badge has broken due to an upstream API change. For this reason it is important for at least one test to call the live API without mocking the interaction. - All badges on shields can be requested in a number of formats. As well as calling https://img.shields.io/wercker/build/wercker/go-wercker-api.svg to generate ![](https://img.shields.io/wercker/build/wercker/go-wercker-api.svg) we can also call https://img.shields.io/wercker/build/wercker/go-wercker-api.json to request the same content as JSON. When writing service tests, we request the badge in JSON format so it is easier to make assertions about the content. - We don't need to explicitly call `/wercker/build/wercker/go-wercker-api.json` here, only `/build/wercker/go-wercker-api.json`. When we create a tester object with `createServiceTester()` the URL base defined in our service class (in this case `/wercker`) is used as the base URL for any requests made by the tester object. 3. `expectJSONTypes()` is an IcedFrisby method which accepts a [Joi][] schema. diff --git a/lib/sys/prometheus-metrics.js b/lib/sys/prometheus-metrics.js index 1892f81e87b3f..1ea92427122f8 100644 --- a/lib/sys/prometheus-metrics.js +++ b/lib/sys/prometheus-metrics.js @@ -11,7 +11,7 @@ class PrometheusMetrics { : matchNothing if (this.enabled) { console.log( - `Metrics are enabled. Access to /metrics resoure is limited to IP addresses matching: ${ + `Metrics are enabled. Access to /metrics resource is limited to IP addresses matching: ${ this.allowedIps }` ) diff --git a/services/base-non-memory-caching.js b/services/base-non-memory-caching.js index 225983a2fb051..3a387877bd02f 100644 --- a/services/base-non-memory-caching.js +++ b/services/base-non-memory-caching.js @@ -13,7 +13,7 @@ const { setCacheHeaders } = require('./cache-headers') // triggers another call to the handler. When using badges for server // diagnostics, that's useful! // -// In constrast, The `handle()` function of most other `BaseService` +// In contrast, The `handle()` function of most other `BaseService` // subclasses is wrapped in onboard, in-memory caching. See `lib /request- // handler.js` and `BaseService.prototype.register()`. // diff --git a/services/bower/bower.tester.js b/services/bower/bower.tester.js index 079d2f9ee28d1..c67e2e84ae1c9 100644 --- a/services/bower/bower.tester.js +++ b/services/bower/bower.tester.js @@ -63,15 +63,15 @@ t.create('custom label for pre version') // e.g. pre version|v0.2.5-alpha-rc-pre }) ) -t.create('Version for Invaild Package') +t.create('Version for Invalid Package') .get('/v/it-is-a-invalid-package-should-error.json') .expectJSON({ name: 'bower', value: 'not found' }) -t.create('Pre Version for Invaild Package') +t.create('Pre Version for Invalid Package') .get('/vpre/it-is-a-invalid-package-should-error.json') .expectJSON({ name: 'bower', value: 'not found' }) -t.create('licence for Invaild Package') +t.create('licence for Invalid Package') .get('/l/it-is-a-invalid-package-should-error.json') .expectJSON({ name: 'license', value: 'not found' }) diff --git a/services/dynamic/dynamic-json.tester.js b/services/dynamic/dynamic-json.tester.js index 062576395314f..93fb7835f7436 100644 --- a/services/dynamic/dynamic-json.tester.js +++ b/services/dynamic/dynamic-json.tester.js @@ -55,7 +55,7 @@ t.create('JSON from url') colorB: colorsB.blue, }) -t.create('JSON from uri (support uri query paramater)') +t.create('JSON from uri (support uri query parameter)') .get( '.json?uri=https://github.com/badges/shields/raw/master/package.json&query=$.name&style=_shields_test' ) diff --git a/services/dynamic/dynamic-xml.tester.js b/services/dynamic/dynamic-xml.tester.js index 39208abe083dd..2690931b1a3ec 100644 --- a/services/dynamic/dynamic-xml.tester.js +++ b/services/dynamic/dynamic-xml.tester.js @@ -35,7 +35,7 @@ t.create('XML from url') colorB: colorsB.blue, }) -t.create('XML from uri (support uri query paramater)') +t.create('XML from uri (support uri query parameter)') .get( '.json?uri=https://services.addons.mozilla.org/en-US/firefox/api/1.5/addon/707078&query=/addon/name&style=_shields_test' ) diff --git a/services/dynamic/dynamic-yaml.tester.js b/services/dynamic/dynamic-yaml.tester.js index c471d1c2044d3..08aaa0b9ff947 100644 --- a/services/dynamic/dynamic-yaml.tester.js +++ b/services/dynamic/dynamic-yaml.tester.js @@ -32,7 +32,7 @@ t.create('YAML from url') colorB: colorsB.blue, }) -t.create('YAML from uri (support uri query paramater)') +t.create('YAML from uri (support uri query parameter)') .get( '.json?uri=https://raw.githubusercontent.com/kubernetes/charts/568291d6e476c39ca8322c30c3f601d0383d4760/stable/coredns/Chart.yaml&query=$.name&style=_shields_test' ) diff --git a/services/github/github-pull-request-check-state.tester.js b/services/github/github-pull-request-check-state.tester.js index dab1e4b5905aa..6e75e065e67e6 100644 --- a/services/github/github-pull-request-check-state.tester.js +++ b/services/github/github-pull-request-check-state.tester.js @@ -11,7 +11,7 @@ t.create('github pull request check state (pull request not found)') .expectJSON({ name: 'checks', value: 'pull request or repo not found' }) t.create( - "github pull request check state (ref returned by github doens't exist" + "github pull request check state (ref returned by github doesn't exist" ) .get('/s/pulls/badges/shields/1110.json') .intercept( diff --git a/services/jenkins/jenkins-plugin-installs.tester.js b/services/jenkins/jenkins-plugin-installs.tester.js index d0f7a45ee1ee9..d03d12ca8b5ca 100644 --- a/services/jenkins/jenkins-plugin-installs.tester.js +++ b/services/jenkins/jenkins-plugin-installs.tester.js @@ -63,7 +63,7 @@ t.create('version installs | valid: numeric version') }) ) -t.create('version installs | valid: alpha-numeric version') +t.create('version installs | valid: alphanumeric version') .get('/view-job-filters/1.27-DRE1.00.json') .expectJSONTypes( Joi.object().keys({ diff --git a/services/luarocks/luarocks-version.js b/services/luarocks/luarocks-version.js index 70df1ad2aca0c..6290a6a8cd322 100644 --- a/services/luarocks/luarocks-version.js +++ b/services/luarocks/luarocks-version.js @@ -5,7 +5,7 @@ */ 'use strict' -// Compare two arrays containing splitted and transformed to +// Compare two arrays containing split and transformed to // positive/negative numbers parts of version strings, // respecting negative/missing values: // [1, 2, 1] > [1, 2], but [1, 2, -1] < [1, 2] ([1, 2] is aligned to [1, 2, 0]) diff --git a/services/pypi/pypi.tester.js b/services/pypi/pypi.tester.js index efbb47e2e4e60..ab204015eec61 100644 --- a/services/pypi/pypi.tester.js +++ b/services/pypi/pypi.tester.js @@ -57,7 +57,7 @@ t.create('monthly downloads (not found)') - 0.1.30b10 are perfectly legal. - We'll run this test againt a project that follows SemVer... + We'll run this test against a project that follows SemVer... */ t.create('version (semver)') .get('/v/requests.json') diff --git a/services/vaadin-directory/vaadin-directory.tester.js b/services/vaadin-directory/vaadin-directory.tester.js index b9a44eed2e754..8603cf31b2156 100644 --- a/services/vaadin-directory/vaadin-directory.tester.js +++ b/services/vaadin-directory/vaadin-directory.tester.js @@ -50,7 +50,7 @@ t.create('publish status of the component') }) ) -t.create('rating of the compoennt (eg: 4.2/5)') +t.create('rating of the component (eg: 4.2/5)') .get('/rating/vaadinvaadin-grid.json') .expectJSONTypes( Joi.object().keys({ diff --git a/services/vscode-marketplace/vscode-marketplace.service.js b/services/vscode-marketplace/vscode-marketplace.service.js index 07a8d6400bc20..da18bf2d8119f 100644 --- a/services/vscode-marketplace/vscode-marketplace.service.js +++ b/services/vscode-marketplace/vscode-marketplace.service.js @@ -44,7 +44,7 @@ function getVscodeApiReqOptions(packageName) { } } -//To extract Statistics (Install/Rating/RatingCount) from respose object for vscode marketplace +//To extract Statistics (Install/Rating/RatingCount) from response object for vscode marketplace function getVscodeStatistic(data, statisticName) { const statistics = data.results[0].extensions[0].statistics try { diff --git a/services/waffle/waffle.tester.js b/services/waffle/waffle.tester.js index 567a1224dd78c..28441870f9777 100644 --- a/services/waffle/waffle.tester.js +++ b/services/waffle/waffle.tester.js @@ -44,7 +44,7 @@ t.create( colorB: '#fbca04', }) -t.create('label should be `Mybug` & value should be formated. e.g: Mybug|25') +t.create('label should be `Mybug` & value should be formatted. e.g: Mybug|25') .get('/ritwickdey/vscode-live-server/bug.json?label=Mybug') .expectJSONTypes( Joi.object().keys({