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

Cleanup #439

Merged
merged 14 commits into from Oct 7, 2021
Merged
33 changes: 27 additions & 6 deletions .eslintrc
@@ -1,17 +1,24 @@
{
"parser": "babel-eslint",
"plugins": ["prettier"],
"plugins": ["prettier", "css-modules"],
"extends": [
"airbnb",
"airbnb-typescript-prettier",
"plugin:cypress/recommended",
"plugin:import/typescript",
"prettier",
"prettier/react",
"plugin:cypress/recommended"
"plugin:css-modules/recommended"
],
"rules": {
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-shadow": "warn",
"@typescript-eslint/no-use-before-define": "warn",
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/no-empty-function": "warn",
"@typescript-eslint/no-var-requires": "warn",
"react-hooks/exhaustive-deps": "warn",

"import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
"no-unused-vars": ["warn"],
"no-param-reassign": ["warn"],
"no-shadow": ["warn"],
"no-case-declarations": ["warn"],
"no-use-before-define": ["warn"],
"no-restricted-globals": ["warn"],
Expand All @@ -30,11 +37,25 @@
"some": ["nesting", "id"]
}
}
],
"react/jsx-filename-extension": [1, { "extensions": [".tsx", ".ts"] }],
"import/extensions": [
"error",
"always",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
]
},
"env": {
"browser": true,
"node": true,
"jquery": true
},
"parserOptions": {
"project": "./tsconfig.json"
}
}
2 changes: 1 addition & 1 deletion Dockerfile
Expand Up @@ -55,7 +55,7 @@ WORKDIR /opt/pyroscope

COPY scripts ./scripts
COPY webapp ./webapp
COPY package.json yarn.lock babel.config.js .eslintrc .eslintignore .prettierrc Makefile ./
COPY package.json yarn.lock babel.config.js .eslintrc .eslintignore .prettierrc tsconfig.json Makefile ./

ARG EXTRA_METADATA=""
RUN EXTRA_METADATA=$EXTRA_METADATA make assets-release
Expand Down
28 changes: 28 additions & 0 deletions cypress/integration/api.ts
@@ -0,0 +1,28 @@
// few tests just to quickly validate the endpoints are working
describe('API tests', () => {
it('tests /render endpoint', () => {
cy.request(
'GET',
'/render?from=now-5m&until=now&query=pyroscope.server.alloc_objects%7B%7D&format=json'
)
.its('headers')
.its('content-type')
.should('include', 'application/json');
});

it('tests /labels endpoint', () => {
// TODO
// this is not returning json
cy.request('GET', '/labels?query=pyroscope.server.alloc_objects');
// .its('headers')
// .its('content-type')
// .should('include', 'application/json');
});

it('tests /render-diff endpoint', () => {
cy.request(
'GET',
'/render-diff?from=now-5m&until=now&query=pyroscope.server.alloc_objects{}&max-nodes=1024&leftFrom=now-1h&leftUntil=now-30m&rightFrom=now-30m&rightUntil=now&format=json'
);
});
});
12 changes: 8 additions & 4 deletions cypress/integration/basic.ts
@@ -1,4 +1,8 @@
import { BAR_HEIGHT } from '../../webapp/javascript/components/FlameGraph/FlameGraphComponent';
// copied from the source code
// TODO move those definitions to a different shareable file
const PX_PER_LEVEL = 18;
const GAP = 0.5;
const BAR_HEIGHT = PX_PER_LEVEL - GAP;

/// <reference types="cypress" />
describe('basic test', () => {
Expand Down Expand Up @@ -328,16 +332,16 @@ describe('basic test', () => {
cy.findByTestId('flamegraph-tooltip-title').should('have.text', 'total');
cy.findByTestId('flamegraph-tooltip-left').should(
'have.text',
`Left: 991 samples, 9.91 seconds (100%)`
'Left: 991 samples, 9.91 seconds (100%)'
);
cy.findByTestId('flamegraph-tooltip-right').should(
'have.text',
`Right: 987 samples, 9.87 seconds (100%)`
'Right: 987 samples, 9.87 seconds (100%)'
);
});
});

describe('tooltip', () => {
describe('highlight', () => {
it('works in diff view', () => {
cy.intercept('**/render*', {
fixture: 'simple-golang-app-cpu-diff.json',
Expand Down
19 changes: 19 additions & 0 deletions cypress/integration/e2e.ts
@@ -0,0 +1,19 @@
// Following tests should have NO mocking involved.
// The objective involve validating server/webapp interaction is working correctly
// Therefore we can't really validate certain states
//
// TODO
// somehow seed the database?
describe('E2E Tests', () => {
it('tests single view', () => {
cy.visit('/');
});

it('tests /comparison view', () => {
cy.visit('/comparison');
});

it('tests /comparison-diff view', () => {
cy.visit('/comparison-diff');
});
});
2 changes: 1 addition & 1 deletion cypress/support/commands.js
Expand Up @@ -38,7 +38,7 @@ Cypress.Commands.overwrite(
if (Cypress.env('COMPARE_SNAPSHOTS')) {
originalFn(snapshotName, options);
} else {
cy.log(`Screenshot comparison is disabled`);
cy.log('Screenshot comparison is disabled');
}
}
);
2 changes: 2 additions & 0 deletions global.d.ts
@@ -0,0 +1,2 @@
// https://stackoverflow.com/a/60029264
declare module '*.module.css';
15 changes: 13 additions & 2 deletions jest.config.js
@@ -1,4 +1,15 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
transformIgnorePatterns: [],
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// TypeScript files (.ts, .tsx) will be transformed by ts-jest to CommonJS syntax, and JavaScript files (.js, jsx) will be transformed by babel-jest.
preset: 'ts-jest/presets/js-with-babel',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/setupAfterEnv.js'],
testMatch: [
'**/__tests__/**/*.+(ts|tsx|js)',
'**/?(*.)+(spec|test).+(ts|tsx|js)',
],

transform: {
'\\.module\\.css$': 'jest-css-modules-transform',
},
};
2 changes: 0 additions & 2 deletions jest.setup.js

This file was deleted.

12 changes: 10 additions & 2 deletions package.json
Expand Up @@ -32,6 +32,9 @@
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.1.1",
"@testing-library/user-event": "^13.2.1",
"@types/jest": "^27.0.2",
"@typescript-eslint/eslint-plugin": "^4.29.3",
"@typescript-eslint/parser": "^4.29.3",
"autoprefixer": "^9.8.5",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-class-properties": "^6.24.1",
Expand All @@ -46,7 +49,10 @@
"enzyme-adapter-react-16": "^1.15.5",
"eslint": "7.2.0",
"eslint-config-airbnb": "18.2.1",
"eslint-config-airbnb-typescript": "^14.0.0",
"eslint-config-airbnb-typescript-prettier": "^4.2.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-css-modules": "^2.11.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
Expand All @@ -56,7 +62,8 @@
"eslint-webpack-plugin": "^2.4.1",
"html-webpack-plugin": "^5.3.2",
"husky": "^7.0.2",
"jest": "^26.6.3",
"jest": "^27.2.4",
"jest-css-modules-transform": "^4.3.0",
"koa-route": "^3.2.0",
"lint-staged": "^11.1.2",
"mini-css-extract-plugin": "^2.2.0",
Expand All @@ -71,7 +78,8 @@
"sass-loader": "^9.0.2",
"size-limit": "^5.0.3",
"sync-request": "^6.1.0",
"typescript": "3.9.3",
"ts-jest": "^27.0.5",
"typescript": "^4.4.3",
"webpack": "~5.51.1",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.8.0",
Expand Down
7 changes: 0 additions & 7 deletions pkg/server/render.go
Expand Up @@ -120,7 +120,6 @@ func (ctrl *Controller) renderDiffHandler(w http.ResponseWriter, r *http.Request
leftOut.Tree, rghtOut.Tree = tree.CombineTree(leftOut.Tree, rghtOut.Tree)
fs := tree.CombineToFlamebearerStruct(leftOut.Tree, rghtOut.Tree, p.maxNodes)

// TODO
fs.SpyName = out.SpyName
fs.SampleRate = out.SampleRate
fs.Units = out.Units
Expand All @@ -140,12 +139,6 @@ func (ctrl *Controller) renderDiffHandler(w http.ResponseWriter, r *http.Request
ctrl.writeResponseJSON(w, res)
}

type mergedFlamebearer struct {
*tree.Flamebearer
LeftTicks int `json:"leftTicks"`
RightTicks int `json:"rightTicks"`
}

func (ctrl *Controller) renderParametersFromRequest(r *http.Request, p *renderParams) error {
v := r.URL.Query()
p.gi = new(storage.GetInput)
Expand Down
2 changes: 1 addition & 1 deletion scripts/webpack/webpack.common.js
Expand Up @@ -77,7 +77,7 @@ module.exports = {
// Note: order is bottom-to-top and/or right-to-left
rules: [
{
test: /\.jsx?$/,
test: /\.(js|ts)x?$/,
exclude: /node_modules/,
use: [
{
Expand Down
3 changes: 2 additions & 1 deletion scripts/webpack/webpack.dev.js
Expand Up @@ -12,6 +12,7 @@ const sleep = (ms) => new Promise((res) => setTimeout(res, ms));

module.exports = merge(common, {
watch: true,
devtool: 'eval-source-map',
mode: 'development',
entry: {
serve: 'webpack-plugin-serve/client',
Expand All @@ -26,7 +27,7 @@ module.exports = merge(common, {
do {
if (maxTries <= 0) {
throw new Error(
`Could not find pyroscope instance running on http://localhost:4040`
'Could not find pyroscope instance running on http://localhost:4040'
);
}
res = request('GET', 'http://localhost:4040');
Expand Down
3 changes: 3 additions & 0 deletions scripts/webpack/webpack.prod.js
Expand Up @@ -4,4 +4,7 @@ const common = require('./webpack.common');

module.exports = merge(common, {
mode: 'production',

// Recommended choice for production builds with high quality SourceMaps.
devtool: 'source-map',
});
1 change: 1 addition & 0 deletions setupAfterEnv.js
@@ -0,0 +1 @@
import '@testing-library/jest-dom';
11 changes: 11 additions & 0 deletions tsconfig.json
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"jsx": "react",
"lib": ["dom", "esnext"],
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
"sourceMap": true
},
"exclude": ["node_modules"]
}
Expand Up @@ -4,6 +4,7 @@ exports[`RefreshButton render correctly RefreshButton component 1`] = `
<div>
<button
className="btn refresh-btn"
data-testid="refresh-btn"
onClick={[Function]}
type="button"
>
Expand Down
4 changes: 2 additions & 2 deletions webapp/javascript/components/CustomDatePicker.jsx
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
// we import moment/src/moment instead of moment because we don't want to load locales
import moment from 'moment/src/moment';
// TODO: don't import locales
import moment from 'moment';
import { useSelector } from 'react-redux';
import DatePicker from 'react-datepicker';
import { readableRange, formatAsOBject } from '../util/formatDate';
Expand Down
@@ -0,0 +1,7 @@
.highlight {
color: red;
position: absolute;
pointer-events: none;
background: #ffffff40;
mix-blend-mode: overlay;
}
Expand Up @@ -3,9 +3,9 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import Highlight from './Highlight';
import Highlight, { HighlightProps } from './Highlight';

function TestComponent(props) {
function TestComponent(props: Omit<HighlightProps, 'canvasRef'>) {
const canvasRef = React.useRef();

return (
Expand All @@ -23,7 +23,7 @@ describe('Highlight', () => {
const xyToHighlightData = jest.fn();
render(
<TestComponent
height={50}
barHeight={50}
isWithinBounds={isWithinBounds}
xyToHighlightData={xyToHighlightData}
/>
Expand Down