Skip to content

Commit

Permalink
chore: add jsconfig with folder alias and refactor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosdevpereira committed Oct 14, 2022
1 parent 633f0a6 commit 994604c
Show file tree
Hide file tree
Showing 16 changed files with 192 additions and 120 deletions.
12 changes: 12 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"baseUrl": "./",
"jsx": "preserve",
"paths": {
"@/*": ["src/*"],
"@tests/*": ["tests/*"]
}
},
"include": ["src/**/*.js", "tests/**/*.js"],
"exclude": ["node_modules", "dist"]
}
13 changes: 8 additions & 5 deletions src/Action.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ class Action {
return this;
}

async saveTestResults() {
await this.repository.addCommitComment(
this.commit.hash,
JSON.stringify(this.testResults)
);
}

async publishToCloudflare() {
const cloudflare = new Cloudflare(this.config.cloudflare);
const commitShortHash = this.commit.shortHash();
Expand All @@ -35,11 +42,7 @@ class Action {
const pullRequests = await this.repository.getPullRequests();

for (const pullRequest of pullRequests) {
await this.repository.commentPullRequest(
pullRequest,
this.testResults,
this.coverageReportUrl
);
await this.repository.commentPullRequest(pullRequest, this.coverageReportUrl);
}

return this;
Expand Down
17 changes: 10 additions & 7 deletions src/Framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ class Framework {
if (!SUPPORTED_TEST_FRAMEWORKS.includes(frameworkName)) {
throw new Error(
'Unsupported test framework selected. Valid options are: '
+ SUPPORTED_TEST_FRAMEWORKS.join(', ')
+ SUPPORTED_TEST_FRAMEWORKS.join(', ')
);
}

this.name = frameworkName;
this.testResults = '';
this.testResults = null;
}

/**
Expand All @@ -27,19 +27,22 @@ class Framework {
async runTests() {
const JEST_PATH = 'node --experimental-vm-modules ./node_modules/jest/bin/jest.js';
const JEST_FLAGS = '--no-cache --detectOpenHandles --coverage --json';
const RESULT_OUTPUT_FILE = `${COVERAGE_OUTPUT_FOLDER}/test-results.json`;

let results = '';
let testRunStats = '';
await exec(`${JEST_PATH} ${JEST_FLAGS}`, undefined, {
listeners: {
stdout: (data) => {
results += data.toString();
testRunStats += data.toString();
},
},
});

fs.writeFileSync(RESULT_OUTPUT_FILE, results);
this.testResults = JSON.parse(results);
const coverageSummary = fs.readFileSync(`${COVERAGE_OUTPUT_FOLDER}/coverage-summary.json`, 'utf-8');

this.testResults = {
stats: JSON.parse(testRunStats),
summary: JSON.parse(coverageSummary)
};

return this.testResults;
}
Expand Down
40 changes: 27 additions & 13 deletions src/Repository.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const github = require('@actions/github');
const Framework = require('./Framework');
const { BuildCommentBody } = require('./utils/buildComment');
const { GetReport, TotalPercentagesAverage } = require('./utils/getReports');
const { TotalPercentagesAverage } = require('./utils/getReports');

class Repository {
constructor(name, owner, config) {
Expand Down Expand Up @@ -40,7 +40,26 @@ class Repository {
return pullRequests;
}

async commentPullRequest(pullRequest, testResults, fullReportUrl) {
async addCommitComment(commitSha, comment) {
await this.github.rest.repos.createCommitComment({
owner: this.owner,
repo: this.name,
commit_sha: commitSha,
body: comment
});
}

async getCommitComment(commitSha) {
const comments = await this.github.rest.repos.listCommentsForCommit({
owner: this.owner,
repo: this.name,
commit_sha: commitSha
});

return comments.data[0].body;
}

async commentPullRequest(pullRequest, fullReportUrl) {
const { data: comments } = await this.github.rest.issues.listComments({
issue_number: pullRequest.number,
owner: this.owner,
Expand All @@ -50,27 +69,22 @@ class Repository {
return comment.user.id === 41_898_282;
});

const headResult = await GetReport({
reportUrl: `${fullReportUrl}/coverage-summary.json`,
});
const baseResult = await GetReport({
ignoreErrors: true,
reportUrl: `https://${pullRequest.baseBranchShortSha}.${this.config.cloudflare.baseUrl}/coverage-summary.json`,
retryCount: 0,
});
// TODO: This can be parallelized
const headResult = JSON.parse(await this.getCommitComment(pullRequest.headBranchSha));
const baseResult = JSON.parse(await this.getCommitComment(pullRequest.baseBranchSha));

const commentBody = await BuildCommentBody({
baseAvgPercentage: TotalPercentagesAverage(baseResult),
baseRef: pullRequest.baseRef,
baseShortHash: pullRequest.baseBranchShortSha,
baseTotals: baseResult.total,
baseTotals: baseResult.summary.total,
branchName: this.branch,
fullReportUrl,
hasBaseResults: Boolean(baseResult),
headAvgPercentage: TotalPercentagesAverage(headResult),
headShortHash: pullRequest.headBranchShortSha,
headTotals: headResult.total,
testResults,
headTotals: headResult.summary.total,
testResults: headResult.stats,
});

if (botComment) {
Expand Down
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ const GithubAction = require('./Action');
await Action.runTests();
core.endGroup();

core.startGroup('Saving test results...');
await Action.saveTestResults();
core.endGroup();

core.startGroup('Uploading to Cloudflare Pages...');
await Action.publishToCloudflare();
core.endGroup();
Expand Down
38 changes: 4 additions & 34 deletions src/utils/getReports.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
const core = require('@actions/core');
const { HttpClient } = require('@actions/http-client');

async function GetReport({ reportUrl, retryCount = 3, ignoreErrors = false } = {}) {
try {
const http = new HttpClient();
const res = await http.get(reportUrl);
const body = await res.readBody();

return JSON.parse(body);
} catch (error) {
if (retryCount === 0) {
if (!ignoreErrors) {
throw error;
}
} else {
core.warning('Cloudflare pages request failed. Retrying...');
await new Promise((resolve) => {
return setTimeout(resolve, 2_500);
});

return await GetReport({
reportUrl,
retryCount: retryCount - 1,
});
}
}
}

function TotalPercentagesAverage(report) {
const percentages = [
report.total.lines.pct,
report.total.statements.pct,
report.total.functions.pct,
report.total.branches.pct,
report.summary.total.lines.pct,
report.summary.total.statements.pct,
report.summary.total.functions.pct,
report.summary.total.branches.pct,
];

return (
Expand All @@ -43,6 +14,5 @@ function TotalPercentagesAverage(report) {
}

module.exports = {
GetReport,
TotalPercentagesAverage,
};
67 changes: 20 additions & 47 deletions tests/Action.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,18 @@ const mockCloudflare = require('@tests/mocks/cloudflare');
const mockCommit = require('@tests/mocks/commit');
const mockRepository = require('@tests/mocks/repository');

jest.mock('../src/Repository', () => {
return jest.fn(() => {
return mockRepository;
});
});
jest.mock('../src/Commit', () => {
return jest.fn(() => {
return mockCommit;
});
});
jest.mock('../src/Cloudflare', () => {
return jest.fn(() => {
return mockCloudflare;
});
});
jest.mock('@/Repository', () => jest.fn(() => mockRepository));
jest.mock('@/Commit', () => jest.fn(() => mockCommit));
jest.mock('@/Cloudflare', () => jest.fn(() => mockCloudflare));

const Commit = require('../src/Commit');
const Repository = require('../src/Repository');
const Commit = require('@/Commit');
const Repository = require('@/Repository');
const githubActionContextFixture = require('@tests/fixtures/github-action-context.json');
const githubActionConfigFixture = require('@tests/fixtures/github-action-config.json');

describe('Action', () => {
const GithubAction = require('../src/Action');
const action = new GithubAction(
{
payload: {
repository: {
name: 'my-repository',
owner: {
login: 'carlosdevpereira',
},
},
},
},
{
cloudflare: {
accountId: '1',
apiToken: '1234',
baseUrl: 'project-base-url.pages.dev',
projectName: 'my-project',
},
github: {
branch: 'main',
token: '1234',
},
testing: {
framework: 'jest',
},
}
);
const GithubAction = require('@/Action');
const action = new GithubAction(githubActionContextFixture, githubActionConfigFixture);

it('creates an instance of a repository', () => {
expect(Repository).toHaveBeenCalled();
Expand All @@ -59,19 +23,28 @@ describe('Action', () => {
expect(Commit).toHaveBeenCalled();
});

describe('Runs unit tests', () => {
describe('when running the unit tests', () => {
it('runs the unit tests from the test framework', async () => {
await action.runTests();

expect(mockRepository.testFramework.runTests).toHaveBeenCalled();
});

it('adds the test results comment to the head commit', async () => {
await action.saveTestResults();

expect(mockRepository.addCommitComment).toHaveBeenCalledWith(
mockCommit.hash,
JSON.stringify(action.testResults)
);
});
});

describe('Publish results to cloudflare', () => {
it('tries to publish results from specific commit to cloudflare', async () => {
await action.publishToCloudflare();

expect(mockCloudflare.publish).toHaveBeenCalledWith('1234');
expect(mockCloudflare.publish).toHaveBeenCalledWith(mockCommit.shortHash());
});
});
});
2 changes: 1 addition & 1 deletion tests/Cloudflare.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jest.mock('shellac', () => {

describe('Cloudflare', () => {
const shellac = require('shellac').default;
const Cloudflare = require('../src/Cloudflare');
const Cloudflare = require('@/Cloudflare');
const cloudflareInstance = new Cloudflare({
accountId: 'account-id',
apiToken: 'api-token',
Expand Down
9 changes: 9 additions & 0 deletions tests/fixtures/coverage-summary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"total": {
"lines": { "total": 147, "covered": 43, "skipped": 0, "pct": 29.25 },
"statements": { "total": 148, "covered": 43, "skipped": 0, "pct": 29.05 },
"functions": { "total": 27, "covered": 7, "skipped": 0, "pct": 25.92 },
"branches": { "total": 20, "covered": 0, "skipped": 0, "pct": 0 },
"branchesTrue": { "total": 0, "covered": 0, "skipped": 0, "pct": 100 }
}
}
15 changes: 15 additions & 0 deletions tests/fixtures/github-action-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"cloudflare": {
"accountId": "1",
"apiToken": "1234",
"baseUrl": "project-base-url.pages.dev",
"projectName": "my-project"
},
"github": {
"branch": "main",
"token": "1234"
},
"testing": {
"framework": "jest"
}
}
11 changes: 11 additions & 0 deletions tests/fixtures/github-action-context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"sha": "the-commit-sha",
"payload": {
"repository": {
"name": "my-repository",
"owner": {
"login": "carlosdevpereira"
}
}
}
}
Loading

0 comments on commit 994604c

Please sign in to comment.