Skip to content

Commit 7245bcc

Browse files
authored
Merge pull request #254 from UnitedIncome/non-bats-tests
First pass at tape tests instead of bats tests
2 parents a42eee3 + eb8cc11 commit 7245bcc

File tree

7 files changed

+172
-38
lines changed

7 files changed

+172
-38
lines changed

appveyor.yml

+9-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
version: '{build}'
2-
init:
3-
- ps: >-
4-
Install-Product node 6
5-
6-
npm i -g serverless
7-
build: off
8-
test_script:
9-
- cmd: >-
10-
cd example
11-
12-
npm i
13-
14-
sls package --pythonBin=c:/python36/python.exe
1+
version: '{build}'
2+
init:
3+
- ps: npm i -g serverless
4+
build: off
5+
test_script:
6+
- cmd: >-
7+
npm i
8+
9+
node test.js

index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ class ServerlessPythonRequirements {
3434
invalidateCaches: false,
3535
fileName: 'requirements.txt',
3636
usePipenv: true,
37-
pythonBin: this.serverless.service.provider.runtime || 'python',
37+
pythonBin:
38+
process.platform === 'win32'
39+
? 'python.exe'
40+
: this.serverless.service.provider.runtime || 'python',
3841
dockerizePip: false,
3942
dockerSsh: false,
4043
dockerImage: null,

lib/pip.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ function installRequirements(targetFolder, serverless, options) {
274274
* @return {string}
275275
*/
276276
function dockerPathForWin(options, path) {
277-
if (process.platform === 'win32' && options.dockerizePip) {
277+
if (process.platform === 'win32') {
278278
return `"${path.replace(/\\/g, '/')}"`;
279279
} else if (process.platform === 'win32' && !options.dockerizePip) {
280280
return path;

package.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@
3838
"main": "index.js",
3939
"bin": {},
4040
"scripts": {
41-
"test": "bats test.bats",
41+
"test": "node test.js && bats test.bats",
4242
"lint": "eslint *.js lib/*.js && prettier -l index.js lib/*.js || (echo need formatting ; exit 1)",
43-
"format": "prettier --write index.js lib/*.js"
43+
"format": "prettier --write index.js lib/*.js test.js"
4444
},
4545
"devDependencies": {
4646
"eslint": "*",
47-
"prettier": "*"
47+
"prettier": "*",
48+
"cross-spawn": "*",
49+
"deasync-promise": "*",
50+
"tape": "*"
4851
},
4952
"dependencies": {
5053
"appdirectory": "^0.1.0",

test.bats

+15-18
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,15 @@ setup() {
1818

1919
teardown() {
2020
rm -rf puck puck2 puck3 node_modules .serverless .requirements.zip .requirements-cache \
21-
foobar package-lock.json serverless-python-requirements-*.tgz
22-
if [ -f serverless.yml.bak ]; then mv serverless.yml.bak serverless.yml; fi
23-
if [ -f slimPatterns.yml ]; then rm -f slimPatterns.yml; fi
24-
if [ -d "${USR_CACHE_DIR}" ] ; then
25-
rm -Rf "${USR_CACHE_DIR}"
26-
fi
21+
foobar package-lock.json serverless.yml.bak slimPatterns.yml "${USR_CACHE_DIR}"
22+
serverless-python-requirements-*.tgz
23+
git checkout serverless.yml
2724
cd ../..
2825
if [ -d "tests/base with a space" ] ; then
2926
rm -Rf "tests/base with a space"
3027
fi
3128
}
3229

33-
@test "py3.6 supports custom file name with fileName option" {
34-
cd tests/base
35-
npm i $(npm pack ../..)
36-
docker &> /dev/null || skip "docker not present"
37-
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
38-
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n fileName: puck/' serverless.yml
39-
echo "requests" > puck
40-
sls package
41-
ls .serverless/requirements/requests
42-
! ls .serverless/requirements/flask
43-
}
44-
4530
@test "py3.6 can package flask with default options" {
4631
cd tests/base
4732
npm i $(npm pack ../..)
@@ -591,3 +576,15 @@ teardown() {
591576
unzip .serverless/sls-py-req-test.zip -d puck
592577
ls puck/flask
593578
}
579+
580+
@test "py3.6 supports custom file name with fileName option" {
581+
cd tests/base
582+
npm i $(npm pack ../..)
583+
docker &> /dev/null || skip "docker not present"
584+
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
585+
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n fileName: puck/' serverless.yml
586+
echo "requests" > puck
587+
sls package
588+
ls .serverless/requirements/requests
589+
! ls .serverless/requirements/flask
590+
}

test.js

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
const crossSpawn = require('cross-spawn');
2+
const deasync = require('deasync-promise');
3+
const glob = require('glob-all');
4+
const JSZip = require('jszip');
5+
const tape = require('tape');
6+
const { removeSync, readFileSync } = require('fs-extra');
7+
const { sep } = require('path');
8+
9+
const { getUserCachePath } = require('./lib/shared');
10+
11+
const initialWorkingDir = process.cwd();
12+
13+
const mkCommand = cmd => (args, options = {}) => {
14+
const { error, stdout, stderr, status } = crossSpawn.sync(
15+
cmd,
16+
args,
17+
Object.assign(
18+
{
19+
env: Object.assign(
20+
process.env,
21+
{ SLS_DEBUG: 't' },
22+
process.env.CI ? { LC_ALL: 'C.UTF-8', LANG: 'C.UTF-8' } : {}
23+
)
24+
},
25+
options
26+
)
27+
);
28+
if (error) throw error;
29+
if (status) {
30+
console.error(stdout.toString()); // eslint-disable-line no-console
31+
console.error(stderr.toString()); // eslint-disable-line no-console
32+
throw new Error(`${cmd} failed with status code ${status}`);
33+
}
34+
return stdout && stdout.toString().trim();
35+
};
36+
const sls = mkCommand('sls');
37+
const git = mkCommand('git');
38+
const npm = mkCommand('npm');
39+
40+
const setup = () => {
41+
removeSync(getUserCachePath());
42+
};
43+
44+
const teardown = () => {
45+
[
46+
'puck',
47+
'puck2',
48+
'puck3',
49+
'node_modules',
50+
'.serverless',
51+
'.requirements.zip',
52+
'.requirements-cache',
53+
'foobar',
54+
'package-lock.json',
55+
'slimPatterns.yml',
56+
'serverless.yml.bak',
57+
getUserCachePath(),
58+
...glob.sync('serverless-python-requirements-*.tgz')
59+
].map(path => removeSync(path));
60+
git(['checkout', 'serverless.yml']);
61+
process.chdir(initialWorkingDir);
62+
removeSync('tests/base with a space');
63+
};
64+
65+
const test = (desc, func) =>
66+
tape.test(desc, t => {
67+
setup();
68+
try {
69+
func(t);
70+
} finally {
71+
teardown();
72+
}
73+
});
74+
75+
const getPythonBin = (version = 3) => {
76+
if (![2, 3].includes(version)) throw new Error('version must be 2 or 3');
77+
if (process.platform === 'win32')
78+
return `c:/python${version === 2 ? '27' : '36'}-x64/python.exe`;
79+
else return version === 2 ? 'python2.7' : 'python3.6';
80+
};
81+
82+
const listZipFiles = filename =>
83+
Object.keys(deasync(new JSZip().loadAsync(readFileSync(filename))).files);
84+
85+
test('default pythonBin can package flask with default options', t => {
86+
process.chdir('tests/base');
87+
const path = npm(['pack', '../..']);
88+
npm(['i', path]);
89+
sls(['package']);
90+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
91+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
92+
t.end();
93+
});
94+
95+
test('py3.6 can package flask with default options', t => {
96+
process.chdir('tests/base');
97+
const path = npm(['pack', '../..']);
98+
npm(['i', path]);
99+
sls([`--pythonBin=${getPythonBin(3)}`, 'package']);
100+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
101+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
102+
t.end();
103+
});
104+
105+
test('py3.6 can package flask with zip option', t => {
106+
process.chdir('tests/base');
107+
const path = npm(['pack', '../..']);
108+
npm(['i', path]);
109+
sls([`--pythonBin=${getPythonBin(3)}`, '--zip=true', 'package']);
110+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
111+
t.true(
112+
zipfiles.includes('.requirements.zip'),
113+
'zipped requirements are packaged'
114+
);
115+
t.true(zipfiles.includes(`unzip_requirements.py`), 'unzip util is packaged');
116+
t.false(
117+
zipfiles.includes(`flask${sep}__init__.py`),
118+
"flask isn't packaged on its own"
119+
);
120+
t.end();
121+
});
122+
123+
test('py3.6 can package flask with slim option', t => {
124+
process.chdir('tests/base');
125+
const path = npm(['pack', '../..']);
126+
npm(['i', path]);
127+
sls([`--pythonBin=${getPythonBin(3)}`, '--slim=true', 'package']);
128+
const zipfiles = listZipFiles('.serverless/sls-py-req-test.zip');
129+
t.true(zipfiles.includes(`flask${sep}__init__.py`), 'flask is packaged');
130+
t.deepEqual(
131+
zipfiles.filter(filename => filename.endsWith('.pyc')),
132+
[],
133+
'no pyc files packaged'
134+
);
135+
t.end();
136+
});

tests/base/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
"author": "",
1010
"license": "ISC",
1111
"dependencies": {
12-
"serverless-python-requirements": "file:serverless-python-requirements-4.2.1.tgz"
12+
"serverless-python-requirements": "file:serverless-python-requirements-4.2.4.tgz"
1313
}
1414
}

0 commit comments

Comments
 (0)