Skip to content

Instantly share code, notes, and snippets.

@heygambo
Created January 15, 2020 10:02
Show Gist options
  • Select an option

  • Save heygambo/5151096e79d978a1fe088553ff36b57b to your computer and use it in GitHub Desktop.

Select an option

Save heygambo/5151096e79d978a1fe088553ff36b57b to your computer and use it in GitHub Desktop.

Revisions

  1. heygambo created this gist Jan 15, 2020.
    982 changes: 982 additions & 0 deletions firebase-mock-list-collections-specs.log
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,982 @@
    (feature/add-list-collections) firebase-mock ツ npm run test

    > firebase-mock@2.3.0 test /Users/gambo/code/github/firebase-mock
    > gulp lint && gulp test

    [11:00:45] Using gulpfile ~/code/github/firebase-mock/gulpfile.js
    [11:00:45] Starting 'lint'...
    [11:00:46] Finished 'lint' after 1.15 s
    [11:00:49] Using gulpfile ~/code/github/firebase-mock/gulpfile.js
    [11:00:49] Starting 'test'...
    [11:00:49] Starting 'cover'...
    [11:00:50] Finished 'cover' after 805 ms
    [11:00:50] Starting '<anonymous>'...


    Auth
    #changeAuthState
    ✓ sets the auth data
    ✓ is a noop if deeply equal
    ✓ is a noop if deeply equal
    ✓ sets null for a non object
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ triggers an auth event
    #getUserByEmail
    ✓ gets a copy of the user by email
    ✓ only searches own properties
    ✓ fails when user not found
    #getUser
    ✓ gets a copy of the user by uid
    ✓ only searches own properties
    ✓ fails when user not found
    #auth
    FIREBASE WARNING: FirebaseRef.auth() being deprecated. Please use FirebaseRef.authWithCustomToken() instead.
    ✓ calls callback on auth state change
    #authWithCustomToken
    ✓ calls the callback with a nextErr
    ✓ invokes the callback when auth state is set
    ✓ handles no callback
    #getAuth
    ✓ is null by default
    ✓ returns the value from changeAuthState
    #onAuth
    ✓ is triggered when changeAuthState modifies data
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is not be triggered if auth state does not change
    ✓ can set a context
    ✓ synchronously triggers the callback with the current auth data
    #offAuth
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ removes a callback
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ only removes callback that matches the context
    #unauth
    ✓ sets auth data to null
    ✓ triggers onAuth callback if not null
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ does not trigger auth events if not authenticated
    #onIdTokenChanged
    ✓ is triggered when changeAuthState modifies the user
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is not triggered when auth state does not change
    ✓ synchronously triggers the callback with the current auth data
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ does not trigger after unsubscribe
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is triggered if only ID token changes
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is triggered on updating current user
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is not triggered on updating non-current user
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is not triggered on updating current user with the same info
    #onAuthStateChanged
    ✓ is triggered when changeAuthState modifies the user
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is not triggered when auth state does not change
    ✓ synchronously triggers the callback with the current auth data
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ does not trigger after unsubscribe
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ is not triggered if only ID token changes
    #createUser
    ✓ creates a new user
    ✓ creates a new user without a password
    ✓ creates a new user and returns promise
    ✓ increments the id for each user
    ✓ creates a new user with preset uid
    ✓ creates a new user with preset additional attributes
    ✓ fails if credentials is not an object
    ✓ fails if email is not a string
    ✓ fails if user already exists
    ✓ fails if failNext is set
    #createUserWithEmailAndPassword
    ✓ creates a new user
    ✓ fails if failNext is set
    #changeEmail
    ✓ changes the email
    ✓ fails if credentials is not an object
    ✓ fails if oldEmail is not a string
    ✓ should fail if newEmail is not a string
    ✓ fails if password is not a string
    ✓ fails if user does not exist
    ✓ fails if password is incorrect
    ✓ fails if failNext is set
    #changePassword
    ✓ changes the password
    ✓ fails if credentials is not an object
    ✓ fails if email is not a string
    ✓ should fail if oldPassword is not a string
    ✓ fails if newPassword is not a string
    ✓ fails if user does not exist
    ✓ fails if oldPassword is incorrect
    ✓ fails if failNext is set
    #removeUser
    ✓ removes the account
    ✓ fails if credentials is not an object
    ✓ fails if email is not a string
    ✓ fails if password is not a string
    ✓ fails if user does not exist
    ✓ fails if password is incorrect
    ✓ fails if failNext is set
    #resetPassword
    ✓ simulates reset if credentials are valid
    ✓ fails if credentials is not an object
    ✓ fails if email is not a string
    ✓ fails if user does not exist
    ✓ fails if failNext is set
    #verifyIdToken
    ✓ succeeds if user exists with token
    ✓ should populates claims
    ✓ fails if no user exists with token
    ✓ fails if failNext is set
    #setCustomUserClaims
    ✓ succeeds if user exists
    ✓ fails if no user exists with token
    ✓ fails if failNext is set
    #updateUser
    ✓ should replace the existing user
    ✓ preserves deep equality of users
    ✓ should select by uid
    ✓ should return the updated user
    ✓ should store a referentially different user from the argument
    ✓ should reject if the user does not exist
    ✓ should wait for flush

    API.md
    Auth example for changeAuthState
    ✓ works as described
    Messaging examples
    ✓ send messages
    ✓ returns custom message responses
    ✓ callback on sending messages

    MockFirebase
    set & transition
    ✓ should work
    Array rendering
    ✓ renders array-like data as an array
    Server Timestamps
    ✓ parses server timestamps
    ✓ parses server timestamps in child data
    ✓ parses server timestamps in priorities
    Firebase#setClock
    ✓ sets a timestamp factory function
    #restoreClock
    ✓ restores the normal clock
    #flush
    ✓ flushes the queue and returns itself
    #autoFlush
    ✓ enables autoflush with no args
    ✓ can specify a flush delay
    ✓ sets the delay on all children
    ✓ sets the delay on a parent
    ✓ returns itself
    #failNext
    ✓ must be called with an Error
    #forceCancel
    ✓ calls the cancel callback
    ✓ calls the cancel callback on the context
    ✓ turns off the listener
    ✓ can match an event type
    ✓ can match a callback
    ✓ can match a context
    ✓ can take null as the cancel callback
    #fakeEvent
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ can trigger a fake value event
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ can trigger a fake child_added event
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ uses null as the default data
    #child
    ✓ requires a path
    ✓ caches children
    ✓ calls child recursively for multi-segment paths
    ✓ can use leading slashes (#23)
    ✓ can use trailing slashes (#23)
    #parent
    ✓ gets a parent ref
    #ref
    ✓ returns itself
    ✓ child / returns same reference
    #set
    ✓ should validate the data
    ✓ should return a promise
    ✓ should remove old keys from data
    ✓ should remove empty properties from data
    ✓ should set priorities on children if included in data
    ✓ should have correct priority in snapshot if added with set
    ✓ should fire child_added events with correct prevChildName
    ✓ should fire child_added events with correct priority
    ✓ should trigger child_removed if child keys are missing
    ✓ should change parent from null to object when child is set
    #setPriority
    ✓ should trigger child_moved with correct prevChildName
    ✓ should trigger a callback
    ✓ can be called on the root
    #setWithPriority
    ✓ should pass the priority to #setPriority
    ✓ should pass the data and callback to #set
    #update
    ✓ must be called with an object
    ✓ should validate the data
    ✓ extends the data
    ✓ removes empty data
    ✓ can work with nested paths
    ✓ can work with nested paths beginning with /
    ✓ overrides the paths with existing data
    ✓ does not change unrelated data
    ✓ handles multiple calls in the same flush
    ✓ can be called on an empty reference
    ✓ can simulate an error
    #remove
    ✓ should return a promise
    ✓ fires child_removed for children
    ✓ changes to null if all children are removed
    ✓ can simulate an error
    #on
    ✓ validates the event name
    ✓ should work when initial value is null
    ✓ can take the context as the 3rd argument
    ✓ can simulate an error
    ✓ can simulate an error
    ✓ is cancelled by an off call before flush
    ✓ returns the callback
    #once
    ✓ validates the event name
    ✓ only fires the listener once
    ✓ can catch a simulated error
    ✓ can provide a context in place of cancel
    #off
    ✓ validates the event name
    ✓ can disable all events
    sinon.reset is deprecated and will be removed from the public API in a future version of sinon.
    ✓ can disable a specific event
    #transaction
    ✓ should call the transaction function
    ✓ should fire the callback with a "committed" boolean and error message
    ✓ should return a promise wrapping a "committed" boolean and a snapshot
    ✓ should update primative value
    ✓ should update property value
    ✓ should update nested property value
    ✓ should remove empty properties from data
    #push
    ✓ should validate the data
    ✓ should return thenable reference
    ✓ should return thenable reference when no arguments are passed
    ✓ can add data by auto id
    ✓ can simulate an error
    ✓ avoids calling set when unnecessary
    #root
    ✓ traverses to the top of the reference
    #getFlushQueue
    ✓ returns an array equal to number of flush events queued
    ✓ does not change length if more items are added to the queue
    ✓ sets the ref attribute correctly
    ✓ sets the `method` attribute correctly
    ✓ sets the `args` attribute correctly
    Firebase.autoId
    ✓ fails to add nested data by auto id
    ✓ succeeds to add nested data by auto id, when Firebase.autoId is replaced

    MockFirestoreCollection
    #flush
    ✓ flushes the queue and returns itself
    #autoFlush
    ✓ enables autoflush with no args
    ✓ can specify a flush delay
    ✓ sets the delay on all collections and documents
    ✓ sets the delay on a parent
    ✓ returns itself
    #get
    ✓ allow calling get()
    ✓ retrieves all no data for non-existing collection
    ✓ retrieves all data for existing collection
    ✓ retrieves data added to collection
    ✓ retrieves data set as document
    #doc
    ✓ allow calling doc()
    ✓ allow calling doc() with empty path to generate id
    ✓ creates child documents with a firestore property pointing at the root db
    ✓ creates child documents with a firestore property pointing at the firestore of the collection
    #add
    ✓ allow calling add()
    ✓ allow adding data to empty collection
    ✓ allow adding data to existing collection
    #where
    ✓ caches children
    ✓ allow calling where() on collection
    ✓ allow calling where() multiple times
    ✓ results contain ref for each doc
    ✓ returns matched documents for operator "=="
    ✓ returns matched documents for operator "array-contains"
    Using unsupported where() operator for firebase-mock, returning entire dataset
    Using unsupported where() operator for firebase-mock, returning entire dataset
    ✓ returns all documents when using unsupported operator
    ✓ returns matched documents with multiple where calls
    ✓ allow using complex path
    #stream
    ✓ returns a stream that emits all results
    #orderBy
    ✓ allow calling orderBy() on collection
    ✓ allow calling orderBy() multiple times
    ✓ returns documents is desired order
    ✓ returns documents ordered by name using FieldPath
    ✓ returns documents ordered by id
    ✓ returns documents ordered by timestamp
    ✓ returns documents ordered by date
    #startAfter
    ✓ returns data after the specified value
    ✓ works with limit
    ✓ throws with no order
    #limit
    ✓ allow calling limit() on collection
    ✓ returns limited amount of documents
    #listDocuments
    ✓ retrieves all data for existing collection
    ✓ retrieves data added to collection
    #onSnapshot
    ✓ returns value after collection is updated
    ✓ calls callback after multiple updates
    ✓ should unsubscribe
    ✓ Calls onError if error

    DocumentDeltaSnapshot
    #exists
    ✓ returns false if no data
    ✓ returns true if data available
    #data
    ✓ returns null if no data
    ✓ returns data if data provided
    #get
    ✓ returns undefined if data does not exist
    ✓ returns undefined if data does not exist
    ✓ returns undefined if path is empty
    ✓ returns undefined if path does not exist
    ✓ returns data if path exists
    ✓ returns data with complex path
    #create
    ✓ returns snapshot at correct path
    ✓ returns snapshot with correct data from previous value
    adding doc
    ✓ correctly applies delta when adding doc
    updating doc
    ✓ correctly applies delta when adding data
    ✓ correctly applies delta when removing data
    ✓ correctly applies delta when changing data
    deleting doc
    ✓ correctly applies delta when deleting doc

    DocumentSnapshot
    #exists
    ✓ returns false if no data
    ✓ returns true if data is empty
    ✓ returns true if data available
    #data
    ✓ returns null if no data
    ✓ returns empty data if empty data provided
    ✓ returns data if data provided
    ✓ returns clone of data
    #get
    ✓ returns undefined if data does not exist
    ✓ returns undefined if data does not exist
    ✓ returns undefined if path is empty
    ✓ returns undefined if path does not exist
    ✓ returns undefined if path leads to null value
    ✓ returns data if path exists
    ✓ returns data if field path exists
    ✓ returns data with complex path
    ✓ returns data with complex field path
    ✓ returns document id
    #ref
    ✓ returns ref for document

    MockFirestoreDocument
    #flush
    ✓ flushes the queue and returns itself
    #autoFlush
    ✓ enables autoflush with no args
    ✓ can specify a flush delay
    ✓ sets the delay on all collections
    ✓ sets the delay on a parent
    ✓ returns itself
    #collection
    ✓ allow calling collection()
    ✓ creates child collections with a firestore property pointing at the root db
    ✓ creates child collections with a firestore property pointing at the firestore of the collection
    #get
    ✓ gets value of doc
    ✓ results contain ref for doc
    #create
    ✓ creates a new doc
    ✓ creates a new doc with null values
    ✓ creates a new doc with server time values
    ✓ throws an error when a doc already exists
    #set
    ✓ sets value of doc
    ✓ sets value of doc with null values
    ✓ sets value of doc with server timestamp
    ✓ sets value of doc with ref
    #set with {merge: true}
    ✓ creates doc if does not exist
    ✓ creates doc with null values if does not exist
    ✓ updates value of doc
    ✓ updates value of doc with null values
    ✓ can update date fields
    #update
    ✓ updates value of doc
    ✓ updates value of doc with null properties
    ✓ updates value of doc with server time value
    ✓ removes property when using FieldValue.delete()
    ✓ updates an array property when using FieldValue.arrayRemove()
    ✓ updates an array property when using FieldValue.arrayUnion()
    ✓ does not merge nested properties recursively by default
    ✓ merges nested properties recursively when using nested paths
    ✓ can update date fields
    #delete
    ✓ delete doc
    #getCollections
    when present
    ✓ returns collections of document
    ✓ returns deeply nested collections of document
    when not present
    ✓ returns empty list of collections
    ✓ skips collections that has no documents
    #listCollections
    when present
    ✓ returns collections of document
    ✓ returns deeply nested collections of document
    when not present
    ✓ returns empty list of collections
    ✓ skips collections that has no documents
    #onSnapshot
    ✓ calls observer with initial state
    ✓ calls observer when document is updated
    ✓ does not call observer when no changes occur
    ✓ returns error if error occured
    ✓ does not returns value when not updated
    ✓ unsubscribes
    ✓ accepts option includeMetadataChanges

    FieldPath
    constructor
    ✓ should have path to "name"
    #documentId
    ✓ should be a function
    ✓ should return FieldPath
    ✓ should have path to "documentId"
    #isEqual
    ✓ should be a function
    ✓ should work with FieldPath.delete()

    FieldValue
    #delete
    ✓ should be a function
    ✓ should return FieldValue
    ✓ should type to "delete"
    #serverTimestamp
    ✓ should be a function
    ✓ should return FieldValue
    ✓ should type to "serverTimestamp"
    #arrayRemove
    ✓ should be a function
    ✓ should return FieldValue
    ✓ should type to "serverTimestamp"
    #arrayUnion
    ✓ should be a function
    ✓ should return FieldValue
    ✓ should type to "serverTimestamp"
    #isEqual
    ✓ should be a function
    ✓ should work with FieldValue.delete()
    ✓ should work with FieldValue.serverTimestamp()

    QuerySnapshot
    #forEach
    ✓ calls the callback with each child
    ✓ can set a this value
    ✓ passes ref for each doc
    #empty
    ✓ tests for children
    #size
    ✓ returns the object size
    ✓ returns 0 for a null snapshot
    #docs
    ✓ returns the data as an array of snapshots

    MockFirestore
    #flush
    ✓ flushes the queue and returns itself
    #autoFlush
    ✓ enables autoflush with no args
    ✓ can specify a flush delay
    ✓ sets the delay on all collections and documents
    ✓ returns itself
    #collection
    ✓ allow calling collection()
    ✓ allow calling collection() with complex path
    ✓ caches children
    ✓ caches deep children
    ✓ caches deep children with paths
    ✓ creates child collection with a firestore property pointing at itself
    #doc
    ✓ allow calling doc()
    ✓ allow calling doc() with complex path
    ✓ caches children
    ✓ caches deep children
    ✓ caches deep children with paths
    ✓ creates child document with a firestore property pointing at itself
    #runTransaction
    ✓ transaction updates data
    ✓ returns the return value of the passed function
    #batch
    ✓ batch runs commands after commit
    ✓ works with set + merge
    ✓ supports method chaining
    when "batch.commit" is not called
    ✓ does not create documents
    #getAll
    ✓ gets the value of all passed documents

    MockMessaging
    #flush
    ✓ flushes the queue and returns itself
    #autoFlush
    ✓ enables autoflush with no args
    ✓ can specify a flush delay
    ✓ returns itself
    #on
    ✓ throws if callback is not a function
    ✓ registers a callback
    #send
    ✓ should check that message is not undefined
    ✓ should return thenable reference
    ✓ can simulate an error
    ✓ can return user defined results
    ✓ invokes callback with args
    #sendAll
    ✓ should check that messages is an array
    ✓ should return thenable reference
    ✓ can simulate an error
    ✓ can return user defined results
    ✓ invokes callback with args
    #sendMulticast
    ✓ should check that message is not undefined
    ✓ should check that message contains a "tokens" array
    ✓ should return thenable reference
    ✓ can simulate an error
    ✓ can return user defined results
    ✓ invokes callback with args

    MockQuery
    #ref
    ✓ returns the ref used to create the query
    #flush
    ✓ flushes the ref
    #autoFlush
    ✓ autoFlushes the ref
    #getData
    ✓ gets data from the slice
    #fakeEvent
    ✓ validates the event name
    ✓ fires the matched event with a snapshot
    on
    ✓ validates the event name
    value
    ✓ should provide value immediately
    ✓ should return null if nothing in range exists
    ✓ should return correct keys
    ✓ should update on change
    ✓ should not update on change outside range
    ✓ can take the context as the 3rd argument
    ✓ should work with equalTo
    ✓ should work with boolean equalTo
    ✓ should return null if not equalTo
    once
    ✓ validates the event name
    ✓ should be triggered if value is null
    ✓ should be triggered if value is not null
    ✓ should not get triggered twice
    child_added
    - should include prevChild
    ✓ should trigger all keys in initial range
    - should notify on a new added event after init
    - should not notify for add outside range
    - should trigger a child_removed if using limitToLast
    ✓ should work if connected from instead a once "value"
    child_changed
    - should trigger for a key in range
    - should not trigger for a key outside of range
    child_removed
    - should trigger for a child in range
    - should not trigger for a child out of range
    - should trigger a child_added for replacement if using limitToLast
    child_moved
    - should trigger if item in range moves in range
    - should trigger child_removed if goes out of range
    - should trigger child_added if moved in range
    off
    - should not notify on callbacks
    limitToFirst
    - should throw Error if non-integer argument
    ✓ should return correct number of results
    ✓ should work if does not match any results
    - should be relevant to endAt()
    - should be relevant to startAt()
    limitToLast
    - should throw Error if non-integer argument
    ✓ should return correct number of results
    ✓ should work if does not match any results
    - should be relevant to endAt()
    - should be relevant to startAt()
    endAt
    - should make limit relative to the end of data
    - should stop at the priority given
    - should stop at the key given
    - should stop at the key+priority given
    startAt
    - should make limit relative to start of data
    - should start at the priority given
    - should start at the key given
    - should start at the key+priority given

    FlushQueue
    ✓ constructs an empty event queue
    ✓ removes events when they are cancelled
    #push
    ✓ pushes simple events onto the queue like [].push
    ✓ pushes complex events
    #flush
    ✓ is throws when there are no deferreds
    ✓ fires the events synchronously by default
    ✓ fires events added during queue processing
    ✓ prevents recursive flush calls
    ✓ can invoke events after a delay
    #getEvents
    ✓ returns a copy of the events

    FlushEvent
    #run
    ✓ runs the event handler on the context
    ✓ emits a done event
    #cancel
    ✓ emits a done event

    MockFirebaseSdk
    Dependency Injection
    ✓ returns DI for database().ref()
    ✓ returns DI for database().refFromURL()
    ✓ returns DI for auth()
    #database
    ✓ returns object with ref properties
    ✓ ServerValue
    #ref
    ✓ returns a MockFirebase reference
    #refFromURL
    ✓ returns a MockFirebase reference
    #firestore
    ✓ returns object with doc and collection functions
    ✓ FieldValue.delete
    ✓ FieldValue.serverTimestamp
    ✓ FieldValue.arrayRemove
    ✓ FieldValue.arrayUnion
    ✓ FieldPath.documentId
    #auth
    ✓ returns Authentication object without ref property
    ✓ should get credential
    #EmailAuthProvider
    ✓ sets provider id
    ✓ should get credential
    #GoogleAuthProvider
    ✓ sets provider id
    ✓ should get credential
    #TwitterAuthProvider
    ✓ sets provider id
    ✓ should get credential
    #FacebookAuthProvider
    ✓ sets provider id
    ✓ should get credential
    #GithubAuthProvider
    ✓ sets provider id
    #initializeApp
    ✓ returns firebase app

    DataSnapshot
    #ref
    ✓ returns the reference
    #val
    ✓ returns a deep clone of the data
    ✓ returns null for an empty object
    #getPriority
    ✓ returns the priority
    #child
    ✓ generates a snapshot for a child ref
    ✓ uses child data
    ✓ uses child data starting with /
    ✓ uses child data ending with /
    ✓ uses child data for false values
    ✓ uses child data for 0 values
    ✓ uses child data when accessing with multiple paths
    ✓ uses child data when accessing with multiple paths for false values
    ✓ uses child data when accessing with multiple paths for 0 values
    ✓ uses null when there is no child data
    ✓ uses null when there is no child data with multiple paths
    ✓ passes the priority
    ✓ allows array indexes
    ✓ allows array indexes in multiple paths
    #exists
    ✓ checks for a null value
    #forEach
    ✓ calls the callback with each child
    ✓ can set a this value
    #hasChild
    ✓ can handle null snapshots
    ✓ tests for the key
    ✓ tests for the key starting with /
    ✓ tests for the key ending with /
    ✓ tests for the key with multiple paths
    #hasChildren
    ✓ tests for children
    #key
    ✓ returns the ref key
    #name
    DataSnapshot.name() is deprecated. Use DataSnapshot.key
    ✓ passes through to #key
    #numChildren
    ✓ returns the object size
    ✓ returns 0 for a null snapshot
    #exportVal
    ✓ handles primitives with no priority
    ✓ handles primitives with priorities
    ✓ recursively builds an export object

    StorageBucket
    constructor
    ✓ should add storage reference
    #file
    ✓ should create file
    #getFiles
    ✓ should get all files without query
    ✓ should get only matched prefix files
    #deleteFiles
    ✓ should delete all files without query
    ✓ should delete only matched prefix files

    StorageFile
    constructor
    ✓ should add bucket reference
    #get
    ✓ should get file
    #save
    ✓ should save contents
    #exists
    ✓ should not exist when no content
    ✓ should exist when content added
    #getSignedUrl
    ✓ should get url
    #download
    ✓ should download file
    ✓ should send file as a buffer
    ✓ should access file from different refs via same bucket
    #delete
    ✓ should delete file from bucket
    ✓ should not exist after file deleted
    #move
    ✓ should move file using string
    ✓ should move file using File
    ✓ should move file using Bucket
    #getMetadata
    ✓ should get metadata
    #setMetadata
    ✓ should set metadata

    StorageFile
    constructor
    ✓ should add storage reference
    #child
    ✓ should work with basic path
    ✓ should work with complex path
    #getDownloadURL
    ✓ should get url

    Storage
    #bucket
    ✓ should create bucket
    ✓ should not recreate bucket with the same name
    #ref
    ✓ should work with basic path
    ✓ should work with complex path
    ✓ should work with leading slash in path
    ✓ should work with trailing slash in path
    ✓ should work with multiple consecutive slashes in path

    Timestamp
    fromDate
    ✓ should convert from date
    fromMillis
    ✓ should convert from milliseconds
    #toDate
    ✓ should convert to date

    User
    ✓ should be exported
    #constructor
    ✓ should reject ID tokens that expire before the issuance time
    ✓ should reject ID tokens that are issued before the auth time
    ✓ should reject ID tokens that are issued in the future
    ✓ should reject ID tokens that show the user authenticating in the future
    ✓ should keep reference to passed-in auth
    #clone
    ✓ deep copies custom claims
    ✓ preserves reference to auth
    ✓ preserves deep equality
    #delete
    ✓ should delete user
    #reload
    ✓ should reload email when changed
    #updateEmail
    ✓ should change email
    #updatePassword
    ✓ should change password
    #updateProfile
    ✓ should change display name
    ✓ should change photo URL
    #getIdToken
    ✓ should get token
    ✓ should refresh token
    ✓ should refresh token result
    #getIdTokenResult
    ✓ should use defaults if the id token result param is omitted
    without forceRefresh
    .authTime
    ✓ should use provided auth time
    ✓ should default auth time to current time
    .issuedAtTime
    ✓ should use provided issued-at time
    ✓ should default to auth time
    .expirationTime
    ✓ should use provided expiration time
    ✓ should default to issued at time plus 1 hour
    .signInProvider
    ✓ should use User's providerId string
    ✓ should default to null
    .claims
    ✓ should use user's customClaims object
    ✓ should default to empty object
    .token
    ✓ should be the same as returned from getIdToken
    with forceRefresh
    ✓ should refresh the ID token
    #_refreshIdToken
    ✓ should return a new token result
    ✓ should persist the new token result
    ✓ should use the previous token's authTime by default
    ✓ should use current time as new issuance time by default
    ✓ should expire one hour after issuance by default
    ✓ should update the upstream user if there is one
    ✓ should accept missing upstream users
    #toJSON
    most fields
    ✓ should be the same
    .metadata
    ✓ keys should be missing if omitted
    ✓ should populate to lastLogin if present
    ✓ should populate to createdAt if present

    utils
    removeEmptyRtdbProperties
    ✓ should return null, when the obj is empty
    ✓ should make no changes, when obj does not contain an empty property
    ✓ should make no changes, when obj is a bool
    ✓ should make no changes, when obj is a string
    ✓ should make no changes, when obj is a number
    ✓ should make no changes, when obj is a NaN
    ✓ should make no changes, when obj is a undefined
    ✓ should remove property, when it is null
    ✓ should remove property, when it is an empty object
    ✓ should remove property, when it is an empty array
    ✓ should return null, when all properties are null
    removeEmptyFirestoreProperties
    ✓ should return null, when the obj is empty
    ✓ should make no changes, when obj does not contain an empty property
    ✓ should make no changes, when obj is a bool
    ✓ should make no changes, when obj is a string
    ✓ should make no changes, when obj is a number
    ✓ should make no changes, when obj is a Date
    ✓ should make no changes, when obj is a Timestamp
    ✓ should make no changes, when obj is a NaN
    ✓ should make no changes, when obj is a undefined
    ✓ should remove property, when it is null
    ✓ should remove property, when it is an empty object
    ✓ should remove property, when it is an empty array
    ✓ should return null, when all properties are null
    updateToRtdbObject
    ✓ should split the properties by slash
    ✓ should not overwrite updates to the same branch
    ✓ should not touch properties without slash
    ✓ should ignore leading slash
    updateToFirestoreObject
    ✓ should split the properties by dot
    ✓ should not overwrite updates to the same branch
    ✓ should not touch properties without dot
    ✓ should ignore leading slash
    priorityComparator
    ✓ should give no priority to equal items
    ✓ should order null items first
    ✓ should order false before true
    ✓ should order booleans before numbers
    ✓ should order numbers before strings
    ✓ should order numbers in ascending order
    ✓ should order strings lexicographically


    613 passing (1s)
    27 pending

    ---------------------------------------|----------|----------|----------|----------|----------------|
    File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
    ---------------------------------------|----------|----------|----------|----------|----------------|
    src/ | 93.58 | 83.32 | 90.7 | 93.86 | |
    auth.js | 91.11 | 62.5 | 66.67 | 91.11 | 34,37,44,74 |
    firebase-auth.js | 89.75 | 82.73 | 86.32 | 90.17 |... 574,575,576 |
    firebase.js | 96.27 | 93.95 | 92.31 | 96.15 |... 645,646,647 |
    firestore-collection.js | 93.94 | 64.29 | 86.67 | 93.75 | 24,46,79,94 |
    firestore-delta-document-snapshot.js | 94.74 | 87.5 | 100 | 94.74 | 24 |
    firestore-document-snapshot.js | 100 | 100 | 100 | 100 | |
    firestore-document.js | 91.79 | 70.97 | 89.47 | 92.19 |... 203,265,319 |
    firestore-field-path.js | 91.67 | 100 | 75 | 91.67 | 17 |
    firestore-field-value.js | 100 | 100 | 100 | 100 | |
    firestore-query-snapshot.js | 100 | 100 | 100 | 100 | |
    firestore-query.js | 92.71 | 73.2 | 89.19 | 92.63 |... 220,254,319 |
    firestore.js | 92.19 | 80 | 86.21 | 92.91 |... 216,217,218 |
    index.js | 100 | 100 | 100 | 100 | |
    lodash.js | 100 | 100 | 100 | 100 | |
    messaging.js | 98.65 | 91.67 | 100 | 98.65 | 123 |
    query.js | 86.73 | 68 | 95.65 | 86.73 |... 136,148,178 |
    queue.js | 100 | 100 | 100 | 100 | |
    sdk.js | 96.77 | 58.33 | 90 | 96.77 | 86,90 |
    slice.js | 80.8 | 71.74 | 72.22 | 82.79 |... 165,174,177 |
    snapshot.js | 100 | 100 | 100 | 100 | |
    storage-bucket.js | 100 | 93.75 | 100 | 100 | |
    storage-file.js | 98.11 | 91.67 | 100 | 98.11 | 52 |
    storage-reference.js | 83.33 | 100 | 50 | 83.33 |... 62,63,67,68 |
    storage.js | 100 | 83.33 | 100 | 100 | |
    timestamp.js | 100 | 100 | 100 | 100 | |
    user.js | 98.21 | 97.06 | 100 | 99.1 | 136 |
    utils.js | 98.09 | 94.17 | 100 | 98.7 | 26,50 |
    validators.js | 100 | 100 | 100 | 100 | |
    write-result.js | 100 | 100 | 100 | 100 | |
    ---------------------------------------|----------|----------|----------|----------|----------------|
    All files | 93.58 | 83.32 | 90.7 | 93.86 | |
    ---------------------------------------|----------|----------|----------|----------|----------------|


    =============================== Coverage summary ===============================
    Statements : 93.58% ( 2290/2447 ), 2 ignored
    Branches : 83.32% ( 884/1061 ), 1 ignored
    Functions : 90.7% ( 478/527 ), 1 ignored
    Lines : 93.86% ( 2263/2411 )
    ================================================================================
    [11:00:53] Finished '<anonymous>' after 2.88 s
    [11:00:53] Finished 'test' after 3.69 s