Skip to content

First pass at tape tests instead of bats tests #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 11, 2018
Merged
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
23 changes: 9 additions & 14 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
version: '{build}'
init:
- ps: >-
Install-Product node 6

npm i -g serverless
build: off
test_script:
- cmd: >-
cd example

npm i

sls package --pythonBin=c:/python36/python.exe
version: '{build}'
init:
- ps: npm i -g serverless
build: off
test_script:
- cmd: >-
npm i

node test.js
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class ServerlessPythonRequirements {
invalidateCaches: false,
fileName: 'requirements.txt',
usePipenv: true,
pythonBin: this.serverless.service.provider.runtime || 'python',
pythonBin:
process.platform === 'win32'
? 'python.exe'
: this.serverless.service.provider.runtime || 'python',
dockerizePip: false,
dockerSsh: false,
dockerImage: null,
Expand Down
2 changes: 1 addition & 1 deletion lib/pip.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ function installRequirements(targetFolder, serverless, options) {
* @return {string}
*/
function dockerPathForWin(options, path) {
if (process.platform === 'win32' && options.dockerizePip) {
if (process.platform === 'win32') {
return `"${path.replace(/\\/g, '/')}"`;
} else if (process.platform === 'win32' && !options.dockerizePip) {
return path;
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@
"main": "index.js",
"bin": {},
"scripts": {
"test": "bats test.bats",
"test": "node test.js && bats test.bats",
"lint": "eslint *.js lib/*.js && prettier -l index.js lib/*.js || (echo need formatting ; exit 1)",
"format": "prettier --write index.js lib/*.js"
"format": "prettier --write index.js lib/*.js test.js"
},
"devDependencies": {
"eslint": "*",
"prettier": "*"
"prettier": "*",
"cross-spawn": "*",
"deasync-promise": "*",
"tape": "*"
},
"dependencies": {
"appdirectory": "^0.1.0",
Expand Down
33 changes: 15 additions & 18 deletions test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,15 @@ setup() {

teardown() {
rm -rf puck puck2 puck3 node_modules .serverless .requirements.zip .requirements-cache \
foobar package-lock.json serverless-python-requirements-*.tgz
if [ -f serverless.yml.bak ]; then mv serverless.yml.bak serverless.yml; fi
if [ -f slimPatterns.yml ]; then rm -f slimPatterns.yml; fi
if [ -d "${USR_CACHE_DIR}" ] ; then
rm -Rf "${USR_CACHE_DIR}"
fi
foobar package-lock.json serverless.yml.bak slimPatterns.yml "${USR_CACHE_DIR}"
serverless-python-requirements-*.tgz
git checkout serverless.yml
cd ../..
if [ -d "tests/base with a space" ] ; then
rm -Rf "tests/base with a space"
fi
}

@test "py3.6 supports custom file name with fileName option" {
cd tests/base
npm i $(npm pack ../..)
docker &> /dev/null || skip "docker not present"
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n fileName: puck/' serverless.yml
echo "requests" > puck
sls package
ls .serverless/requirements/requests
! ls .serverless/requirements/flask
}

@test "py3.6 can package flask with default options" {
cd tests/base
npm i $(npm pack ../..)
Expand Down Expand Up @@ -591,3 +576,15 @@ teardown() {
unzip .serverless/sls-py-req-test.zip -d puck
ls puck/flask
}

@test "py3.6 supports custom file name with fileName option" {
cd tests/base
npm i $(npm pack ../..)
docker &> /dev/null || skip "docker not present"
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n fileName: puck/' serverless.yml
echo "requests" > puck
sls package
ls .serverless/requirements/requests
! ls .serverless/requirements/flask
}
136 changes: 136 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
const crossSpawn = require('cross-spawn');
const deasync = require('deasync-promise');
const glob = require('glob-all');
const JSZip = require('jszip');
const tape = require('tape');
const { removeSync, readFileSync } = require('fs-extra');
const { sep } = require('path');

const { getUserCachePath } = require('./lib/shared');

const initialWorkingDir = process.cwd();

const mkCommand = cmd => (args, options = {}) => {
const { error, stdout, stderr, status } = crossSpawn.sync(
cmd,
args,
Object.assign(
{
env: Object.assign(
process.env,
{ SLS_DEBUG: 't' },
process.env.CI ? { LC_ALL: 'C.UTF-8', LANG: 'C.UTF-8' } : {}
)
},
options
)
);
if (error) throw error;
if (status) {
console.error(stdout.toString()); // eslint-disable-line no-console
console.error(stderr.toString()); // eslint-disable-line no-console
throw new Error(`${cmd} failed with status code ${status}`);
}
return stdout && stdout.toString().trim();
};
const sls = mkCommand('sls');
const git = mkCommand('git');
const npm = mkCommand('npm');

const setup = () => {
removeSync(getUserCachePath());
};

const teardown = () => {
[
'puck',
'puck2',
'puck3',
'node_modules',
'.serverless',
'.requirements.zip',
'.requirements-cache',
'foobar',
'package-lock.json',
'slimPatterns.yml',
'serverless.yml.bak',
getUserCachePath(),
...glob.sync('serverless-python-requirements-*.tgz')
].map(path => removeSync(path));
git(['checkout', 'serverless.yml']);
process.chdir(initialWorkingDir);
removeSync('tests/base with a space');
};

const test = (desc, func) =>
tape.test(desc, t => {
setup();
try {
func(t);
} finally {
teardown();
}
});

const getPythonBin = (version = 3) => {
if (![2, 3].includes(version)) throw new Error('version must be 2 or 3');
if (process.platform === 'win32')
return `c:/python${version === 2 ? '27' : '36'}-x64/python.exe`;
else return version === 2 ? 'python2.7' : 'python3.6';
};

const listZipFiles = filename =>
Object.keys(deasync(new JSZip().loadAsync(readFileSync(filename))).files);

test('default pythonBin can package flask with default options', t => {
process.chdir('tests/base');
const path = npm(['pack', '../..']);
npm(['i', path]);
sls(['package']);
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
t.end();
});

test('py3.6 can package flask with default options', t => {
process.chdir('tests/base');
const path = npm(['pack', '../..']);
npm(['i', path]);
sls([`--pythonBin=${getPythonBin(3)}`, 'package']);
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
t.end();
});

test('py3.6 can package flask with zip option', t => {
process.chdir('tests/base');
const path = npm(['pack', '../..']);
npm(['i', path]);
sls([`--pythonBin=${getPythonBin(3)}`, '--zip=true', 'package']);
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
t.true(
zipfiles.includes('.requirements.zip'),
'zipped requirements are packaged'
);
t.true(zipfiles.includes(`unzip_requirements.py`), 'unzip util is packaged');
t.false(
zipfiles.includes(`flask${sep}__init__.py`),
"flask isn't packaged on its own"
);
t.end();
});

test('py3.6 can package flask with slim option', t => {
process.chdir('tests/base');
const path = npm(['pack', '../..']);
npm(['i', path]);
sls([`--pythonBin=${getPythonBin(3)}`, '--slim=true', 'package']);
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
t.deepEqual(
zipfiles.filter(filename => filename.endsWith('.pyc')),
[],
'no pyc files packaged'
);
t.end();
});
2 changes: 1 addition & 1 deletion tests/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"author": "",
"license": "ISC",
"dependencies": {
"serverless-python-requirements": "file:serverless-python-requirements-4.2.1.tgz"
"serverless-python-requirements": "file:serverless-python-requirements-4.2.4.tgz"
}
}