diff --git a/docs/schema.md b/docs/schema.md
index 886de8c..0ee2f32 100644
--- a/docs/schema.md
+++ b/docs/schema.md
@@ -394,12 +394,12 @@ type BrowseQuery {
# The MBID of a collection in which the entity is found.
collection: MBID
- # The MBID of a release to which the entity is linked.
- release: MBID
-
# The [International Standard Recording Code](https://musicbrainz.org/doc/ISRC)
# (ISRC) of the recording.
isrc: ISRC
+
+ # The MBID of a release to which the entity is linked.
+ release: MBID
after: String
first: Int
): RecordingConnection
@@ -415,9 +415,19 @@ type BrowseQuery {
# The MBID of a collection in which the entity is found.
collection: MBID
+ # A [disc ID](https://musicbrainz.org/doc/Disc_ID)
+ # associated with the release.
+ discID: DiscID
+
# The MBID of a label to which the entity is linked.
label: MBID
+ # The MBID of a recording to which the entity is linked.
+ recording: MBID
+
+ # The MBID of a release group to which the entity is linked.
+ releaseGroup: MBID
+
# The MBID of a track that is included in the release.
track: MBID
@@ -425,21 +435,11 @@ type BrowseQuery {
# release, but is not included in the credits for the release itself.
trackArtist: MBID
- # The MBID of a recording to which the entity is linked.
- recording: MBID
-
- # The MBID of a release group to which the entity is linked.
- releaseGroup: MBID
-
# Filter by one or more release group types.
type: [ReleaseGroupType]
# Filter by one or more release statuses.
status: [ReleaseStatus]
-
- # A [disc ID](https://musicbrainz.org/doc/Disc_ID)
- # associated with the release.
- discID: DiscID
after: String
first: Int
): ReleaseConnection
@@ -502,28 +502,28 @@ type Collection implements Node, Entity {
# field.
typeID: MBID
- # A list of areas linked to this entity.
+ # The list of areas found in this collection.
areas(after: String, first: Int): AreaConnection
- # A list of artists linked to this entity.
+ # The list of artists found in this collection.
artists(after: String, first: Int): ArtistConnection
- # A list of events linked to this entity.
+ # The list of events found in this collection.
events(after: String, first: Int): EventConnection
- # A list of instruments linked to this entity.
+ # The list of instruments found in this collection.
instruments(after: String, first: Int): InstrumentConnection
- # A list of labels linked to this entity.
+ # The list of labels found in this collection.
labels(after: String, first: Int): LabelConnection
- # A list of places linked to this entity.
+ # The list of places found in this collection.
places(after: String, first: Int): PlaceConnection
- # A list of recordings linked to this entity.
+ # The list of recordings found in this collection.
recordings(after: String, first: Int): RecordingConnection
- # A list of releases linked to this entity.
+ # The list of releases found in this collection.
releases(
# Filter by one or more release group types.
type: [ReleaseGroupType]
@@ -534,7 +534,7 @@ type Collection implements Node, Entity {
first: Int
): ReleaseConnection
- # A list of release groups linked to this entity.
+ # The list of release groups found in this collection.
releaseGroups(
# Filter by one or more release group types.
type: [ReleaseGroupType]
@@ -542,10 +542,10 @@ type Collection implements Node, Entity {
first: Int
): ReleaseGroupConnection
- # A list of series linked to this entity.
+ # The list of series found in this collection.
series(after: String, first: Int): SeriesConnection
- # A list of works linked to this entity.
+ # The list of works found in this collection.
works(after: String, first: Int): WorkConnection
}
@@ -1688,8 +1688,8 @@ type ReleaseEdge {
score: Int
}
-# Date on which a release was issued in a country/region with a
-# particular label, catalog number, barcode, and what release format was used.
+# The date on which a release was issued in a country/region with
+# a particular label, catalog number, barcode, and format.
type ReleaseEvent {
area: Area
date: Date
diff --git a/docs/types.md b/docs/types.md
index 6d8c6d8..0d542f5 100644
--- a/docs/types.md
+++ b/docs/types.md
@@ -1127,17 +1127,17 @@ entity.
MBID |
The MBID of a collection in which the entity is found. |
-
- | release |
- MBID |
- The MBID of a release to which the entity is linked. |
-
| isrc |
ISRC |
The International Standard Recording Code
(ISRC) of the recording. |
+
+ | release |
+ MBID |
+ The MBID of a release to which the entity is linked. |
+
| after |
String |
@@ -1170,11 +1170,27 @@ entity.
MBID |
The MBID of a collection in which the entity is found. |
+
+ | discID |
+ DiscID |
+ A disc ID
+associated with the release. |
+
| label |
MBID |
The MBID of a label to which the entity is linked. |
+
+ | recording |
+ MBID |
+ The MBID of a recording to which the entity is linked. |
+
+
+ | releaseGroup |
+ MBID |
+ The MBID of a release group to which the entity is linked. |
+
| track |
MBID |
@@ -1186,16 +1202,6 @@ entity.
The MBID of an artist that appears on a track in the
release, but is not included in the credits for the release itself. |
-
- | recording |
- MBID |
- The MBID of a recording to which the entity is linked. |
-
-
- | releaseGroup |
- MBID |
- The MBID of a release group to which the entity is linked. |
-
| type |
[ReleaseGroupType] |
@@ -1206,12 +1212,6 @@ release, but is not included in the credits for the release itself.
[ReleaseStatus] |
Filter by one or more release statuses. |
-
- | discID |
- DiscID |
- A disc ID
-associated with the release. |
-
| after |
String |
@@ -1360,7 +1360,7 @@ field.
areas |
AreaConnection |
- A list of areas linked to this entity.
+ The list of areas found in this collection.
|
@@ -1377,7 +1377,7 @@ field.
| artists |
ArtistConnection |
- A list of artists linked to this entity.
+ The list of artists found in this collection.
|
@@ -1394,7 +1394,7 @@ field.
| events |
EventConnection |
- A list of events linked to this entity.
+ The list of events found in this collection.
|
@@ -1411,7 +1411,7 @@ field.
| instruments |
InstrumentConnection |
- A list of instruments linked to this entity.
+ The list of instruments found in this collection.
|
@@ -1428,7 +1428,7 @@ field.
| labels |
LabelConnection |
- A list of labels linked to this entity.
+ The list of labels found in this collection.
|
@@ -1445,7 +1445,7 @@ field.
| places |
PlaceConnection |
- A list of places linked to this entity.
+ The list of places found in this collection.
|
@@ -1462,7 +1462,7 @@ field.
| recordings |
RecordingConnection |
- A list of recordings linked to this entity.
+ The list of recordings found in this collection.
|
@@ -1479,7 +1479,7 @@ field.
| releases |
ReleaseConnection |
- A list of releases linked to this entity.
+ The list of releases found in this collection.
|
@@ -1506,7 +1506,7 @@ field.
| releaseGroups |
ReleaseGroupConnection |
- A list of release groups linked to this entity.
+ The list of release groups found in this collection.
|
@@ -1528,7 +1528,7 @@ field.
| series |
SeriesConnection |
- A list of series linked to this entity.
+ The list of series found in this collection.
|
@@ -1545,7 +1545,7 @@ field.
| works |
WorkConnection |
- A list of works linked to this entity.
+ The list of works found in this collection.
|
@@ -4274,8 +4274,8 @@ these results were found through a search.
### ReleaseEvent
-Date on which a release was issued in a country/region with a
-particular label, catalog number, barcode, and what release format was used.
+The date on which a release was issued in a country/region with
+a particular label, catalog number, barcode, and format.
diff --git a/package.json b/package.json
index 03208d2..a98abcf 100644
--- a/package.json
+++ b/package.json
@@ -39,10 +39,6 @@
"test:watch": "npm run test:only -- --watch",
"update-schema": "npm run -s print-schema:json > schema.json"
},
- "pre-commit": [
- "build:docs",
- "lint"
- ],
"keywords": [
"musicbrainz",
"graphql",
@@ -67,7 +63,7 @@
"compression": "^1.6.2",
"dashify": "^0.2.2",
"dataloader": "^1.2.0",
- "debug": "^2.3.3",
+ "debug": "^2.4.3",
"dotenv": "^2.0.0",
"es6-error": "^4.0.0",
"express": "^4.14.0",
@@ -78,7 +74,7 @@
"pascalcase": "^0.1.1",
"qs": "^6.3.0",
"request": "^2.79.0",
- "retry": "^0.10.0"
+ "retry": "^0.10.1"
},
"devDependencies": {
"ava": "^0.17.0",
@@ -95,9 +91,9 @@
"marked": "^0.3.6",
"nodemon": "^1.11.0",
"nyc": "^10.0.0",
- "pre-commit": "^1.2.1",
"rimraf": "^2.5.4",
"sepia": "^2.0.2",
+ "sinon": "^1.17.6",
"snazzy": "^5.0.0",
"standard": "^8.6.0"
},
diff --git a/schema.json b/schema.json
index 4e4da69..ad75d46 100644
--- a/schema.json
+++ b/schema.json
@@ -3227,7 +3227,7 @@
{
"kind": "OBJECT",
"name": "ReleaseEvent",
- "description": "Date on which a release was issued in a country/region with a\nparticular label, catalog number, barcode, and what release format was used.",
+ "description": "The date on which a release was issued in a country/region with\na particular label, catalog number, barcode, and format.",
"fields": [
{
"name": "area",
@@ -5432,7 +5432,7 @@
},
{
"name": "areas",
- "description": "A list of areas linked to this entity.",
+ "description": "The list of areas found in this collection.",
"args": [
{
"name": "after",
@@ -5465,7 +5465,7 @@
},
{
"name": "artists",
- "description": "A list of artists linked to this entity.",
+ "description": "The list of artists found in this collection.",
"args": [
{
"name": "after",
@@ -5498,7 +5498,7 @@
},
{
"name": "events",
- "description": "A list of events linked to this entity.",
+ "description": "The list of events found in this collection.",
"args": [
{
"name": "after",
@@ -5531,7 +5531,7 @@
},
{
"name": "instruments",
- "description": "A list of instruments linked to this entity.",
+ "description": "The list of instruments found in this collection.",
"args": [
{
"name": "after",
@@ -5564,7 +5564,7 @@
},
{
"name": "labels",
- "description": "A list of labels linked to this entity.",
+ "description": "The list of labels found in this collection.",
"args": [
{
"name": "after",
@@ -5597,7 +5597,7 @@
},
{
"name": "places",
- "description": "A list of places linked to this entity.",
+ "description": "The list of places found in this collection.",
"args": [
{
"name": "after",
@@ -5630,7 +5630,7 @@
},
{
"name": "recordings",
- "description": "A list of recordings linked to this entity.",
+ "description": "The list of recordings found in this collection.",
"args": [
{
"name": "after",
@@ -5663,7 +5663,7 @@
},
{
"name": "releases",
- "description": "A list of releases linked to this entity.",
+ "description": "The list of releases found in this collection.",
"args": [
{
"name": "type",
@@ -5724,7 +5724,7 @@
},
{
"name": "releaseGroups",
- "description": "A list of release groups linked to this entity.",
+ "description": "The list of release groups found in this collection.",
"args": [
{
"name": "type",
@@ -5771,7 +5771,7 @@
},
{
"name": "series",
- "description": "A list of series linked to this entity.",
+ "description": "The list of series found in this collection.",
"args": [
{
"name": "after",
@@ -5804,7 +5804,7 @@
},
{
"name": "works",
- "description": "A list of works linked to this entity.",
+ "description": "The list of works found in this collection.",
"args": [
{
"name": "after",
@@ -8980,16 +8980,6 @@
},
"defaultValue": null
},
- {
- "name": "release",
- "description": "The MBID of a release to which the entity is linked.",
- "type": {
- "kind": "SCALAR",
- "name": "MBID",
- "ofType": null
- },
- "defaultValue": null
- },
{
"name": "isrc",
"description": "The [International Standard Recording Code](https://musicbrainz.org/doc/ISRC)\n(ISRC) of the recording.",
@@ -9000,6 +8990,16 @@
},
"defaultValue": null
},
+ {
+ "name": "release",
+ "description": "The MBID of a release to which the entity is linked.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "MBID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
{
"name": "after",
"description": null,
@@ -9063,6 +9063,16 @@
},
"defaultValue": null
},
+ {
+ "name": "discID",
+ "description": "A [disc ID](https://musicbrainz.org/doc/Disc_ID)\nassociated with the release.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "DiscID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
{
"name": "label",
"description": "The MBID of a label to which the entity is linked.",
@@ -9073,26 +9083,6 @@
},
"defaultValue": null
},
- {
- "name": "track",
- "description": "The MBID of a track that is included in the release.",
- "type": {
- "kind": "SCALAR",
- "name": "MBID",
- "ofType": null
- },
- "defaultValue": null
- },
- {
- "name": "trackArtist",
- "description": "The MBID of an artist that appears on a track in the\nrelease, but is not included in the credits for the release itself.",
- "type": {
- "kind": "SCALAR",
- "name": "MBID",
- "ofType": null
- },
- "defaultValue": null
- },
{
"name": "recording",
"description": "The MBID of a recording to which the entity is linked.",
@@ -9113,6 +9103,26 @@
},
"defaultValue": null
},
+ {
+ "name": "track",
+ "description": "The MBID of a track that is included in the release.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "MBID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "trackArtist",
+ "description": "The MBID of an artist that appears on a track in the\nrelease, but is not included in the credits for the release itself.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "MBID",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
{
"name": "type",
"description": "Filter by one or more release group types.",
@@ -9141,16 +9151,6 @@
},
"defaultValue": null
},
- {
- "name": "discID",
- "description": "A [disc ID](https://musicbrainz.org/doc/Disc_ID)\nassociated with the release.",
- "type": {
- "kind": "SCALAR",
- "name": "DiscID",
- "ofType": null
- },
- "defaultValue": null
- },
{
"name": "after",
"description": null,
diff --git a/src/queries/browse.js b/src/queries/browse.js
index 4e1ebd3..26686a5 100644
--- a/src/queries/browse.js
+++ b/src/queries/browse.js
@@ -122,18 +122,25 @@ entity.`,
recordings: createBrowseField(RecordingConnection, {
artist,
collection,
- release,
isrc: {
type: ISRC,
description: `The [International Standard Recording Code](https://musicbrainz.org/doc/ISRC)
(ISRC) of the recording.`
- }
+ },
+ release
}),
releases: createBrowseField(ReleaseConnection, {
area,
artist,
collection,
+ discID: {
+ type: DiscID,
+ description: `A [disc ID](https://musicbrainz.org/doc/Disc_ID)
+associated with the release.`
+ },
label,
+ recording,
+ releaseGroup,
track: {
type: MBID,
description: 'The MBID of a track that is included in the release.'
@@ -143,15 +150,8 @@ entity.`,
description: `The MBID of an artist that appears on a track in the
release, but is not included in the credits for the release itself.`
},
- recording,
- releaseGroup,
type: releaseGroupType,
- status: releaseStatus,
- discID: {
- type: DiscID,
- description: `A [disc ID](https://musicbrainz.org/doc/Disc_ID)
-associated with the release.`
- }
+ status: releaseStatus
}),
releaseGroups: createBrowseField(ReleaseGroupConnection, {
artist,
diff --git a/src/types/collection.js b/src/types/collection.js
index 7cd13e5..c234ff0 100644
--- a/src/types/collection.js
+++ b/src/types/collection.js
@@ -22,6 +22,7 @@ import {
works,
fieldWithID,
resolveHyphenated,
+ createCollectionField,
connectionWithExtras
} from './helpers'
@@ -46,17 +47,17 @@ lists of entities that users can create.`,
...fieldWithID('type', {
description: 'The type of collection.'
}),
- areas,
- artists,
- events,
- instruments,
- labels,
- places,
- recordings,
- releases,
- releaseGroups,
- series,
- works
+ areas: createCollectionField(areas),
+ artists: createCollectionField(artists),
+ events: createCollectionField(events),
+ instruments: createCollectionField(instruments),
+ labels: createCollectionField(labels),
+ places: createCollectionField(places),
+ recordings: createCollectionField(recordings),
+ releases: createCollectionField(releases),
+ releaseGroups: createCollectionField(releaseGroups),
+ series: createCollectionField(series),
+ works: createCollectionField(works)
})
})
diff --git a/src/types/helpers.js b/src/types/helpers.js
index 32c497d..e2b37fa 100644
--- a/src/types/helpers.js
+++ b/src/types/helpers.js
@@ -98,6 +98,14 @@ field.`,
}
}
+export function createCollectionField (config) {
+ const typeName = toPlural(toWords(config.type.name.slice(0, -10)))
+ return {
+ ...config,
+ description: `The list of ${typeName} found in this collection.`
+ }
+}
+
export const id = globalIdField()
export const mbid = {
type: new GraphQLNonNull(MBID),
diff --git a/src/types/release-event.js b/src/types/release-event.js
index d939d99..a8d4373 100644
--- a/src/types/release-event.js
+++ b/src/types/release-event.js
@@ -4,8 +4,8 @@ import Area from './area'
export default new GraphQLObjectType({
name: 'ReleaseEvent',
- description: `Date on which a release was issued in a country/region with a
-particular label, catalog number, barcode, and what release format was used.`,
+ description: `The date on which a release was issued in a country/region with
+a particular label, catalog number, barcode, and format.`,
fields: () => ({
area: { type: Area },
date: { type: DateType }
diff --git a/test/api.js b/test/api.js
index 4917257..e2405bd 100644
--- a/test/api.js
+++ b/test/api.js
@@ -1,5 +1,5 @@
import test from 'ava'
-import { MusicBrainzError } from '../src/api'
+import MusicBrainz, { MusicBrainzError } from '../src/api'
import client from './helpers/client'
test('getLookupURL() generates a lookup URL', t => {
@@ -33,3 +33,32 @@ test('rejects the promise when the API returns an error', t => {
})
return t.throws(req, MusicBrainzError)
})
+
+test('shouldRetry() retries only 5xx responses from MusicBrainz', t => {
+ t.true(client.shouldRetry(new MusicBrainzError('error', 500)))
+ t.true(client.shouldRetry(new MusicBrainzError('error', 501)))
+ t.true(client.shouldRetry(new MusicBrainzError('error', 598)))
+ t.true(client.shouldRetry(new MusicBrainzError('error', 599)))
+ t.false(client.shouldRetry(new MusicBrainzError('error', 404)))
+ t.false(client.shouldRetry(new MusicBrainzError('error', 499)))
+ t.false(client.shouldRetry(new MusicBrainzError('error', 600)))
+})
+
+test('shouldRetry() retries only transient local connection issues', t => {
+ t.true(client.shouldRetry({ code: 'ECONNRESET' }))
+ t.true(client.shouldRetry({ code: 'ENOTFOUND' }))
+ t.true(client.shouldRetry({ code: 'ESOCKETTIMEDOUT' }))
+ t.true(client.shouldRetry({ code: 'ETIMEDOUT' }))
+ t.true(client.shouldRetry({ code: 'ECONNREFUSED' }))
+ t.true(client.shouldRetry({ code: 'EHOSTUNREACH' }))
+ t.true(client.shouldRetry({ code: 'EPIPE' }))
+ t.true(client.shouldRetry({ code: 'EAI_AGAIN' }))
+ t.false(client.shouldRetry({ code: 'ENOENT' }))
+ t.false(client.shouldRetry({ code: 'EACCES' }))
+ t.false(client.shouldRetry({ code: 'EPERM' }))
+})
+
+test('rejects non-MusicBrainz errors', t => {
+ const client = new MusicBrainz({ baseURL: '$!@#$' })
+ t.throws(client.get('artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da'), Error)
+})
diff --git a/test/fixtures/28589f231a3be39ac9077fe789bed818 b/test/fixtures/28589f231a3be39ac9077fe789bed818
new file mode 100644
index 0000000..7151a25
Binary files /dev/null and b/test/fixtures/28589f231a3be39ac9077fe789bed818 differ
diff --git a/test/fixtures/28589f231a3be39ac9077fe789bed818.headers b/test/fixtures/28589f231a3be39ac9077fe789bed818.headers
new file mode 100644
index 0000000..fc64dd5
--- /dev/null
+++ b/test/fixtures/28589f231a3be39ac9077fe789bed818.headers
@@ -0,0 +1,29 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "date": "Wed, 14 Dec 2016 22:14:47 GMT",
+ "content-type": "application/json; charset=utf-8",
+ "transfer-encoding": "chunked",
+ "connection": "keep-alive",
+ "keep-alive": "timeout=15",
+ "vary": "Accept-Encoding",
+ "x-ratelimit-limit": "700",
+ "x-ratelimit-remaining": "142",
+ "x-ratelimit-reset": "1481753687",
+ "server": "Plack::Handler::Starlet",
+ "etag": "W/\"4dc2f8a9f1d01f204478fe0af56fc4b2\"",
+ "access-control-allow-origin": "*",
+ "content-encoding": "gzip"
+ },
+ "url": "http://musicbrainz.org:80/ws/2/label/38dc88de-7720-4100-9d5b-3cdc41b0c474?inc=tags&fmt=json",
+ "time": 1911,
+ "request": {
+ "method": "GET",
+ "headers": {
+ "User-Agent": "graphbrainz/4.5.0 ( https://github.com/exogen/graphbrainz )",
+ "host": "musicbrainz.org",
+ "accept-encoding": "gzip, deflate",
+ "accept": "application/json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/fixtures/4fe2b849e82d3a0e82f9776573e98d1b b/test/fixtures/4fe2b849e82d3a0e82f9776573e98d1b
new file mode 100644
index 0000000..4612cf2
Binary files /dev/null and b/test/fixtures/4fe2b849e82d3a0e82f9776573e98d1b differ
diff --git a/test/fixtures/4fe2b849e82d3a0e82f9776573e98d1b.headers b/test/fixtures/4fe2b849e82d3a0e82f9776573e98d1b.headers
new file mode 100644
index 0000000..bffc608
--- /dev/null
+++ b/test/fixtures/4fe2b849e82d3a0e82f9776573e98d1b.headers
@@ -0,0 +1,29 @@
+{
+ "statusCode": 200,
+ "headers": {
+ "date": "Wed, 14 Dec 2016 22:14:47 GMT",
+ "content-type": "application/json; charset=UTF-8",
+ "transfer-encoding": "chunked",
+ "connection": "keep-alive",
+ "keep-alive": "timeout=15",
+ "vary": "Accept-Encoding",
+ "x-ratelimit-limit": "700",
+ "x-ratelimit-remaining": "145",
+ "x-ratelimit-reset": "1481753687",
+ "last-modified": "Wed, 14 Dec 2016 21:34:26 GMT",
+ "server": "Jetty(9.3.10.v20160621)",
+ "access-control-allow-origin": "*",
+ "content-encoding": "gzip"
+ },
+ "url": "http://musicbrainz.org:80/ws/2/artist?limit=1&inc=tags&query=Leonard%20Cohen&fmt=json",
+ "time": 1884,
+ "request": {
+ "method": "GET",
+ "headers": {
+ "User-Agent": "graphbrainz/4.5.0 ( https://github.com/exogen/graphbrainz )",
+ "host": "musicbrainz.org",
+ "accept-encoding": "gzip, deflate",
+ "accept": "application/json"
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/schema.js b/test/schema.js
index 33f9f20..824087d 100644
--- a/test/schema.js
+++ b/test/schema.js
@@ -1031,3 +1031,43 @@ test('disc queries can be deeply nested', testData, `
})
})
})
+
+test('entities support tags', testData, `
+ {
+ lookup {
+ label(mbid: "38dc88de-7720-4100-9d5b-3cdc41b0c474") {
+ tags {
+ edges {
+ node {
+ name
+ count
+ }
+ }
+ }
+ }
+ }
+ search {
+ artists(query: "Leonard Cohen", first: 1) {
+ edges {
+ node {
+ tags {
+ edges {
+ node {
+ name
+ count
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+`, (t, data) => {
+ const { label } = data.lookup
+ const artists = data.search.artists.edges.map(edge => edge.node)
+ t.true(label.tags.edges.some(edge => edge.node.name === 'indie folk'))
+ t.true(label.tags.edges.some(edge => edge.node.count > 0))
+ t.true(artists[0].tags.edges.some(edge => edge.node.name === 'blues rock'))
+ t.true(artists[0].tags.edges.some(edge => edge.node.count > 0))
+})
diff --git a/test/util.js b/test/util.js
new file mode 100644
index 0000000..0a95e69
--- /dev/null
+++ b/test/util.js
@@ -0,0 +1,11 @@
+import test from 'ava'
+import sinon from 'sinon'
+import { prettyPrint } from '../src/util'
+
+test.beforeEach(t => { sinon.stub(console, 'log') })
+test.afterEach(t => { console.log.restore() })
+
+test('prettyPrint writes to stdout', t => {
+ prettyPrint('foo')
+ t.true(console.log.calledOnce)
+})
diff --git a/yarn.lock b/yarn.lock
index 5eceed9..eea800f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -32,8 +32,8 @@ ajv-keywords@^1.0.0:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.2.0.tgz#676c4f087bfe1e8b12dca6fda2f3c74f417b099c"
ajv@^4.7.0:
- version "4.9.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.9.2.tgz#3f7dcda95b0c34bceb2d69945117d146219f1a2c"
+ version "4.10.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.10.0.tgz#7ae6169180eb199192a8b9a19fd0f47fc9ac8764"
dependencies:
co "^4.6.0"
json-stable-stringify "^1.0.1"
@@ -1173,7 +1173,7 @@ cli-spinners@^0.1.2:
cli-truncate@^0.2.0:
version "0.2.1"
- resolved "http://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
dependencies:
slice-ansi "0.0.4"
string-width "^1.0.1"
@@ -1261,7 +1261,7 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-concat-stream@^1.0.0, concat-stream@^1.4.6, concat-stream@^1.4.7, concat-stream@^1.5.0:
+concat-stream@^1.0.0, concat-stream@^1.4.6, concat-stream@^1.5.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
dependencies:
@@ -1371,14 +1371,6 @@ cross-spawn@^4, cross-spawn@^4.0.0:
lru-cache "^4.0.1"
which "^1.2.9"
-cross-spawn@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.0.1.tgz#a3bbb302db2297cbea3c04edf36941f4613aa399"
- dependencies:
- lru-cache "^4.0.1"
- shebang-command "^1.2.0"
- which "^1.2.9"
-
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -1419,9 +1411,9 @@ debug-log@^1.0.0, debug-log@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f"
-debug@^2.0.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c"
+debug@^2.0.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.4.3:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.4.3.tgz#3fe67c5588e724d0f5d9e48c8f08ff69b4b20643"
dependencies:
ms "0.7.2"
@@ -1947,7 +1939,7 @@ finalhandler@0.5.0:
find-cache-dir@^0.1.1:
version "0.1.1"
- resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9"
+ resolved "http://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9"
dependencies:
commondir "^1.0.1"
mkdirp "^0.5.1"
@@ -2014,6 +2006,12 @@ form-data@~2.1.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
+formatio@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9"
+ dependencies:
+ samsam "~1.1"
+
forwarded@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363"
@@ -2377,6 +2375,10 @@ inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+inherits@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
+
ini@~1.3.0:
version "1.3.4"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
@@ -2565,7 +2567,7 @@ is-plain-obj@^1.0.0:
is-posix-bracket@^0.1.0:
version "0.1.1"
- resolved "http://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+ resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
is-primitive@^2.0.0:
version "2.0.0"
@@ -2747,8 +2749,8 @@ jsprim@^1.2.2:
verror "1.3.6"
jsx-ast-utils@^1.3.3:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.3.4.tgz#0257ed1cc4b1e65b39d7d9940f9fb4f20f7ba0a9"
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.3.5.tgz#9ba6297198d9f754594d62e59496ffb923778dd4"
dependencies:
acorn-jsx "^3.0.1"
object-assign "^4.1.0"
@@ -2923,6 +2925,10 @@ log-update@^1.0.1:
ansi-escapes "^1.0.0"
cli-cursor "^1.0.2"
+lolex@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31"
+
longest-streak@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-1.0.0.tgz#d06597c4d4c31b52ccb1f5d8f8fe7148eafd6965"
@@ -3199,8 +3205,8 @@ npm-prefix@^1.0.1:
untildify "^2.1.0"
npmlog@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.1.tgz#d14f503b4cd79710375553004ba96e6662fbc0b8"
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f"
dependencies:
are-we-there-yet "~1.1.2"
console-control-strings "~1.1.0"
@@ -3329,17 +3335,13 @@ os-locale@^1.4.0:
dependencies:
lcid "^1.0.0"
-os-shim@^0.1.2:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
-
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
osenv@^0.1.0:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.3.tgz#83cf05c6d6458fc4d5ac6362ea325d92f2754217"
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
@@ -3561,14 +3563,6 @@ power-assert-util-string-width@^1.1.1:
dependencies:
eastasianwidth "^0.1.1"
-pre-commit@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.1.tgz#6c591d1af460b41b36d136a0fe0ff9570b3c5473"
- dependencies:
- cross-spawn "^5.0.1"
- spawn-sync "^1.0.15"
- which "1.2.x"
-
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@@ -3955,8 +3949,8 @@ resolve-from@^2.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
resolve@^1.1.6:
- version "1.1.7"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.2.0.tgz#9589c3f2f6149d1417a40becc1663db6ec6bc26c"
restore-cursor@^1.0.1:
version "1.0.1"
@@ -3965,9 +3959,9 @@ restore-cursor@^1.0.1:
exit-hook "^1.0.0"
onetime "^1.0.0"
-retry@^0.10.0:
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.0.tgz#649e15ca408422d98318161935e7f7d652d435dd"
+retry@^0.10.1:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4"
right-align@^0.1.1:
version "0.1.3"
@@ -3995,6 +3989,10 @@ rx-lite@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
+samsam@1.1.2, samsam@~1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567"
+
semver-diff@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@@ -4050,16 +4048,6 @@ setprototypeof@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08"
-shebang-command@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
- dependencies:
- shebang-regex "^1.0.0"
-
-shebang-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
-
shelljs@^0.7.5:
version "0.7.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675"
@@ -4080,6 +4068,15 @@ signal-exit@^3.0.0, signal-exit@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+sinon@^1.17.6:
+ version "1.17.6"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.6.tgz#a43116db59577c8296356afee13fafc2332e58e1"
+ dependencies:
+ formatio "1.1.1"
+ lolex "1.3.2"
+ samsam "1.1.2"
+ util ">=0.10.3 <1"
+
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
@@ -4132,13 +4129,6 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1:
version "0.5.6"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
-spawn-sync@^1.0.15:
- version "1.0.15"
- resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
- dependencies:
- concat-stream "^1.4.7"
- os-shim "^0.1.2"
-
spawn-wrap@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.2.4.tgz#920eb211a769c093eebfbd5b0e7a5d2e68ab2e40"
@@ -4416,8 +4406,8 @@ timed-out@^2.0.0:
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a"
timed-out@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.0.0.tgz#ff88de96030ce960eabd42487db61d3add229273"
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.0.tgz#43b98b14bb712c9161c28f4dc1f3068d67a04ec2"
to-fast-properties@^1.0.1:
version "1.0.2"
@@ -4466,8 +4456,8 @@ tunnel-agent@~0.4.1:
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
- version "0.14.4"
- resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.4.tgz#8c9dbfb52795686f166cd2023794bcf103d13c2b"
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
type-check@~0.3.2:
version "0.3.2"
@@ -4622,6 +4612,12 @@ util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+"util@>=0.10.3 <1":
+ version "0.10.3"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
+ dependencies:
+ inherits "2.0.1"
+
utils-merge@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
@@ -4703,7 +4699,7 @@ which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
-which@1.2.x, which@^1.2.4, which@^1.2.9:
+which@^1.2.4, which@^1.2.9:
version "1.2.12"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192"
dependencies: