Skip to content

Commit

Permalink
add support for multiple rules
Browse files Browse the repository at this point in the history
  • Loading branch information
bobvanderlinden committed Aug 24, 2018
1 parent b6659e7 commit fc866c3
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type ConditionConfig = {
}

export type Config = {
rules?: ConditionConfig[],
updateBranch: boolean,
deleteBranchAfterMerge: boolean,
mergeMethod: 'merge' | 'rebase' | 'squash'
Expand Down
20 changes: 19 additions & 1 deletion src/pull-request-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,23 @@ export function getPullRequestStatus (
conditions: Conditions,
pullRequestInfo: PullRequestInfo
): PullRequestStatus {
return getConditionResults(context.config, pullRequestInfo)
const globalConfig = context.config
const globalResults = getConditionResults(globalConfig, conditions, pullRequestInfo)
if (!getConclusion(globalResults)) {
return globalResults
}
return (globalConfig.rules || []).reduce<undefined | ConditionResults>((result, ruleConfig) => {
if (result !== undefined) {
return result
}
const ruleResult = getConditionResults(ruleConfig, conditions, pullRequestInfo)
if (getConclusion(ruleResult)) {
return ruleResult
}
return undefined
}, undefined) || globalResults
}

export function getConclusion (conditionResults: ConditionResults): boolean {
return Object.values(conditionResults).every(conditionResult => conditionResult.status === 'success')
}
15 changes: 13 additions & 2 deletions test/mock.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConditionConfig, defaultRuleConfig } from './../src/config'
import { Review, CheckRun, PullRequestReviewState } from './../src/github-models'
import { DeepPartial } from './../src/utils'
import { HandlerContext } from './../src/models'
Expand Down Expand Up @@ -68,13 +69,23 @@ export function createGithubApi (options?: DeepPartial<GitHubAPI>): GitHubAPI {
} as GitHubAPI
}

export function createConfig (options?: Partial<Config>): Config {
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
export type PartialConfig = {
rules?: Partial<ConditionConfig>[]
} & Partial<Omit<Config, 'rules'>>

export function createConfig (options?: PartialConfig): Config {
const rules = ((options || {}).rules || []).map(rule => ({
...defaultRuleConfig,
...rule
}))
return {
...defaultConfig,
minApprovals: {
MEMBER: 1
},
...options
...options,
rules
}
}

Expand Down
106 changes: 105 additions & 1 deletion test/pull-request-status.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ConditionResults, Conditions, conditions } from './../src/conditions/index'
import { getPullRequestStatus } from '../src/pull-request-status'
import { mapObject } from '../src/utils'
import { createHandlerContext, createPullRequestInfo } from './mock'
import { createHandlerContext, createPullRequestInfo, createConfig, approvedReview } from './mock'
import { ConditionResult } from '../src/condition'

const successConditionResults: ConditionResults = mapObject(conditions, (_) => ({ status: 'success' } as ConditionResult))
Expand All @@ -10,6 +10,12 @@ function createConditionsFromResults (conditionResults: ConditionResults) {
return mapObject(conditionResults, conditionResult => jest.fn(() => conditionResult))
}

function createConditions (overrideConditions: Partial<Conditions>): Conditions {
return {
...createConditionsFromResults(successConditionResults),
...overrideConditions
}
}

describe('pull request status', () => {
it('calls all conditions', () => {
Expand All @@ -23,5 +29,103 @@ describe('pull request status', () => {
expect(conditionFn).toHaveBeenCalledTimes(1)
}
})

it('returns success when all conditions and no configuration is defined', () => {
const successConditions = createConditionsFromResults(successConditionResults)
const results = getPullRequestStatus(
createHandlerContext(),
successConditions,
createPullRequestInfo()
)
expect(results).toEqual(successConditionResults)
})

it('returns fail when global config fails and a rule passes', () => {
const results = getPullRequestStatus(
createHandlerContext({
config: createConfig({
rules: [{
minApprovals: {
NONE: 0
}
}],
minApprovals: {
OWNER: 1
}
})
}),
createConditions({
minimumApprovals: conditions.minimumApprovals
}),
createPullRequestInfo({
reviews: {
nodes: [
approvedReview({
authorAssociation: 'MEMBER'
})
]
}
})
)

expect(results.minimumApprovals.status).toEqual('fail')
})

it('returns success when global config passes and there are no rules', () => {
const results = getPullRequestStatus(
createHandlerContext({
config: createConfig({
rules: [],
minApprovals: {
MEMBER: 1
}
})
}),
createConditions({
minimumApprovals: conditions.minimumApprovals
}),
createPullRequestInfo({
reviews: {
nodes: [
approvedReview({
authorAssociation: 'MEMBER'
})
]
}
})
)
expect(results.minimumApprovals.status).toEqual('success')
})

it('returns success when no global config and one rule and there are no rules', () => {
const results = getPullRequestStatus(
createHandlerContext({
config: createConfig({
rules: [{
minApprovals: {
OWNER: 1
}
}, {
minApprovals: {
MEMBER: 1
}
}]
})
}),
createConditions({
minimumApprovals: conditions.minimumApprovals
}),
createPullRequestInfo({
reviews: {
nodes: [
approvedReview({
authorAssociation: 'MEMBER'
})
]
}
})
)

expect(results.minimumApprovals.status).toEqual('success')
})
})

0 comments on commit fc866c3

Please sign in to comment.