testcontext

package
v42.0.0-...-56f38d9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2017 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package testcontext helps you bootstrap test scenarios very effectively.

Take a look at the

NewContext()

function to learn how to use this package.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DeferredCreationFunc

type DeferredCreationFunc func(ctx *TestContext, idx int)

A DeferredCreationFunc acts as a generic callback to the various entity creation functions (e.g. Identities(), Spaces(), etc.). The current test context is given with the ctx argument and the position of the object that will be created next is indicated by the index idx. That index can be used to look up e.g. a space with

s := ctx.Spaces[idx]

That space s will be a ready-to-create space object on that you can modify to your liking.

Notice that when you lookup objects in the test context, you can only safely access those object on which the entity depends, because those are guaranteed to be already created. For example when you try to access a work item type from a deferred space creation callback, it will not be very useful:

NewContext(t, db, WorkItemTypes(1), Spaces(1, func(ctx *TestContext, idx int){
    witID := ctx.WorkItems[0].ID // this will not give you a uuid.Nil
}))

On the other hand, you can safely lookup the space ID when you're in the deferred work item creation callback:

NewContext(t, db, WorkItemTypes(1), Spaces(1, func(ctx *TestContext, idx int){
    witID := ctx.WorkItems[0].ID // this will not give you a uuid.Nil
}))

Notice that you can do all kinds of distribution related functions in a deferred creation function. For example, you can control which identity owns a space or define what work item type each work item shall have. If not otherwise specified (e.g. as for WorkItemLinks()) we use a straight forward approach. So for example if you write

NewContext(t, db, Identities(7), Spaces(100))

then we will create 10 identites and 100 spaces and the owner of all spaces will be identified with the ID of the first identity:

ctx.Identities[0].ID

If you want a different distribution, you can create your own deferred creation function (see Identities() for an example).

If you for some error reason you want your test context creation to fail you can use the ctx.T test instance:

NewContext(t, db, Identities(100, func(ctx *TestContext, idx int){
    ctx.T.Fatal("some test failure reason")
}))

func Topology

func Topology(topology string) DeferredCreationFunc

Topology ensures that all created link types will have the given topology type.

func TopologyDependency

func TopologyDependency() DeferredCreationFunc

TopologyDependency ensures that all created link types will have the "dependency" topology type.

func TopologyDirectedNetwork

func TopologyDirectedNetwork() DeferredCreationFunc

TopologyDirectedNetwork ensures that all created link types will have the "directed network" topology type.

func TopologyNetwork

func TopologyNetwork() DeferredCreationFunc

TopologyNetwork ensures that all created link types will have the "network" topology type.

func TopologyTree

func TopologyTree() DeferredCreationFunc

TopologyTree ensures that all created link types will have the "tree" topology type.

type RecipeFunction

type RecipeFunction func(ctx *TestContext)

A RecipeFunction ... TODO(kwk): document me

func Areas

func Areas(n int, fns ...DeferredCreationFunc) RecipeFunction

Areas tells the test context to create at least n area objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Spaces(1)

but with NewContextIsolated(), no other objects will be created.

func Codebases

func Codebases(n int, fns ...DeferredCreationFunc) RecipeFunction

Codebases tells the test context to create at least n codebase objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Spaces(1)

but with NewContextIsolated(), no other objects will be created.

func Comments

func Comments(n int, fns ...DeferredCreationFunc) RecipeFunction

Comments tells the test context to create at least n comment objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Identities(1)
WorkItems(1)

but with NewContextIsolated(), no other objects will be created.

func Identities

func Identities(n int, fns ...DeferredCreationFunc) RecipeFunction

Identities tells the test context to create at least n identity objects.

If called multiple times with differently n's, the biggest n wins. All deferred creation functions fns from all calls will be respected when creating the test context.

Here's an example how you can create 42 identites and give them a numbered user name like "John Doe 0", "John Doe 1", and so forth:

Identities(42, func(ctx *TestContext, idx int){
    ctx.Identities[idx].Username = "Jane Doe " + strconv.FormatInt(idx, 10)
})

Notice that the index idx goes from 0 to n-1 and that you have to manually lookup the object from the test context. The identity object referenced by

ctx.Identities[idx]

is guaranteed to be ready to be used for creation. That means, you don't necessarily have to touch it to avoid unique key violation for example. This is totally optional.

func Iterations

func Iterations(n int, fns ...DeferredCreationFunc) RecipeFunction

Iterations tells the test context to create at least n iteration objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Spaces(1)

but with NewContextIsolated(), no other objects will be created.

func Spaces

func Spaces(n int, fns ...DeferredCreationFunc) RecipeFunction

Spaces tells the test context to create at least n space objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Identities(1)

but with NewContextIsolated(), no other objects will be created.

func WorkItemLinkCategories

func WorkItemLinkCategories(n int, fns ...DeferredCreationFunc) RecipeFunction

WorkItemLinkCategories tells the test context to create at least n work item link category objects. See also the Identities() function for more general information on n and fns.

No other objects will be created.

func WorkItemLinkTypes

func WorkItemLinkTypes(n int, fns ...DeferredCreationFunc) RecipeFunction

WorkItemLinkTypes tells the test context to create at least n work item link type objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Spaces(1)
WorkItemLinkCategories(1)

but with NewContextIsolated(), no other objects will be created.

We've created these helper functions that you should have a look at if you want to implement your own re-usable deferred creation functions:

TopologyNetwork()
TopologyDirectedNetwork()
TopologyDependency()
TopologyTree()
Topology(topology string) // programmatically set the topology

The topology functions above are neat because you don't have to write a full callback function yourself.

By default a call to

WorkItemLinkTypes(1)

equals

WorkItemLinkTypes(1, TopologyTree())

because we automatically set the topology for each link type to be "tree".

func WorkItemLinks(n int, fns ...DeferredCreationFunc) RecipeFunction

WorkItemLinks tells the test context to create at least n work item link objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

WorkItemLinkTypes(1)
WorkItems(2*n)

but with NewContextIsolated(), no other objects will be created.

Notice, that we will create two times the number of work items of your requested links. The way those links will be created can for sure be influenced using a deferred creation function; but by default we create each link between two distinct work items. That means, no link will include the same work item.

func WorkItemTypes

func WorkItemTypes(n int, fns ...DeferredCreationFunc) RecipeFunction

WorkItemTypes tells the test context to create at least n work item type objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Spaces(1)

but with NewContextIsolated(), no other objects will be created.

The work item type that we create for each of the n instances is always the same and it tries to be compatible with the planner item work item type by specifying the same fields.

func WorkItems

func WorkItems(n int, fns ...DeferredCreationFunc) RecipeFunction

WorkItems tells the test context to create at least n work item objects. See also the Identities() function for more general information on n and fns.

When called in NewContext() this function will call also call

Spaces(1)
WorkItemTypes(1)
Identities(1)

but with NewContextIsolated(), no other objects will be created.

Notice that the Number field of a work item is only set after the work item has been created, so any changes you make to

ctx.WorkItems[idx].Number

will have no effect.

type TestContext

type TestContext struct {

	// Use this test reference in deferred creation function in order let the
	// test context creation fail.
	T *testing.T

	Identities             []*account.Identity          // Itentities (if any) that were created for this test context.
	Iterations             []*iteration.Iteration       // Iterations (if any) that were created for this test context.
	Areas                  []*area.Area                 // Areas (if any) that were created for this test context.
	Spaces                 []*space.Space               // Spaces (if any) that were created for this test context.
	Codebases              []*codebase.Codebase         // Codebases (if any) that were created for this test context.
	WorkItems              []*workitem.WorkItem         // Work items (if any) that were created for this test context.
	Comments               []*comment.Comment           // Comments (if any) that were created for this test context.
	WorkItemTypes          []*workitem.WorkItemType     // Work item types (if any) that were created for this test context.
	WorkItemLinkTypes      []*link.WorkItemLinkType     // Work item link types (if any) that were created for this test context.
	WorkItemLinkCategories []*link.WorkItemLinkCategory // Work item link categories (if any) that were created for this test context.
	WorkItemLinks          []*link.WorkItemLink         // Work item links (if any) that were created for this test context.
	// contains filtered or unexported fields
}

A TestContext object is the result of a call to

NewContext()

or

NewContextIsolated()

Don't create one on your own!

func NewContext

func NewContext(t *testing.T, db *gorm.DB, recipeFuncs ...RecipeFunction) *TestContext

NewContext will create a test context by executing the recipies from the given recipe functions. If recipeFuncs is empty, nothing will happen. If there's an error during the setup, the given test t will fail.

For example

NewContext(t, db, Comments(100))

will create a work item (and everything required in order to create it) and author 100 comments for it. They will all be created by the same user if you don't tell the system to do it differently. For example, to create 100 comments from 100 different users we can do the following:

NewContext(t, db, Identities(100), Comments(100, func(ctx *TestContext, idx int){
    ctx.Comments[idx].Creator = ctx.Identities[idx].ID
}))

That will create 100 identities and 100 comments and for each comment we're using the ID of one of the identities that have been created earlier. There's one important observation to make with this example: there's an order to how entities get created in the test context. That order is basically defined by the number of dependencies that each entity has. For example an identity has no dependency, so it will be created first and then can be accessed safely by any of the other entity creation functions. A comment for example depends on a work item which itself depends on a work item type and a space. The NewContext function does take of recursively resolving those dependcies first.

If you just want to create 100 identities and 100 work items but don't care about resolving the dependencies automatically you can create the entities in isolation:

NewContextIsolated(t, db, Identities(100), Comments(100, func(ctx *TestContext, idx int){
    ctx.Comments[idx].Creator = ctx.Identities[idx].ID
    ctx.Comments[idx].ParentID = someExistingWorkItemID
}))

Notice that I manually have to specify the ParentID of the work comment then because we cannot automatically resolve to which work item we will attach the comment.

func NewContextIsolated

func NewContextIsolated(t *testing.T, db *gorm.DB, setupFuncs ...RecipeFunction) *TestContext

NewContextIsolated will create a test context by executing the recipies from the given recipe functions. If recipeFuncs is empty, nothing will happen. If there's an error during the setup, the given test t will fail.

The difference to the normal NewContext function is that we will only create those object that where specified in the recipeFuncs. We will not create any object that is normally demanded by an object. For example, if you call

NewContext(t, db, WorkItems(1))

you would (apart from other objects) get at least one work item AND a work item type because that is needed to create a work item. With

NewContextIsolated(t, db, Comments(2), WorkItems(1))

on the other hand, we will only create a work item, two comments for it, and nothing more. And for sure your test will fail if you do that because you need to specify a space ID and a work item type ID for the created work item:

NewContextIsolated(t, db, Comments(2), WorkItems(1, func(ctx *TestContext, idx int){
  ctx.WorkItems[idx].SpaceID = someExistingSpaceID
  ctx.WorkItems[idx].WorkItemType = someExistingWorkItemTypeID
}))

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL