feat: create stage

This commit is contained in:
wancat committed 2024-03-08 00:38:49 +08:00
1 parent 65ad72223b
commit 77fe2d37b3
11 files changed
+67 -18

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
import { IStage, ICommand } from './types'
import { Condition } from './condition/Condition'
export class Stage {
id: string
name: string
condition: Condition
constructor({ id, name, condition }: IStage) {
this.id = id
this.name = name
this.condition = new Condition(condition)
}
satisfies(command: ICommand): boolean {
return this.condition.match(command)
}
}
@@ -1,4 +1,4 @@
import { Command } from '../types.js'
import { ICommand } from '../types.js'
import { Matcher } from './Matcher.js'
export class CommandMatcher implements Matcher {
@@ -7,7 +7,7 @@ export class CommandMatcher implements Matcher {
this.matcher = new RegExp(command, flags)
}
match(command: Command): boolean {
match(command: ICommand): boolean {
return !!command.command && this.matcher.test(command.command)
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import {
Command,
ICommand,
ICondition,
IFileExistenceChecker,
FileExistenceInput,
@@ -30,7 +30,7 @@ export class Condition {
this.matchers.push(new ErrorMatcher(error)) // always check unexpected error
}
match(command: Command): boolean {
match(command: ICommand): boolean {
return this.matchers.every((matcher) => {
return matcher.match(command)
})
+2 -2
View File
@@ -1,5 +1,5 @@
import { Matcher } from './Matcher.js'
import { Command } from '../types.js'
import { ICommand } from '../types.js'
export class ErrorMatcher implements Matcher {
private matcher?: RegExp
@@ -9,7 +9,7 @@ export class ErrorMatcher implements Matcher {
}
}
match(command: Command): boolean {
match(command: ICommand): boolean {
if (!this.matcher) {
return !command.error
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { Command } from '../types.js'
import { ICommand } from '../types.js'
export interface Matcher {
match(command: Command): boolean
match(command: ICommand): boolean
}
+2 -2
View File
@@ -1,10 +1,10 @@
import { Command } from '../types.js'
import { ICommand } from '../types.js'
import { Matcher } from './Matcher.js'
export class NotMatcher implements Matcher {
constructor(private condition: Matcher) {}
match(command: Command): boolean {
match(command: ICommand): boolean {
return !this.condition.match(command)
}
}
+2 -2
View File
@@ -1,10 +1,10 @@
import { Command } from '../types.js'
import { ICommand } from '../types.js'
import { Matcher } from './Matcher.js'
export class OrMatcher implements Matcher {
constructor(private conditions: Matcher[]) {}
match(command: Command): boolean {
match(command: ICommand): boolean {
return this.conditions.some((condition) => condition.match(command))
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { Command } from '../types.js'
import { ICommand } from '../types.js'
import { Matcher } from './Matcher.js'
export class OutputMatcher implements Matcher {
@@ -7,7 +7,7 @@ export class OutputMatcher implements Matcher {
this.matcher = new RegExp(pattern, args)
}
match(command: Command): boolean {
match(command: ICommand): boolean {
return !!command.output && this.matcher.test(command.output.trim())
}
}
+2 -2
View File
@@ -1,10 +1,10 @@
import { Command } from '../types.js'
import { ICommand } from '../types.js'
import { Matcher } from './Matcher.js'
export class PwdMatcher implements Matcher {
constructor(private pwd: string) {}
match(command: Command): boolean {
match(command: ICommand): boolean {
return command.pwd === this.pwd
}
}
+8 -2
View File
@@ -1,4 +1,4 @@
export interface Command {
export interface ICommand {
command?: string
output?: string
error?: string
@@ -12,7 +12,7 @@ export interface ICondition {
pwd?: string
or?: ICondition[]
not?: ICondition
files: FileExistenceInput[]
files?: FileExistenceInput[]
}
export enum FileType {
@@ -32,3 +32,9 @@ export interface FileExistenceInput extends FileInput {
export interface IFileExistenceChecker {
exists(file: FileInput): Promise<boolean>
}
export interface IStage {
id: string
name: string
condition: ICondition
}
+25
View File
@@ -0,0 +1,25 @@
import { test, expect } from '@jest/globals'
import { Stage } from '../src/Stage'
test('check stage condition', () => {
const stage = new Stage({
id: 'stage1',
name: 'List the files using `ls`',
condition: {
command: 'ls',
pwd: '/home/user',
},
})
expect(
stage.satisfies({
command: 'ls',
pwd: '/home/user',
})
).toBe(true)
expect(
stage.satisfies({
command: 'ls',
pwd: '/home/user/Downloads',
})
).toBe(false)
})