Skip to content
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

Run full suite of tests, every time (most of the time) #246

Merged
merged 11 commits into from
Jul 1, 2018
30 changes: 17 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
sudo: required
os:
- linux
- osx
- linux
- osx
language: node_js
node_js:
- node
- '9'
- '8'
- '7'
- '6'
- node
- '9'
- '8'
- '7'
- '6'
cache:
directories:
- "$HOME/.npm"
before_install:
- npm install -g npm@latest
# Decrypt the .clasprc.json.enc file used for authentication for clasp commands
# Will not decrypt on PRs from forks.
- openssl aes-256-cbc -K $encrypted_0f9bbf7a60f4_key -iv $encrypted_0f9bbf7a60f4_iv
-in ./tests/.clasprc.json.enc -out .clasprc.json -d || true
- npm install -g npm@latest
install:
# npm-ci (https://docs.npmjs.com/cli/ci) is used for the install step instead
# of npm-install because it ensures that the package-lock.json is up to date
# of npm-install because it ensures that the package-lock.json is up to date
# with the package.json in order for the travis tests to pass.
- npm ci
- npm ci
before_script:
- npm run build
- npm run build
script:
- npm run lint
- npm run test
- npm run lint
- npm run test
after_success: npm run coverage
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,15 +343,15 @@ clasp <command>

(If you see build errors, run `sudo npm run build-fresh`)

#### Run Tests (experimental)

Change `describe.skip(...)` to `describe(...)` for relevant tests.
#### Run Tests

```sh
sudo npm run build;
npm run test
```

See `/tests/README.md` for more information.

#### Lint

- Use `npm run lint` to find common style errors.
Expand Down
2 changes: 2 additions & 0 deletions tests/.clasprc.json.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
�t�@�NM����.|9%� �M�mc)eJ�&���,nv�9��N����7=b����C,P8�O��A��T�,SЇ ��f�4wk�gn�<��2��p9p� �ץ�p�Y�d|K��Z(�xn�T(��"��g���={)3�(�y ��O���S��
�N�[��`�>���?���֫e�;b�� 2��w �P�A��OʣJ��P�� %����q�A- ��i ��AU�����q��%�U9#d�f���.0z[ 1
Expand Down
58 changes: 58 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Tests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a sentence here to describe what the testing situation is for clasp. Something like:

Many of clasp's CLI commands have unit tests that run the clasp command and asserts the std output and std error code is as expected.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Many of `clasp`'s CLI commands have unit tests that run the `clasp` command and asserts the std output and std error code is as expected.

These tests should ideally be run for every Pull Request, though due to the need to run `clasp login` before some commands, some tests are not run.

To run tests yourself, follow the __Local Configuration__ instructions.

## Local Configuration

1. Make sure you are logged in (`clasp login`).
1. Rebuild: `sudo npm run build`
1. Run `npm run test`

## Configuration using Travis

Travis (https://travis-ci.org/) is used to automatically build and run tests on `clasp`. Every version of `clasp` should pass the Travis build step before release.

Since Travis cannot `clasp login`, a `.clasprc.json` file is included that was created locally using `clasp login`.

It is encrypted as `.clasprc.json.enc` and then decrypted by Travis:

```openssl aes-256-cbc -K $encrypted_0f9bbf7a60f4_key -iv $encrypted_0f9bbf7a60f4_iv -in .clasprc.json.enc -out .clasprc.json -d || true```

Travis will not decrypt files on a Pull Request from a fork (see: https://docs.travis-ci.com/user/encrypting-files/).

There are complicated ways around this, see (https://blog.algolia.com/travis-encrypted-variables-external-contributions/) for ideas.

The command ends with ` || true` so Travis doesn't immediately fail on any PR.

## Test these commands and configs.

### Commands:
* [ ] clasp;
* [ ] clasp login';
* [ ] clasp login --no-localhost;
* [x] clasp logout;
* [x] clasp create "myTitle"
* [x] clasp create <untitled>
* [x] clasp list
* [x] clasp clone <scriptId>
* [x] clasp clone
* [x] clasp pull
* [x] clasp push
* [ ] echo '// test' >> index.js && clasp push
* [x] clasp open
* [ ] clasp deployments
* [ ] clasp deploy [version] [description]
* [ ] clasp redeploy <deploymentId> <version> <description>
* [ ] clasp version [description]
* [x] clasp versions
* [x] saveProjectId
* [x] getScriptURL
* [x] getFileType
* [x] getAPIFileType
### Configs
* [ ] .js and .gs files
* [ ] Ignored files
119 changes: 74 additions & 45 deletions tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { spawnSync } = require('child_process');
const TEST_CODE_JS = 'function test() { Logger.log(\'test\'); }';
const TEST_JSON = '{"timeZone": "America/New_York"}';
const CLASP = (os.type() === 'Windows_NT') ? 'clasp.cmd' : 'clasp';
const isPR = process.env.TRAVIS_PULL_REQUEST;

describe('Test help for each function', () => {
it('should output help for run command', () => {
Expand All @@ -28,7 +29,12 @@ describe('Test help for each function', () => {
});
});

describe.skip('Test clasp list function', () => {
describe('Test clasp list function', () => {
before(function() {
Copy link
Contributor

@grant grant Jul 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you extract this to a function?

function skipIfPR() {
  if (!Boolean(isPR)) return this.skip();
}
before(skipIfPR);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure this will work, Typescript is not a fan:

[ts] 'this' implicitly has type 'any' because it does not have a type annotation.

I'm not sure the best way to pass this through that makes it work.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, isPR is never a boolean, it's either an int like this PR is 246 or it is "false" (string)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, we can follow up in a different change.

if (isPR !== 'false') {
this.skip();
}
});
it('should list clasp projects correctly', () => {
const result = spawnSync(
CLASP, ['list'], { encoding: 'utf8' },
Expand All @@ -41,7 +47,12 @@ describe.skip('Test clasp list function', () => {
});
});

describe.skip('Test clasp create function', () => {
describe('Test clasp create function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should prompt for a project name correctly', () => {
spawnSync('rm', ['.clasp.json']);
const result = spawnSync(
Expand All @@ -59,7 +70,12 @@ describe.skip('Test clasp create function', () => {
});
});

describe.skip('Test clasp create <title> function', () => {
describe('Test clasp create <title> function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should create a new project named <title> correctly', () => {
spawnSync('rm', ['.clasp.json']);
const result = spawnSync(
Expand All @@ -70,7 +86,12 @@ describe.skip('Test clasp create <title> function', () => {
});
});

describe.skip('Test clasp clone <scriptId> function', () => {
describe('Test clasp clone <scriptId> function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should clone an existing project correctly', () => {
const settings = JSON.parse(fs.readFileSync('.clasp.json', 'utf8'));
fs.removeSync('.clasp.json');
Expand All @@ -93,7 +114,12 @@ describe.skip('Test clasp clone <scriptId> function', () => {
});
});

describe.skip('Test clasp pull function', () => {
describe('Test clasp pull function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should pull an existing project correctly', () => {
const result = spawnSync(
CLASP, ['pull'], { encoding: 'utf8' },
Expand All @@ -104,7 +130,12 @@ describe.skip('Test clasp pull function', () => {
});
});

describe.skip('Test clasp push function', () => {
describe('Test clasp push function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should push local project correctly', () => {
fs.removeSync('.claspignore');
fs.writeFileSync('Code.js', TEST_CODE_JS);
Expand All @@ -130,7 +161,12 @@ describe.skip('Test clasp push function', () => {
});
});

describe.skip('Test clasp status function', () => {
describe('Test clasp status function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
function setupTmpDirectory(filepathsAndContents: Array<{ file: string, data: string }>) {
fs.ensureDirSync('tmp');
const tmpdir = tmp.dirSync({ unsafeCleanup: true, dir: 'tmp/', keep: false }).name;
Expand Down Expand Up @@ -171,7 +207,12 @@ describe.skip('Test clasp status function', () => {
});
});

describe.skip('Test clasp open function', () => {
describe('Test clasp open function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should open a project correctly', () => {
const result = spawnSync(
CLASP, ['open'], { encoding: 'utf8' },
Expand All @@ -181,7 +222,12 @@ describe.skip('Test clasp open function', () => {
});
});

describe.skip('Test clasp deployments function', () => {
describe('Test clasp deployments function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should list deployments correctly', () => {
const result = spawnSync(
CLASP, ['deployments'], { encoding: 'utf8' },
Expand All @@ -191,7 +237,12 @@ describe.skip('Test clasp deployments function', () => {
});
});

describe.skip('Test clasp deploy function', () => {
describe('Test clasp deploy function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should deploy correctly', () => {
const result = spawnSync(
CLASP, ['deploy'], { encoding: 'utf8' },
Expand All @@ -201,7 +252,12 @@ describe.skip('Test clasp deploy function', () => {
});
});

describe.skip('Test clasp version and versions function', () => {
describe('Test clasp version and versions function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
let versionNumber = '';
it('should create new version correctly', () => {
const result = spawnSync(
Expand All @@ -221,7 +277,12 @@ describe.skip('Test clasp version and versions function', () => {
});
});

describe.skip('Test clasp clone function', () => {
describe('Test clasp clone function', () => {
before(function() {
if (isPR !== 'false') {
this.skip();
}
});
it('should prompt for which script to clone correctly', () => {
spawnSync('rm', ['.clasp.json']);
const result = spawnSync(
Expand Down Expand Up @@ -322,36 +383,4 @@ describe('Test clasp logout function', () => {
const dotExists = fs.existsSync('~/.clasprc.json');
expect(dotExists).to.equal(false);
});
});

/**
* TODO: Test these commands and configs.
*
* # Commands:
* [ ] clasp;
* [ ] clasp login';
* [ ] clasp login --no-localhost;
* [x] clasp logout;
* [x] clasp create "myTitle"
* [x] clasp create <untitled>
* [x] clasp list
* [x] clasp clone <scriptId>
* [x] clasp clone
* [x] clasp pull
* [x] clasp push
* [ ] echo '// test' >> index.js && clasp push
* [x] clasp open
* [ ] clasp deployments
* [ ] clasp deploy [version] [description]
* [ ] clasp redeploy <deploymentId> <version> <description>
* [ ] clasp version [description]
* [x] clasp versions
* [x] saveProjectId
* [x] getScriptURL
* [x] getFileType
* [x] getAPIFileType
*
* # Configs
* - .js and .gs files
* - Ignored files
*/
});