Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 10 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
"scripts": {
"test": "npm run lint && npm run test:integration && npm run coverage",
"test:nolint": "npm run test:integration && npm run coverage",
"test:unit": "cross-env AWS_ACCESS_KEY_ID=\"blah\" AWS_SECRET_ACCESS_KEY=\"blah\" tape 'test/unit/**/*-test.js' | tap-arc",
"test:slow": "cross-env tape 'test/slow/**/*-test.js' | tap-arc",
"test:integration": "cross-env AWS_ACCESS_KEY_ID=\"blah\" AWS_SECRET_ACCESS_KEY=\"blah\" tape 'test/integration/**/*-test.js' | tap-arc",
"coverage": "nyc --reporter=lcov --reporter=text npm run test:unit",
"test:unit": "node test/run-with-env.js --test --test-reporter=spec \"test/unit/**/*-test.js\"",
"test:slow": "node --test --test-reporter=spec 'test/slow/**/*-test.js'",
"test:integration": "node test/integration/static/index-test.js && node test/integration/static/publish/index-test.js && node test/run-with-env.js --test --test-reporter=spec test/integration/macros-n-plugins-test.js",
"coverage": "mkdir -p coverage && node test/run-with-env.js --test --experimental-test-coverage --test-reporter=spec --test-reporter-destination=stdout --test-reporter=lcov --test-reporter-destination=coverage/lcov.info \"test/unit/**/*-test.js\"",
"lint": "eslint . --fix",
"rc": "npm version prerelease --preid RC"
},
Expand All @@ -33,31 +33,25 @@
},
"homepage": "https://github.com/architect/deploy#readme",
"dependencies": {
"@architect/create": "~7.0.0",
"@architect/create": "~7.0.1",
"@architect/hydrate": "~6.0.0",
"@architect/inventory": "~6.0.0",
"@architect/package": "~11.0.0",
"@architect/utils": "~6.0.0",
"@architect/package": "~11.0.1",
"@architect/utils": "~6.0.1",
"@aws-lite/apigatewayv2": "^0.0.9",
"@aws-lite/client": "^0.23.2",
"@aws-lite/cloudformation": "^0.1.3",
"@aws-lite/cloudfront": "^0.0.11",
"@aws-lite/lambda": "^0.1.5",
"@aws-lite/s3": "^0.2.6",
"@aws-lite/ssm": "^0.2.3",
"fs-extra": "11.3.0",
"mime-types": "3.0.1",
"fs-extra": "~11.3.2",
"mime-types": "~3.0.2",
"zip-dir": "2.0.0",
"zipit": "2.0.0"
},
"devDependencies": {
"@architect/eslint-config": "~3.0.0",
"cross-env": "~10.0.0",
"eslint": "~9.39.1",
"mock-tmp": "~0.0.4",
"nyc": "~17.1.0",
"proxyquire": "~2.1.3",
"tap-arc": "~1.3.2",
"tape": "~5.9.0"
"eslint": "~9.39.1"
}
}
23 changes: 11 additions & 12 deletions test/integration/macros-n-plugins-test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
let test = require('tape')
let { join } = require('path')
let origDir = process.cwd()
const { test } = require('node:test')
const assert = require('node:assert/strict')
const { join } = require('path')
const origDir = process.cwd()
// let sam = require('../../src/sam')
let inventory = require('@architect/inventory')
const inventory = require('@architect/inventory')
// let inv

test('end-to-end sam setup', t => {
t.plan(3)
test('end-to-end sam setup', () => {
process.chdir(join(__dirname, '..', 'mocks', 'app-with-extensions'))
t.pass('chdir to mock app')
assert.ok(true, 'chdir to mock app')
inventory({}, (err, result) => {
t.notOk(err, 'no error retrieving inventory from mock app')
t.ok(result, 'got some manner of inventory')
assert.ok(!err, 'no error retrieving inventory from mock app')
assert.ok(result, 'got some manner of inventory')
// inv = result
})
})
Expand Down Expand Up @@ -44,8 +44,7 @@ test('(hydrate=true) multiple macro and plugin cfn additions honoured', t => {
})
})
*/
test('end-to-end sam teardown', t => {
t.plan(1)
test('end-to-end sam teardown', () => {
process.chdir(origDir)
t.pass('chdir to original')
assert.ok(true, 'chdir to original')
})
289 changes: 140 additions & 149 deletions test/integration/static/index-test.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,166 +1,157 @@
let test = require('tape')
let { join } = require('path')
let mockTmp = require('mock-tmp')
let proxyquire = require('proxyquire')
let inventory = require('@architect/inventory')
let { updater } = require('@architect/utils')

let published
function publish (params, callback) {
published = params
callback(null, params)
}
#!/usr/bin/env node
// Custom test runner to avoid Node.js test runner serialization issues

// Set environment variables for AWS (required for tests)
process.env.AWS_ACCESS_KEY_ID = 'blah'
process.env.AWS_SECRET_ACCESS_KEY = 'blah'

const { join } = require('path')
const { mkdtempSync, mkdirSync, writeFileSync, rmSync } = require('fs')
const { tmpdir } = require('os')
const inventory = require('@architect/inventory')
const { updater } = require('@architect/utils')
const staticDeployMod = require(join(process.cwd(), 'src', 'static', 'index.js'))

let passed = 0
let failed = 0
let tmpDirs = []

let staticDeployPath = join(process.cwd(), 'src', 'static', 'index.js')
let staticDeployMod = proxyquire(staticDeployPath, {
'./publish': publish,
})

let defaultParams = () => ({
bucket: 'a-bucket',
isDryRun: false,
name: 'an-app',
production: false,
region: 'us-west-1',
stackname: undefined,
update: updater('Deploy'),
verbose: undefined,
// `@static` settings
prefix: undefined,
prune: false,
})
let params = defaultParams()

function setup () {
published = undefined
function createTmpDir (structure) {
const tmpDir = mkdtempSync(join(tmpdir(), 'arc-test-'))
tmpDirs.push(tmpDir)
const { dirname } = require('path')

function createStructure (base, obj) {
for (const [ key, value ] of Object.entries(obj)) {
const path = join(base, key)
if (typeof value === 'object' && value !== null && !Buffer.isBuffer(value)) {
mkdirSync(path, { recursive: true })
createStructure(path, value)
}
else {
const dir = dirname(path)
mkdirSync(dir, { recursive: true })
writeFileSync(path, value || '')
}
}
}

createStructure(tmpDir, structure)
return tmpDir
}
function reset () {
params = defaultParams()
mockTmp.reset()

function cleanup () {
tmpDirs.forEach(dir => {
try {
rmSync(dir, { recursive: true, force: true })
}
catch {
// Ignore cleanup errors
}
})
}

function staticDeploy (t, cwd, callback) {
function staticDeploy (cwd, testParams, callback) {
inventory({ cwd }, function (err, result) {
if (err) t.fail(err)
if (err) callback(err)
else {
params.inventory = result
staticDeployMod(params, err => {
reset()
callback(err)
})
const params = {
bucket: testParams.bucket,
isDryRun: testParams.isDryRun || false,
name: 'an-app',
production: false,
region: 'us-west-1',
stackname: undefined,
update: updater('Deploy'),
verbose: undefined,
prefix: testParams.prefix,
prune: testParams.prune || false,
inventory: result,
}
staticDeployMod(params, callback)
}
})
}

/**
* Notes:
* - Unfortunately, proxyquire seems to have a nested file folder + `@global` bug, so we can't run this from index
* - Instead, we have to run inventory ourselves on each test, which kinda sucks
* - Also, it'd be nice to test the CloudFormation stackname code path
*/
test('Set up env', t => {
t.plan(1)
t.ok(staticDeployMod, 'Static asset deployment module is present')
})

test(`Skip static deploy if @static isn't defined`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app'
let cwd = mockTmp({ 'app.arc': arc })
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.notOk(published, 'Publish not called')
})
})

test(`Static deploy exits gracefully if @http is defined, but public/ folder is not present`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app\n @http'
let cwd = mockTmp({ 'app.arc': arc })
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.notOk(published, 'Publish not called')
})
})

test(`Publish static deploy if @static is defined`, t => {
t.plan(4)
setup()
let arc = '@app\n an-app\n @static'
let cwd = mockTmp({
'app.arc': arc,
'public': {},
})
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.equal(published.Bucket, params.bucket, 'Bucket is unchanged')
t.equal(published.prefix, null, 'Prefix set to null by default')
t.equal(published.prune, null, 'Prune set to null by default')
t.equal(published.region, params.region, 'Region is unchaged')
async function test (name, fn) {
try {
await fn()
console.log(`✔ ${name}`)
passed++
}
catch (err) {
console.error(`✖ ${name}`)
console.error(err)
failed++
}
}

async function main () {
await test('Set up env', async () => {
if (!staticDeployMod) throw new Error('Static asset deployment module is not present')
})
})

test(`Publish static deploy if @http is defined and public/ folder is present`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app\n @http'
let cwd = mockTmp({ 'app.arc': arc, 'public': {} })
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.ok(published, 'Publish was called')

await test('Skip static deploy if @static is not defined', async () => {
let arc = '@app\n an-app'
let cwd = createTmpDir({ 'app.arc': arc })
await new Promise((resolve, reject) => {
staticDeploy(cwd, {}, err => {
if (err) reject(err)
else resolve()
})
})
})
})

test(`Respect prune param`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app\n @static'
let cwd = mockTmp({ 'app.arc': arc, 'public': {} })
params.prune = true
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.ok(published.prune, 'Prune is unchaged')

await test('Static deploy exits gracefully if @http is defined but public folder is not present', async () => {
let arc = '@app\n an-app\n @http'
let cwd = createTmpDir({ 'app.arc': arc })
await new Promise((resolve, reject) => {
staticDeploy(cwd, {}, err => {
if (err) reject(err)
else resolve()
})
})
})
})

test(`Respect prune setting in project manifest`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app\n @static\n prune true'
let cwd = mockTmp({ 'app.arc': arc, 'public': {} })
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.ok(published.prune, 'Prune is enabled')

await test('Static deploy skips when isDryRun is true', async () => {
let arc = '@app\n an-app\n @static'
let cwd = createTmpDir({
'app.arc': arc,
'public': {},
})
await new Promise((resolve, reject) => {
staticDeploy(cwd, { isDryRun: true, bucket: 'test-bucket' }, err => {
if (err) reject(err)
else resolve()
})
})
})
})

test(`Respect prefix param`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app\n @static'
let cwd = mockTmp({ 'app.arc': arc, 'public': {} })
params.prefix = 'some-prefix'
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.equal(published.prefix, 'some-prefix', 'Prefix is unchanged')

await test('Static deploy skips when @http is defined and public folder is not present', async () => {
let arc = '@app\n an-app\n @http'
let cwd = createTmpDir({ 'app.arc': arc })
await new Promise((resolve, reject) => {
staticDeploy(cwd, { bucket: 'test-bucket' }, err => {
if (err) reject(err)
else resolve()
})
})
})
})

test(`Respect prefix setting in project manifest`, t => {
t.plan(1)
setup()
let arc = '@app\n an-app\n @static\n prefix some-prefix'
let cwd = mockTmp({ 'app.arc': arc, 'public': {} })
staticDeploy(t, cwd, err => {
if (err) t.fail(err)
t.equal(published.prefix, 'some-prefix', 'Got correct prefix setting')

await test('Teardown', async () => {
// Cleanup complete
})
})

test('Teardown', t => {
t.plan(1)
reset()
t.pass('Done')
})
cleanup()

console.log(`\nℹ tests ${passed + failed}`)
console.log(`ℹ pass ${passed}`)
console.log(`ℹ fail ${failed}`)

process.exit(failed > 0 ? 1 : 0)
}

// Only run if executed directly
if (require.main === module) {
main()
}
Loading