diff --git a/app/assets/javascripts/store/index.js b/app/assets/javascripts/store/index.js
index 6687664cd..02a6c0abd 100644
--- a/app/assets/javascripts/store/index.js
+++ b/app/assets/javascripts/store/index.js
@@ -43,4 +43,8 @@ const store = createStore(
composeWithDevTools(applyMiddleware(thunk.withExtraArgument(dependencies)))
);
+export const testStore = preloadedState => {
+ return createStore(reducer, preloadedState);
+};
+
export default store;
diff --git a/app/assets/javascripts/views/story_view.jsx b/app/assets/javascripts/views/story_view.jsx
index ed4039291..4b68cc895 100644
--- a/app/assets/javascripts/views/story_view.jsx
+++ b/app/assets/javascripts/views/story_view.jsx
@@ -200,7 +200,7 @@ const StoryView = FormView.extend({
this.model[transitionEvent]({ silent: true });
var that = this;
- this.model.save(null, {
+ return this.model.save(null, {
success: function (model, response) {
that.saveInProgress = false;
that.render();
@@ -223,7 +223,7 @@ const StoryView = FormView.extend({
this.model.set({ estimate: points });
var that = this;
- this.model.save(null, {
+ return this.model.save(null, {
success: function (model, response) {
that.saveInProgress = false;
that.render();
@@ -322,7 +322,7 @@ const StoryView = FormView.extend({
var that = this;
- this.model.save(null, {
+ return this.model.save(null, {
success: function (model, response) {
that.enableForm();
that.model.set({ editing: editMode });
@@ -542,21 +542,24 @@ const StoryView = FormView.extend({
);
},
- appendAttachments: function() {
+ appendAttachments: function () {
this.$el.append(
- this.makeFormControl(function(div) {
+ this.makeFormControl(function (div) {
const $storyAttachments = $('
');
$(div).append($storyAttachments);
- if(process.env.NODE_ENV !== 'test') {
+ if (process.env.NODE_ENV !== 'test') {
clearTimeout(window.executeAttachinaryTimeout);
- window.executeAttachinaryTimeout = setTimeout(ExecuteAttachinary, 1000);
+ window.executeAttachinaryTimeout = setTimeout(
+ ExecuteAttachinary,
+ 1000
+ );
}
})
);
},
- renderCollapsed: function(isGuest) {
+ renderCollapsed: function (isGuest) {
this.$el.removeClass('editing');
this.$el.html(this.template({ story: this.model, view: this }));
this.$el.toggleClass(
@@ -575,14 +578,22 @@ const StoryView = FormView.extend({
const estimateButtons = this.$('[data-story-estimate-buttons]').get(0);
if (estimateButtons) {
ReactDOM.render(
-
,
+
,
estimateButtons
);
}
- const copyStoryIdClipboardLink = this.$('[data-story-id-copy-clipboard]').get(0)
- if(copyStoryIdClipboardLink) {
- ReactDOM.render(
, copyStoryIdClipboardLink)
+ const copyStoryIdClipboardLink = this.$(
+ '[data-story-id-copy-clipboard]'
+ ).get(0);
+ if (copyStoryIdClipboardLink) {
+ ReactDOM.render(
+
,
+ copyStoryIdClipboardLink
+ );
}
if (isGuest) {
@@ -1160,7 +1171,7 @@ const StoryView = FormView.extend({
},
clickSave: function (event) {
- this.saveEdit(event, false);
+ return this.saveEdit(event, false);
},
toggleControlButtons: function (isDisabled, changeCancel) {
diff --git a/package.json b/package.json
index cf9c30f9e..b8ae1953f 100644
--- a/package.json
+++ b/package.json
@@ -3,44 +3,14 @@
"version": "0.0.1",
"license": "MIT",
"scripts": {
- "test": "jest",
- "coveralls": "jest --coverage --coverageReporters=text-lcov | coveralls",
+ "test": "vitest",
+ "coveralls": "vitest run --coverage --coverageReporters=text-lcov | coveralls",
"lint": "eslint app/assets/javascripts",
"start:test": "rails s -e test -p 5000 & wait-on http://localhost:5000",
"cy:run": "cypress run -P spec/",
"format": "prettier --write 'app/assets/javascripts/**/*.{js,jsx}'",
"prepare": "husky install"
},
- "jest": {
- "setupFilesAfterEnv": [
- "jest-sinon",
- "./node_modules/jest-enzyme/lib/index.js",
- "
/spec/javascripts/support/setup.js"
- ],
- "testMatch": [
- "/spec/javascripts/**/*_spec.js"
- ],
- "transform": {
- "^.+\\.ejs$": "/spec/javascripts/support/ejsTransformer.js",
- "^.+\\.jsx?$": "babel-jest"
- },
- "moduleNameMapper": {
- "^vendor/(.*)": "/vendor/assets/javascripts/$1",
- "^collections/(.*)": "/app/assets/javascripts/collections/$1",
- "^mixins/(.*)": "/app/assets/javascripts/mixins/$1",
- "^models/(.*)": "/app/assets/javascripts/models/$1",
- "^templates/(.*)": "/app/assets/javascripts/templates/$1",
- "^views/(.*)": "/app/assets/javascripts/views/$1",
- "^libs/(.*)": "/app/assets/javascripts/libs/$1",
- "^components/(.*)": "/app/assets/javascripts/components/$1",
- "^controllers/(.*)": "/app/assets/javascripts/controllers/$1",
- "^reducers/(.*)": "/app/assets/javascripts/reducers/$1",
- "^actions/(.*)": "/app/assets/javascripts/actions/$1",
- "^central/(.*)": "/app/assets/javascripts/central/$1",
- "^store/(.*)": "/app/assets/javascripts/store/$1",
- "^gritter$": "gritter/js/jquery.gritter.min.js"
- }
- },
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-transform-runtime": "^7.7.4",
@@ -117,8 +87,6 @@
"babel-jest": "^24.9.0",
"coveralls": "^3.0.9",
"cypress": "^10.1.0",
- "enzyme": "^3.11.0",
- "enzyme-adapter-react-16": "^1.15.1",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-react-app": "^5.0.2",
@@ -129,16 +97,15 @@
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-react": "^7.16.0",
"husky": "^8.0.0",
- "jest": "^26.6.3",
- "jest-enzyme": "^7.1.2",
- "jest-sinon": "^1.0.1",
+ "jsdom": "^25.0.0",
"lint-staged": "^15.0.2",
+ "msw": "^2.4.4",
"prettier": "^3.0.3",
"react-addons-test-utils": "^15.6.2",
"react-test-renderer": "^16.12.0",
- "sinon": "^7.5.0",
"vite": "^4.5.3",
- "vite-plugin-ruby": "^3.2.0"
+ "vite-plugin-ruby": "^3.2.0",
+ "vitest": "^2.0.5"
},
"engines": {
"node": "18.12.0"
diff --git a/spec/javascripts/actions/history_spec.js b/spec/javascripts/actions/history_spec.js
index 7f31c34b7..2c6b782c5 100644
--- a/spec/javascripts/actions/history_spec.js
+++ b/spec/javascripts/actions/history_spec.js
@@ -1,61 +1,65 @@
-import * as actions from "../../../app/assets/javascripts/actions/story";
-import history from "../support/factories/historyFactory";
-import story from "../support/factories/storyFactory";
+import * as actions from '../../../app/assets/javascripts/actions/story';
+import history from '../support/factories/historyFactory';
+import story from '../support/factories/storyFactory';
-describe("History Actions", () => {
- it("Should load a new history when called showHistory action", async () => {
- const fakeDispatch = sinon.stub().resolves({});
+describe('History Actions', () => {
+ it('Should load a new history when called showHistory action', async () => {
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub();
+ const fakeGetState = vi.fn();
const FakeStory = {
- findById: sinon.stub().returns(story()),
- getHistory: sinon.stub().resolves(history()),
- withScope: sinon.stub().returns([story()]),
- denormalizeState: sinon.stub().returns({ all: [story()] }),
+ findById: vi.fn().mockReturnValue(story()),
+ getHistory: vi.fn().mockResolvedValue(history()),
+ withScope: vi.fn().mockReturnValue([story()]),
+ denormalizeState: vi.fn().mockReturnValue({ all: [story()] }),
};
- fakeGetState.returns({ stories: { all: [story()] } });
+ fakeGetState.mockReturnValue({ stories: { all: [story()] } });
await actions.showHistory(story().id)(fakeDispatch, fakeGetState, {
Story: FakeStory,
});
- expect(fakeDispatch).toHaveBeenCalledWith(actions.loadHistory("title"));
+ expect(fakeDispatch).toHaveBeenCalledWith(actions.loadHistory('title'));
});
- it("Should receive a history when called showHistory action", async () => {
+ it('Should receive a history when called showHistory action', async () => {
const FakeStory = {
- findById: sinon.stub().returns(story()),
- getHistory: sinon.stub().resolves(history()),
- withScope: sinon.stub().returns([story()]),
- denormalizeState: sinon.stub().returns({ all: [story()] }),
+ findById: vi.fn().mockReturnValue(story()),
+ getHistory: vi.fn().mockResolvedValue(history()),
+ withScope: vi.fn().mockReturnValue([story()]),
+ denormalizeState: vi.fn().mockReturnValue({ all: [story()] }),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub().returns({ stories: { all: [story()] } });
+ const fakeGetState = vi
+ .fn()
+ .mockReturnValue({ stories: { all: [story()] } });
await actions.showHistory(story().id)(fakeDispatch, fakeGetState, {
Story: FakeStory,
});
expect(fakeDispatch).toHaveBeenCalledWith(
- actions.receiveHistory(history(), "title")
+ actions.receiveHistory(history(), 'title')
);
});
- it("Should dispatch errorLoadHistory when called showHistory action", async () => {
+ it('Should dispatch errorLoadHistory when called showHistory action', async () => {
const FakeStory = {
- findById: sinon.stub().returns(story()),
- getHistory: sinon.stub().rejects("error"),
- withScope: sinon.stub().returns([story()]),
- denormalizeState: sinon.stub().returns({ all: [story()] }),
+ findById: vi.fn().mockReturnValue(story()),
+ getHistory: vi.fn().mockRejectedValue('error'),
+ withScope: vi.fn().mockReturnValue([story()]),
+ denormalizeState: vi.fn().mockReturnValue({ all: [story()] }),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub().returns({ stories: { all: [story()] } });
+ const fakeGetState = vi
+ .fn()
+ .mockReturnValue({ stories: { all: [story()] } });
await actions.showHistory(story().id)(fakeDispatch, fakeGetState, {
Story: FakeStory,
diff --git a/spec/javascripts/actions/note_spec.js b/spec/javascripts/actions/note_spec.js
index 06dca7817..3d56ea8c6 100644
--- a/spec/javascripts/actions/note_spec.js
+++ b/spec/javascripts/actions/note_spec.js
@@ -3,49 +3,56 @@ import * as Story from 'actions/story';
describe('Note Actions', () => {
describe('createNote', () => {
- const note = { id: 42, note: 'testNote' }
+ const note = { id: 42, note: 'testNote' };
const projectId = 42;
const storyId = 420;
it('calls FakeNote.post with projectId, storyId and note', async () => {
const FakeNote = {
- post: sinon.stub().resolves(note)
+ post: vi.fn().mockResolvedValue(note),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Note.createNote(projectId, storyId, note)
- (fakeDispatch, null, { Note: FakeNote });
+ await Note.createNote(projectId, storyId, note)(fakeDispatch, null, {
+ Note: FakeNote,
+ });
expect(FakeNote.post).toHaveBeenCalledWith(projectId, storyId, note);
});
it('dispatch createNoteSuccess with storyId and note', async () => {
const FakeNote = {
- post: sinon.stub().resolves(note)
+ post: vi.fn().mockResolvedValue(note),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Note.createNote(projectId, storyId, note)
- (fakeDispatch, null, { Note: FakeNote });
+ await Note.createNote(projectId, storyId, note)(fakeDispatch, null, {
+ Note: FakeNote,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Note.createNoteSuccess(storyId, note));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Note.createNoteSuccess(storyId, note)
+ );
});
it('dispatches storyFailure when promise fails', async () => {
- const error = { error: "boom" };
+ const error = { error: 'boom' };
const FakeNote = {
- post: sinon.stub().rejects(error)
+ post: vi.fn().mockRejectedValue(error),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Note.createNote(projectId, storyId, note)
- (fakeDispatch, null, { Note: FakeNote });
+ await Note.createNote(projectId, storyId, note)(fakeDispatch, null, {
+ Note: FakeNote,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Story.storyFailure(storyId, error));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Story.storyFailure(storyId, error)
+ );
});
});
@@ -56,44 +63,50 @@ describe('Note Actions', () => {
it('calls FakeNote.destroy with projectId, storyId and noteId', async () => {
const FakeNote = {
- destroy: sinon.stub().resolves({})
+ destroy: vi.fn().mockResolvedValue({}),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Note.deleteNote(projectId, storyId, noteId)
- (fakeDispatch, null, { Note: FakeNote });
+ await Note.deleteNote(projectId, storyId, noteId)(fakeDispatch, null, {
+ Note: FakeNote,
+ });
expect(FakeNote.destroy).toHaveBeenCalledWith(projectId, storyId, noteId);
});
it('dispatch deleteNoteSuccess with storyId and noteId', async () => {
const FakeNote = {
- destroy: sinon.stub().resolves({})
+ destroy: vi.fn().mockResolvedValue({}),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Note.deleteNote(projectId, storyId, noteId)
- (fakeDispatch, null, { Note: FakeNote });
+ await Note.deleteNote(projectId, storyId, noteId)(fakeDispatch, null, {
+ Note: FakeNote,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Note.deleteNoteSuccess(storyId, noteId));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Note.deleteNoteSuccess(storyId, noteId)
+ );
});
it('dispatches storyFailure when promise fails', async () => {
- const error = { error: "boom" };
+ const error = { error: 'boom' };
const FakeNote = {
- destroy: sinon.stub().rejects(error)
+ destroy: vi.fn().mockRejectedValue(error),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
+ await Note.deleteNote(projectId, storyId, noteId)(fakeDispatch, null, {
+ Note: FakeNote,
+ });
- await Note.deleteNote(projectId, storyId, noteId)
- (fakeDispatch, null, { Note: FakeNote });
-
- expect(fakeDispatch).toHaveBeenCalledWith(Story.storyFailure(storyId, error));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Story.storyFailure(storyId, error)
+ );
});
});
-})
+});
diff --git a/spec/javascripts/actions/notifications_spec.js b/spec/javascripts/actions/notifications_spec.js
index 31cedc9d7..14ef376a4 100644
--- a/spec/javascripts/actions/notifications_spec.js
+++ b/spec/javascripts/actions/notifications_spec.js
@@ -8,15 +8,15 @@ describe('Notifications Actions', () => {
const newNotification = {
id: 42,
type: types.SUCCESS,
- message: 'Success message'
- }
+ message: 'Success message',
+ };
const FakeNotification = {
createNotification: () => newNotification,
- types
+ types,
};
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
Notification.sendSuccessNotification(newNotification.message)(
fakeDispatch,
@@ -24,24 +24,26 @@ describe('Notifications Actions', () => {
{ Notification: FakeNotification }
);
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
it('dispatches removeNotification after 5000ms to remove notification', () => {
const newNotification = {
id: 42,
type: types.SUCCESS,
- message: 'Success message'
- }
+ message: 'Success message',
+ };
const FakeNotification = {
createNotification: () => newNotification,
- types
+ types,
};
- const clock = sinon.useFakeTimers()
+ const clock = vi.useFakeTimers();
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
Notification.sendSuccessNotification(newNotification.message)(
fakeDispatch,
@@ -49,11 +51,11 @@ describe('Notifications Actions', () => {
{ Notification: FakeNotification }
);
- clock.tick(5000);
+ clock.advanceTimersByTime(5000);
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.removeNotification(newNotification.id));
-
- clock.restore();
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.removeNotification(newNotification.id)
+ );
});
});
@@ -61,7 +63,7 @@ describe('Notifications Actions', () => {
const createNotification = (type, message) => ({
id: 42,
type,
- message
+ message,
});
describe('when response error is an unprocessable_entity', () => {
@@ -70,25 +72,23 @@ describe('Notifications Actions', () => {
status: status.UNPROCESSABLE_ENTITY,
data: {
story: {
- errors: {}
- }
- }
- }
+ errors: {},
+ },
+ },
+ },
};
it('dispatches addValidationNotifications', () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
expect(fakeDispatch).toHaveBeenCalled();
});
@@ -97,118 +97,120 @@ describe('Notifications Actions', () => {
describe('when response error is unauthorized', () => {
const error = {
response: {
- status: status.UNAUTHORIZED
- }
+ status: status.UNAUTHORIZED,
+ },
};
it('dispatches addNotification with the unauthorized message', () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
const newNotification = createNotification({
type: types.ERROR,
- message: I18n.t('users.You are not authorized to perform this action')
+ message: I18n.t(
+ 'users.You are not authorized to perform this action'
+ ),
});
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
});
describe('when response error is not_found', () => {
const error = {
response: {
- status: status.NOT_FOUND
- }
+ status: status.NOT_FOUND,
+ },
};
it('dispatches addNotification with the not_found message', () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
const newNotification = createNotification({
type: types.ERROR,
- message: I18n.t('not_found')
+ message: I18n.t('not_found'),
});
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
});
describe('when response error is unknown', () => {
const error = {
response: {
- status: 'unknown'
- }
+ status: 'unknown',
+ },
};
it('dispatches addNotification with the default message', () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
const newNotification = createNotification({
type: types.ERROR,
- message: I18n.t('messages.operations.error.default_error')
+ message: I18n.t('messages.operations.error.default_error'),
});
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
});
describe('when error has no response property', () => {
const error = {
- message: "I'm an error!"
- }
+ message: "I'm an error!",
+ };
it('dispatches addNotification with the default message', () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
const newNotification = createNotification({
type: types.ERROR,
- message: I18n.t('messages.operations.error.default_error')
+ message: I18n.t('messages.operations.error.default_error'),
});
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
});
@@ -217,35 +219,35 @@ describe('Notifications Actions', () => {
invalidMessageErrors.forEach(message => {
const error = {
- response: message
+ response: message,
};
it('dispatch addNotification with default notification', () => {
const defaultNotifcation = createNotification({
type: types.ERROR,
- message: I18n.t('messages.operations.error.default_error')
+ message: I18n.t('messages.operations.error.default_error'),
});
const FakeNotification = {
createNotification,
- types
+ types,
};
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(defaultNotifcation));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(defaultNotifcation)
+ );
});
});
});
describe('when custom is true', () => {
- const errorsMessage = ['error','message here','lorem ipsum'];
+ const errorsMessage = ['error', 'message here', 'lorem ipsum'];
errorsMessage.forEach(error => {
describe(`and error is ${error}`, () => {
@@ -254,15 +256,15 @@ describe('Notifications Actions', () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
const newNotification = createNotification({
type: types.ERROR,
- message: I18n.t(error)
+ message: I18n.t(error),
});
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
Notification.sendErrorNotification(error, trueCustom)(
fakeDispatch,
@@ -270,7 +272,9 @@ describe('Notifications Actions', () => {
{ Notification: FakeNotification }
);
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
});
});
@@ -281,33 +285,33 @@ describe('Notifications Actions', () => {
const createNotification = (type, message) => ({
id: 42,
type,
- message
+ message,
});
-
- const errorsMessage = ['error','message here','lorem ipsum'];
+
+ const errorsMessage = ['error', 'message here', 'lorem ipsum'];
errorsMessage.forEach(error => {
describe(`when message is ${error}`, () => {
it(`dispatch addNotification with ${error}`, () => {
const FakeNotification = {
createNotification,
- types
+ types,
};
const newNotification = createNotification({
type: types.ERROR,
- message: I18n.t(error)
+ message: I18n.t(error),
});
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.sendCustomErrorNotification(error)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.sendCustomErrorNotification(error)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(newNotification));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(newNotification)
+ );
});
});
});
@@ -316,37 +320,37 @@ describe('Notifications Actions', () => {
describe('addValidationNotifications', () => {
const errors = {
title: 'can not be null',
- estimate: 'can not be 0'
- }
+ estimate: 'can not be 0',
+ };
it('add all errors to addNotification', () => {
const createNotification = (type, message) => ({
id: 42,
type,
- message
+ message,
});
const expectedNotifications = Object.keys(errors).map(error =>
createNotification({
type: types.ERROR,
- message: `Error. ${error}: ${errors[error]}`
+ message: `Error. ${error}: ${errors[error]}`,
})
);
const FakeNotification = {
createNotification,
- types
+ types,
};
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
- Notification.addValidationNotifications(errors)(
- fakeDispatch,
- null,
- { Notification: FakeNotification }
- );
+ Notification.addValidationNotifications(errors)(fakeDispatch, null, {
+ Notification: FakeNotification,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Notification.addNotification(expectedNotifications));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Notification.addNotification(expectedNotifications)
+ );
});
});
});
diff --git a/spec/javascripts/actions/pastIterations_spec.js b/spec/javascripts/actions/pastIterations_spec.js
index bb9a2ea01..81cc7c353 100644
--- a/spec/javascripts/actions/pastIterations_spec.js
+++ b/spec/javascripts/actions/pastIterations_spec.js
@@ -8,21 +8,23 @@ describe('Past iteration actions', () => {
const pastIterationsArray = overrides => [
{
iterationNumber: 42,
- startDate: previousSprintDate.format("YYYY/MM/DD"),
- endDate: currentSprintDate.format("YYYY/MM/DD"),
+ startDate: previousSprintDate.format('YYYY/MM/DD'),
+ endDate: currentSprintDate.format('YYYY/MM/DD'),
stories: [41, 42, 43],
- ...overrides
- }
+ ...overrides,
+ },
];
describe('receivePastIterations', () => {
const expected = {
type: actionTypes.RECEIVE_PAST_ITERATIONS,
- data: pastIterationsArray()
- }
+ data: pastIterationsArray(),
+ };
it('creates an action to receive past iterations', () => {
- const created = PastIterations.receivePastIterations(pastIterationsArray());
+ const created = PastIterations.receivePastIterations(
+ pastIterationsArray()
+ );
expect(created).toEqual(expected);
});
});
@@ -30,8 +32,8 @@ describe('Past iteration actions', () => {
describe('requestPastStories', () => {
const expected = {
type: actionTypes.REQUEST_PAST_STORIES,
- iterationNumber: 42
- }
+ iterationNumber: 42,
+ };
it('creates an action to request past iteration stories', () => {
const created = PastIterations.requestPastStories(42);
@@ -44,11 +46,14 @@ describe('Past iteration actions', () => {
type: actionTypes.RECEIVE_PAST_STORIES,
stories: pastIterationsArray(),
iterationNumber: 42,
- from: undefined
- }
+ from: undefined,
+ };
it('creates an action to receive past iteration stories', () => {
- const created = PastIterations.receivePastStories(pastIterationsArray(), 42);
+ const created = PastIterations.receivePastStories(
+ pastIterationsArray(),
+ 42
+ );
expect(created).toEqual(expected);
});
});
@@ -57,8 +62,8 @@ describe('Past iteration actions', () => {
const expected = {
type: actionTypes.ERROR_REQUEST_PAST_STORIES,
iterationNumber: 42,
- error: '404'
- }
+ error: '404',
+ };
it('creates an action to receive past iteration stories', () => {
const created = PastIterations.errorRequestPastStories('404', 42);
@@ -74,45 +79,60 @@ describe('Past iteration actions', () => {
let PastIteration;
beforeEach(() => {
PastIteration = {
- getStories: sinon.stub().returns(stories)
- }
+ getStories: vi.fn().mockReturnValue(stories),
+ };
});
it('calls dispatch with requestPastSotires', async () => {
- const getState = sinon.stub();
- getState.returns({ project, pastIterations });
- const dispatch = sinon.stub().resolves({});
-
- await PastIterations.fetchPastStories(iterationNumber)
- (dispatch, getState, { PastIteration });
-
- expect(dispatch).toHaveBeenCalledWith(PastIterations.requestPastStories(iterationNumber));
+ const getState = vi.fn();
+ getState.mockReturnValue({ project, pastIterations });
+ const dispatch = vi.fn().mockResolvedValue({});
+
+ await PastIterations.fetchPastStories(iterationNumber)(
+ dispatch,
+ getState,
+ { PastIteration }
+ );
+
+ expect(dispatch).toHaveBeenCalledWith(
+ PastIterations.requestPastStories(iterationNumber)
+ );
});
it('tries to fetch iteration stories', async () => {
- const getState = sinon.stub();
- getState.returns({ project, pastIterations });
- const dispatch = sinon.stub().resolves({});
-
- await PastIterations.fetchPastStories(iterationNumber, startDate, endDate)
- (dispatch, getState, { PastIteration });
-
- expect(PastIteration.getStories).toHaveBeenCalledWith(project.id, startDate, endDate);
+ const getState = vi.fn();
+ getState.mockReturnValue({ project, pastIterations });
+ const dispatch = vi.fn().mockResolvedValue({});
+
+ await PastIterations.fetchPastStories(
+ iterationNumber,
+ startDate,
+ endDate
+ )(dispatch, getState, { PastIteration });
+
+ expect(PastIteration.getStories).toHaveBeenCalledWith(
+ project.id,
+ startDate,
+ endDate
+ );
});
describe('when request to get stories is sucessful', () => {
it('calls dispatch with receivePastStories', async () => {
- const getState = sinon.stub();
- getState.returns({ project, pastIterations });
- const dispatch = sinon.stub().resolves({});
+ const getState = vi.fn();
+ getState.mockReturnValue({ project, pastIterations });
+ const dispatch = vi.fn().mockResolvedValue({});
- await PastIterations.fetchPastStories(iterationNumber, startDate, endDate)
- (dispatch, getState, { PastIteration });
+ await PastIterations.fetchPastStories(
+ iterationNumber,
+ startDate,
+ endDate
+ )(dispatch, getState, { PastIteration });
expect(dispatch).toHaveBeenCalledWith(
PastIterations.receivePastStories(stories, iterationNumber)
);
- })
+ });
});
describe('when request to get stories throws error', () => {
@@ -120,21 +140,24 @@ describe('Past iteration actions', () => {
const PastIterationError = {
getStories: async () => {
throw error;
- }
- }
+ },
+ };
it('calls dispatch with errorRequestPastStories', async () => {
- const getState = sinon.stub();
- getState.returns({ project, pastIterations });
- const dispatch = sinon.stub().resolves({});
+ const getState = vi.fn();
+ getState.mockReturnValue({ project, pastIterations });
+ const dispatch = vi.fn().mockResolvedValue({});
- await PastIterations.fetchPastStories(iterationNumber, startDate, endDate)
- (dispatch, getState, { PastIteration: PastIterationError });
+ await PastIterations.fetchPastStories(
+ iterationNumber,
+ startDate,
+ endDate
+ )(dispatch, getState, { PastIteration: PastIterationError });
expect(dispatch).toHaveBeenCalledWith(
PastIterations.errorRequestPastStories(error, iterationNumber)
);
- })
+ });
});
});
});
diff --git a/spec/javascripts/actions/projectBoard_spec.js b/spec/javascripts/actions/projectBoard_spec.js
index 409c26bb0..95c32e08b 100644
--- a/spec/javascripts/actions/projectBoard_spec.js
+++ b/spec/javascripts/actions/projectBoard_spec.js
@@ -1,5 +1,8 @@
import * as ProjectBoard from '../../../app/assets/javascripts/actions/projectBoard';
-import { toggleStory, receiveStories } from '../../../app/assets/javascripts/actions/story';
+import {
+ toggleStory,
+ receiveStories,
+} from '../../../app/assets/javascripts/actions/story';
import { sendErrorNotification } from '../../../app/assets/javascripts/actions/notifications';
describe('Project Board Actions', () => {
@@ -7,28 +10,28 @@ describe('Project Board Actions', () => {
describe('when storyId is true', () => {
it('dispatch toggleStory', () => {
const storyId = 127;
-
- const fakeGetHash = sinon.stub();
- fakeGetHash.returns(storyId);
-
- const fakeDispatch = sinon.stub();
- fakeDispatch.resolves({});
-
+
+ const fakeGetHash = vi.fn();
+ fakeGetHash.mockReturnValue(storyId);
+
+ const fakeDispatch = vi.fn();
+ fakeDispatch.mockResolvedValue({});
+
ProjectBoard.expandStoryIfNeeded(fakeDispatch, fakeGetHash);
expect(fakeDispatch).toHaveBeenCalledWith(toggleStory(storyId));
});
});
-
+
describe('when storyId is false', () => {
it('does not dispatch toggleStory', () => {
const storyId = null;
-
- const fakeGetHash = sinon.stub();
- fakeGetHash.returns(storyId);
-
- const fakeDispatch = sinon.stub();
- fakeDispatch.resolves({});
-
+
+ const fakeGetHash = vi.fn();
+ fakeGetHash.mockReturnValue(storyId);
+
+ const fakeDispatch = vi.fn();
+ fakeDispatch.mockResolvedValue({});
+
ProjectBoard.expandStoryIfNeeded(fakeDispatch, fakeGetHash);
expect(fakeDispatch).not.toHaveBeenCalledWith(toggleStory(storyId));
});
@@ -40,24 +43,32 @@ describe('Project Board Actions', () => {
it('calls "dispatch"', () => {
const condition = true;
const code = 'code';
-
- const fakeDispatch = sinon.stub();
- fakeDispatch.resolves({});
-
- ProjectBoard.sendErrorNotificationIfNeeded(fakeDispatch, code, condition);
+
+ const fakeDispatch = vi.fn();
+ fakeDispatch.mockResolvedValue({});
+
+ ProjectBoard.sendErrorNotificationIfNeeded(
+ fakeDispatch,
+ code,
+ condition
+ );
expect(fakeDispatch).toHaveBeenCalled();
});
});
-
+
describe('when condition is false', () => {
it('does not call "dispatch"', () => {
const condition = false;
const code = 'code';
-
- const fakeDispatch = sinon.stub();
- fakeDispatch.resolves({});
-
- ProjectBoard.sendErrorNotificationIfNeeded(fakeDispatch, code, condition);
+
+ const fakeDispatch = vi.fn();
+ fakeDispatch.mockResolvedValue({});
+
+ ProjectBoard.sendErrorNotificationIfNeeded(
+ fakeDispatch,
+ code,
+ condition
+ );
expect(fakeDispatch).not.toHaveBeenCalled();
});
});
@@ -68,18 +79,19 @@ describe('Project Board Actions', () => {
let fakeGetState;
beforeEach(() => {
- fakeDispatch = sinon.stub();
- fakeDispatch.resolves({});
+ fakeDispatch = vi.fn();
+ fakeDispatch.mockResolvedValue({});
- fakeGetState = sinon.stub();
- fakeGetState.returns({});
+ fakeGetState = vi.fn();
+ fakeGetState.mockReturnValue({});
- ProjectBoard.closeSearch()
- (fakeDispatch, fakeGetState, {});
+ ProjectBoard.closeSearch()(fakeDispatch, fakeGetState, {});
});
it('dispatch closeSearchSuccess', () => {
- expect(fakeDispatch).toHaveBeenCalledWith(ProjectBoard.closeSearchSuccess());
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ ProjectBoard.closeSearchSuccess()
+ );
});
it('dispatch receiveStories', () => {
@@ -89,22 +101,18 @@ describe('Project Board Actions', () => {
describe('search', () => {
describe('when search is invalid', () => {
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
const keyword = '';
const projectId = 1;
- const FakeSearch = {
- searchStories: sinon.stub()
+ const FakeSearch = {
+ searchStories: vi.fn(),
};
- ProjectBoard.search(keyword, projectId)(
- fakeDispatch,
- null,
- {
- Search: FakeSearch,
- }
- );
+ ProjectBoard.search(keyword, projectId)(fakeDispatch, null, {
+ Search: FakeSearch,
+ });
it('does nothing', () => {
expect(fakeDispatch).not.toHaveBeenCalled();
@@ -112,34 +120,36 @@ describe('Project Board Actions', () => {
});
describe('when search is valid', () => {
- const fakeDispatch = sinon.stub();
+ const fakeDispatch = vi.fn();
const result = [];
const keyword = 'keyword';
const projectId = 1;
- const FakeSearch = {
- searchStories: (_, __, callback) => callback.onSuccess(result)
+ const FakeSearch = {
+ searchStories: (_, __, callback) => callback.onSuccess(result),
};
- ProjectBoard.search(keyword, projectId)(
- fakeDispatch,
- null,
- {
- Search: FakeSearch,
- }
- );
+ ProjectBoard.search(keyword, projectId)(fakeDispatch, null, {
+ Search: FakeSearch,
+ });
it('dispatch updateLoadingSearch with false', () => {
- expect(fakeDispatch).toHaveBeenCalledWith(ProjectBoard.updateLoadingSearch(false));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ ProjectBoard.updateLoadingSearch(false)
+ );
});
it('dispatch searchStoriesSuccess with keyword', () => {
- expect(fakeDispatch).toHaveBeenCalledWith(ProjectBoard.searchStoriesSuccess(keyword));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ ProjectBoard.searchStoriesSuccess(keyword)
+ );
});
it('dispatch receiveStories with search and result', () => {
- expect(fakeDispatch).toHaveBeenCalledWith(receiveStories(result, 'search'));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ receiveStories(result, 'search')
+ );
});
});
});
@@ -153,23 +163,21 @@ describe('Project Board Actions', () => {
let fakeProjectBoard;
beforeEach(() => {
- fakeDispatch = sinon.stub();
- fakeGetState = sinon.stub().returns({});
- fakeProjectBoard = {
- toggleColumn: (_, __, callback) => callback.onToggle()
+ fakeDispatch = vi.fn();
+ fakeGetState = vi.fn().mockReturnValue({});
+ fakeProjectBoard = {
+ toggleColumn: (_, __, callback) => callback.onToggle(),
};
});
it('always dispatch toggleColumnVisibility', () => {
- ProjectBoard.toggleColumn(column)(
- fakeDispatch,
- fakeGetState,
- {
- ProjectBoard: fakeProjectBoard,
- }
- );
+ ProjectBoard.toggleColumn(column)(fakeDispatch, fakeGetState, {
+ ProjectBoard: fakeProjectBoard,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(ProjectBoard.toggleColumnVisibility(column));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ ProjectBoard.toggleColumnVisibility(column)
+ );
});
});
});
diff --git a/spec/javascripts/actions/story_spec.js b/spec/javascripts/actions/story_spec.js
index d6ec16f4d..0b80a7f27 100644
--- a/spec/javascripts/actions/story_spec.js
+++ b/spec/javascripts/actions/story_spec.js
@@ -2,8 +2,8 @@ import { sendDefaultErrorNotification } from 'actions/notifications';
import * as Story from 'actions/story';
import storyFactory from '../support/factories/storyFactory';
-jest.mock('../../../app/assets/javascripts/reducers/stories', () => ({
- storiesWithScope: jest.fn(),
+vi.mock('../../../app/assets/javascripts/reducers/stories', () => ({
+ storiesWithScope: vi.fn(),
}));
describe('Story Actions', () => {
@@ -21,16 +21,16 @@ describe('Story Actions', () => {
};
const FakeStory = {
- findById: sinon.stub().returns(editedStory),
- update: sinon.stub().resolves(story),
- isNew: sinon.stub().returns(false),
- needConfirmation: sinon.stub().returns(false),
+ findById: vi.fn().mockReturnValue(editedStory),
+ update: vi.fn().mockResolvedValue(story),
+ isNew: vi.fn().mockReturnValue(false),
+ needConfirmation: vi.fn().mockReturnValue(false),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub();
- fakeGetState.returns({ stories: { all: [editedStory] } });
+ const fakeGetState = vi.fn();
+ fakeGetState.mockReturnValue({ stories: { all: [editedStory] } });
await Story.saveStory(editedStory.id, projectId)(
fakeDispatch,
@@ -40,7 +40,8 @@ describe('Story Actions', () => {
expect(FakeStory.update).toHaveBeenCalledWith(
editedStory._editing,
- projectId
+ projectId,
+ undefined
);
});
@@ -54,15 +55,15 @@ describe('Story Actions', () => {
};
const FakeStory = {
- findById: sinon.stub().returns(editedStory),
- update: sinon.stub().resolves(story),
- isNew: sinon.stub().returns(false),
+ findById: vi.fn().mockReturnValue(editedStory),
+ update: vi.fn().mockResolvedValue(story),
+ isNew: vi.fn().mockReturnValue(false),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub();
- fakeGetState.returns({ stories: { all: [editedStory] } });
+ const fakeGetState = vi.fn();
+ fakeGetState.mockReturnValue({ stories: { all: [editedStory] } });
await Story.saveStory(editedStory.id, projectId)(
fakeDispatch,
@@ -88,16 +89,16 @@ describe('Story Actions', () => {
};
const FakeStory = {
- findById: sinon.stub().returns(editedStory),
- update: sinon.stub().resolves(story),
- isNew: sinon.stub().returns(false),
- needConfirmation: sinon.stub().returns(false),
+ findById: vi.fn().mockReturnValue(editedStory),
+ update: vi.fn().mockResolvedValue(story),
+ isNew: vi.fn().mockReturnValue(false),
+ needConfirmation: vi.fn().mockReturnValue(false),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub();
- fakeGetState.returns({ stories: { all: [editedStory] } });
+ const fakeGetState = vi.fn();
+ fakeGetState.mockReturnValue({ stories: { all: [editedStory] } });
await Story.saveStory(editedStory.id, projectId)(
fakeDispatch,
@@ -119,17 +120,17 @@ describe('Story Actions', () => {
};
const FakeStory = {
- findById: sinon.stub().returns(editedStory),
- post: sinon.stub().resolves(story),
- isNew: sinon.stub().returns(true),
- needConfirmation: sinon.stub().returns(false),
- getHighestNewPosition: sinon.stub().returns(1),
+ findById: vi.fn().mockReturnValue(editedStory),
+ post: vi.fn().mockResolvedValue(story),
+ isNew: vi.fn().mockReturnValue(true),
+ needConfirmation: vi.fn().mockReturnValue(false),
+ getHighestNewPosition: vi.fn().mockReturnValue(1),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- const fakeGetState = sinon.stub();
- fakeGetState.returns({ stories: { all: [editedStory] } });
+ const fakeGetState = vi.fn();
+ fakeGetState.mockReturnValue({ stories: { all: [editedStory] } });
await Story.saveStory(editedStory.id, projectId)(
fakeDispatch,
@@ -161,15 +162,15 @@ describe('Story Actions', () => {
};
const FakeStory = {
- findById: sinon.stub().returns(editedStory),
- update: sinon.stub().rejects(error),
- isNew: sinon.stub().returns(false),
- needConfirmation: sinon.stub().returns(false),
+ findById: vi.fn().mockReturnValue(editedStory),
+ update: vi.fn().mockRejectedValue(error),
+ isNew: vi.fn().mockReturnValue(false),
+ needConfirmation: vi.fn().mockReturnValue(false),
};
- const fakeDispatch = sinon.stub().resolves({});
- const fakeGetState = sinon.stub();
- fakeGetState.returns({ stories: { all: [editedStory] } });
+ const fakeDispatch = vi.fn().mockResolvedValue({});
+ const fakeGetState = vi.fn();
+ fakeGetState.mockReturnValue({ stories: { all: [editedStory] } });
await Story.saveStory(editedStory.id, projectId)(
fakeDispatch,
@@ -190,15 +191,15 @@ describe('Story Actions', () => {
it('calls Story.deleteStory with projectId and storyId', async () => {
const FakeStory = {
- findById: sinon.stub().returns(story),
- deleteStory: sinon.stub().resolves({}),
+ findById: vi.fn().mockReturnValue(story),
+ deleteStory: vi.fn().mockResolvedValue({}),
};
- const fakeGetState = sinon.stub().returns({
+ const fakeGetState = vi.fn().mockReturnValue({
stories: {
all: [story],
},
});
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
await Story.deleteStory(storyId, projectId)(fakeDispatch, fakeGetState, {
Story: FakeStory,
@@ -209,13 +210,13 @@ describe('Story Actions', () => {
it('dispatch deleteStorySuccess', async () => {
const FakeStory = {
- findById: sinon.stub().returns(story),
- deleteStory: sinon.stub().resolves({}),
+ findById: vi.fn().mockReturnValue(story),
+ deleteStory: vi.fn().mockResolvedValue({}),
};
- const fakeGetState = sinon.stub().returns({
+ const fakeGetState = vi.fn().mockReturnValue({
stories: { all: [story] },
});
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
await Story.deleteStory(storyId, projectId)(fakeDispatch, fakeGetState, {
Story: FakeStory,
@@ -230,13 +231,13 @@ describe('Story Actions', () => {
const error = { error: 'boom' };
const FakeStory = {
- findById: sinon.stub().returns(story),
- deleteStory: sinon.stub().rejects(error),
+ findById: vi.fn().mockReturnValue(story),
+ deleteStory: vi.fn().mockRejectedValue(error),
};
- const fakeGetState = sinon.stub().returns({
+ const fakeGetState = vi.fn().mockReturnValue({
stories: { all: [story] },
});
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
await Story.deleteStory(storyId, projectId)(fakeDispatch, fakeGetState, {
Story: FakeStory,
@@ -251,8 +252,8 @@ describe('Story Actions', () => {
describe('highlight', () => {
it('always dispatch updateHighlight', () => {
const storyId = 1;
- const fakeDispatch = sinon.stub().resolves({});
- const fakeGetState = sinon.stub().returns({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
+ const fakeGetState = vi.fn().mockReturnValue({});
Story.highlight(storyId)(fakeDispatch, fakeGetState, {});
@@ -273,17 +274,17 @@ describe('Story Actions', () => {
it('calls Story.sortStories with new position', async () => {
const FakeStory = {
- findById: sinon.stub().returns(updatedStory),
- updatePosition: sinon.stub().resolves(updatedStories),
- isNew: sinon.stub().returns(false),
- addNewAttributes: sinon.stub().returns(story),
- sortOptimistically: sinon.stub().resolves(updatedStories),
+ findById: vi.fn().mockReturnValue(updatedStory),
+ updatePosition: vi.fn().mockResolvedValue(updatedStories),
+ isNew: vi.fn().mockReturnValue(false),
+ addNewAttributes: vi.fn().mockReturnValue(story),
+ sortOptimistically: vi.fn().mockResolvedValue(updatedStories),
};
- const fakeGetState = sinon.stub().returns({
+ const fakeGetState = vi.fn().mockReturnValue({
stories: { all: updatedStories },
});
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
await Story.dragDropStory(
story.id,
@@ -304,18 +305,18 @@ describe('Story Actions', () => {
const error = { error: 'boom' };
const FakeStory = {
- findById: sinon.stub().returns(updatedStory),
- updatePosition: sinon.stub().rejects(error),
- isNew: sinon.stub().returns(false),
- addNewAttributes: sinon.stub().returns(story),
- sortOptimistically: sinon.stub().returns(updatedStory),
+ findById: vi.fn().mockReturnValue(updatedStory),
+ updatePosition: vi.fn().mockRejectedValue(error),
+ isNew: vi.fn().mockReturnValue(false),
+ addNewAttributes: vi.fn().mockReturnValue(story),
+ sortOptimistically: vi.fn().mockReturnValue(updatedStory),
};
- const fakeGetState = sinon.stub().returns({
+ const fakeGetState = vi.fn().mockReturnValue({
stories: { all: updatedStories },
});
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
beforeEach(async () => {
await Story.dragDropStory(story.id, story.projectId, {
@@ -343,13 +344,13 @@ describe('Story Actions', () => {
let confirm;
beforeEach(() => {
- needConfirmation = sinon.stub().returns(false);
- confirm = sinon.stub();
+ needConfirmation = vi.fn().mockReturnValue(false);
+ confirm = vi.fn();
});
describe('and callback.onConfirmed do not throws an error', () => {
it('call callback.onConfirmed', async () => {
- const callback = { onConfirmed: sinon.stub() };
+ const callback = { onConfirmed: vi.fn() };
await Story.confirmBeforeSaveIfNeeded(
story,
@@ -368,9 +369,9 @@ describe('Story Actions', () => {
beforeEach(() => {
error = { error: 'boom' };
callback = {
- onConfirmed: sinon.stub().rejects(error),
- onError: sinon.stub(),
- onCanceled: sinon.stub(),
+ onConfirmed: vi.fn().mockRejectedValue(error),
+ onError: vi.fn(),
+ onCanceled: vi.fn(),
};
});
@@ -416,9 +417,9 @@ describe('Story Actions', () => {
let confirm;
beforeEach(() => {
- callback = { onConfirmed: sinon.stub(), onCanceled: sinon.stub() };
- needConfirmation = sinon.stub().returns(true);
- confirm = sinon.stub().returns(false);
+ callback = { onConfirmed: vi.fn(), onCanceled: vi.fn() };
+ needConfirmation = vi.fn().mockReturnValue(true);
+ confirm = vi.fn().mockReturnValue(false);
});
it('do not call callback.onConfirmed', async () => {
@@ -449,13 +450,13 @@ describe('Story Actions', () => {
let confirm;
beforeEach(() => {
- needConfirmation = sinon.stub().returns(true);
- confirm = sinon.stub().returns(true);
+ needConfirmation = vi.fn().mockResolvedValue(true);
+ confirm = vi.fn().mockResolvedValue(true);
});
describe('and callback.onConfirmed do not throws an error', () => {
it('call callback.onConfirmed', async () => {
- const callback = { onConfirmed: sinon.stub() };
+ const callback = { onConfirmed: vi.fn() };
await Story.confirmBeforeSaveIfNeeded(
story,
@@ -474,9 +475,9 @@ describe('Story Actions', () => {
beforeEach(() => {
error = { error: 'boom' };
callback = {
- onConfirmed: sinon.stub().rejects(error),
- onError: sinon.stub(),
- onCanceled: sinon.stub(),
+ onConfirmed: vi.fn().mockRejectedValue(error),
+ onError: vi.fn(),
+ onCanceled: vi.fn(),
};
});
@@ -524,11 +525,11 @@ describe('Story Actions', () => {
const label = 'label';
beforeEach(() => {
- fakeGetState = jest.fn(() => ({
+ fakeGetState = vi.fn(() => ({
projectBoard: { projectId: 'test-project' },
}));
stories = Array(3).fill(storyFactory());
- fakeDispatch = jest.fn();
+ fakeDispatch = vi.fn();
});
describe('when does not throws an error', () => {
@@ -536,7 +537,7 @@ describe('Story Actions', () => {
beforeEach(() => {
fakeStory = {
- getByLabel: jest.fn().mockResolvedValue(stories),
+ getByLabel: vi.fn().mockResolvedValue(stories),
};
});
diff --git a/spec/javascripts/actions/task_spec.js b/spec/javascripts/actions/task_spec.js
index b72465bc4..ab02e7cb8 100644
--- a/spec/javascripts/actions/task_spec.js
+++ b/spec/javascripts/actions/task_spec.js
@@ -9,43 +9,50 @@ describe('Task Actions', () => {
it('calls FakeTask.newTask with projectId, story and task', async () => {
const FakeTask = {
- post: sinon.stub().resolves(task)
+ post: vi.fn().mockResolvedValue(task),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Task.createTask(projectId, story.id, task)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.createTask(projectId, story.id, task)(fakeDispatch, null, {
+ Task: FakeTask,
+ });
expect(FakeTask.post).toHaveBeenCalledWith(projectId, story.id, task);
});
it('dispatch TaskAdd with story and task', async () => {
const FakeTask = {
- post: sinon.stub().resolves(task)
+ post: vi.fn().mockResolvedValueOnce(task),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValueOnce({});
- await Task.createTask(projectId, story.id, task)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.createTask(projectId, story.id, task)(fakeDispatch, null, {
+ Task: FakeTask,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Task.createTaskSuccess(task, story.id));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Task.createTaskSuccess(task, story.id)
+ );
});
it('dispatches storyFailure when promise fails', async () => {
- const error = { error: "boom" };
+ const error = { error: 'boom' };
const FakeTask = {
- post: sinon.stub().rejects(error)
+ post: vi.fn().mockRejectedValueOnce(error),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValueOnce({});
- await Task.createTask(projectId, story.id, task)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.createTask(projectId, story.id, task)(fakeDispatch, null, {
+ Task: FakeTask,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Story.storyFailure(story.id, error));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Story.storyFailure(story.id, error)
+ );
});
});
@@ -56,43 +63,54 @@ describe('Task Actions', () => {
it('calls FakeTask.destroy with projectId, story and task.id', async () => {
const FakeTask = {
- destroy: sinon.stub().resolves({})
+ destroy: vi.fn().mockRejectedValueOnce({}),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockRejectedValueOnce({});
- await Task.deleteTask(projectId, story.id, task.id)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.deleteTask(projectId, story.id, task.id)(fakeDispatch, null, {
+ Task: FakeTask,
+ });
- expect(FakeTask.destroy).toHaveBeenCalledWith(projectId, story.id, task.id);
+ expect(FakeTask.destroy).toHaveBeenCalledWith(
+ projectId,
+ story.id,
+ task.id
+ );
});
it('dispatch removeTask with story and task.id', async () => {
const FakeTask = {
- destroy: sinon.stub().resolves(task)
+ destroy: vi.fn().mockResolvedValueOnce(task),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValueOnce({});
- await Task.deleteTask(projectId, story.id, task.id)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.deleteTask(projectId, story.id, task.id)(fakeDispatch, null, {
+ Task: FakeTask,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Task.deleteTaskSuccess(task.id, story.id));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Task.deleteTaskSuccess(task.id, story.id)
+ );
});
it('dispatches storyFailure when promise fails', async () => {
- const error = { error: "boom" };
+ const error = { error: 'boom' };
const FakeTask = {
- destroy: sinon.stub().rejects(error)
+ destroy: vi.fn().mockRejectedValueOnce(error),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Task.deleteTask(projectId, story.id, task)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.deleteTask(projectId, story.id, task)(fakeDispatch, null, {
+ Task: FakeTask,
+ });
- expect(fakeDispatch).toHaveBeenCalledWith(Story.storyFailure(story.id, error));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Story.storyFailure(story.id, error)
+ );
});
});
@@ -104,28 +122,43 @@ describe('Task Actions', () => {
it('calls FakeTask.toggle with projectId, story, task and status', async () => {
const FakeTask = {
- toggle: sinon.stub().resolves(task)
+ toggle: vi.fn().mockResolvedValue(task),
};
- const fakeDispatch = sinon.stub().resolves({});
-
- await Task.toggleTask(projectId, story, task, status)
- (fakeDispatch, null, { Task: FakeTask });
-
- expect(FakeTask.toggle).toHaveBeenCalledWith(projectId, story.id, task.id, status);
+ const fakeDispatch = vi.fn().mockResolvedValue({});
+
+ await Task.toggleTask(
+ projectId,
+ story,
+ task,
+ status
+ )(fakeDispatch, null, { Task: FakeTask });
+
+ expect(FakeTask.toggle).toHaveBeenCalledWith(
+ projectId,
+ story.id,
+ task.id,
+ status
+ );
});
it('dispatch toggleTaskSuccess with story and task', async () => {
const FakeTask = {
- toggle: sinon.stub().resolves(task)
+ toggle: vi.fn().mockResolvedValue(task),
};
- const fakeDispatch = sinon.stub().resolves({});
+ const fakeDispatch = vi.fn().mockResolvedValue({});
- await Task.toggleTask(projectId, story, task, status)
- (fakeDispatch, null, { Task: FakeTask });
+ await Task.toggleTask(
+ projectId,
+ story,
+ task,
+ status
+ )(fakeDispatch, null, { Task: FakeTask });
- expect(fakeDispatch).toHaveBeenCalledWith(Task.toggleTaskSuccess(task, story));
+ expect(fakeDispatch).toHaveBeenCalledWith(
+ Task.toggleTaskSuccess(task, story)
+ );
});
});
});
diff --git a/spec/javascripts/collections/story_collection_spec.js b/spec/javascripts/collections/story_collection_spec.js
index 9eb285a8e..d426c0127 100644
--- a/spec/javascripts/collections/story_collection_spec.js
+++ b/spec/javascripts/collections/story_collection_spec.js
@@ -1,42 +1,44 @@
import Story from 'models/story';
import StoryCollection from 'collections/story_collection';
-describe('StoryCollection', function() {
+describe('StoryCollection', function () {
let story1;
let story2;
let story3;
let stories;
- beforeEach(function() {
- story1 = new Story({id: 1, title: "Story 1", position: '10.0'});
- story2 = new Story({id: 2, title: "Story 2", position: '20.0'});
- story3 = new Story({id: 3, title: "Story 3", position: '30.0'});
- story1.labels = story2.labels = story3.labels = function() { return []; };
+ beforeEach(function () {
+ story1 = new Story({ id: 1, title: 'Story 1', position: '10.0' });
+ story2 = new Story({ id: 2, title: 'Story 2', position: '20.0' });
+ story3 = new Story({ id: 3, title: 'Story 3', position: '30.0' });
+ story1.labels =
+ story2.labels =
+ story3.labels =
+ function () {
+ return [];
+ };
stories = new StoryCollection();
stories.url = '/foo';
stories.add([story3, story2, story1]);
});
- describe('position', function() {
-
- it('should return stories in position order', function() {
+ describe('position', function () {
+ it('should return stories in position order', function () {
expect(stories.at(0)).toBe(story1);
expect(stories.at(1)).toBe(story2);
expect(stories.at(2)).toBe(story3);
});
- it('should move between 2 other stories', function() {
-
+ it('should move between 2 other stories', function () {
expect(stories.at(2)).toBe(story3);
- story3.moveBetween(1,2);
+ story3.moveBetween(1, 2);
expect(story3.position()).toEqual(15.0);
expect(stories.at(1).id).toEqual(story3.id);
});
- it('should move after another story', function() {
-
+ it('should move after another story', function () {
expect(stories.at(2)).toBe(story3);
story3.moveAfter(1);
@@ -44,22 +46,21 @@ describe('StoryCollection', function() {
expect(stories.at(1).id).toEqual(story3.id);
});
- it('should move after the last story', function() {
+ it('should move after the last story', function () {
expect(stories.at(2)).toBe(story3);
story1.moveAfter(3);
expect(story1.position()).toEqual(31.0);
expect(stories.at(2).id).toEqual(story1.id);
});
- it('should move before the first story', function() {
+ it('should move before the first story', function () {
expect(stories.at(0)).toBe(story1);
story3.moveBefore(1);
expect(story3.position()).toEqual(5.0);
expect(stories.at(0).id).toEqual(story3.id);
});
- it('should move before another story', function() {
-
+ it('should move before another story', function () {
expect(stories.at(2)).toBe(story3);
story3.moveBefore(2);
@@ -67,111 +68,117 @@ describe('StoryCollection', function() {
expect(stories.at(1).id).toEqual(story3.id);
});
- it('should return the story after a given story', function() {
+ it('should return the story after a given story', function () {
expect(stories.next(story1)).toBe(story2);
// Should return undefined if there is no next story
expect(stories.next(story3)).toBeUndefined();
});
- it('should return the story before a given story', function() {
+ it('should return the story before a given story', function () {
expect(stories.previous(story3)).toBe(story2);
// Should return undefined if there is no previous story
expect(stories.previous(story1)).toBeUndefined();
});
- it("should reset whenever a models position attr changes", function() {
- var spy = sinon.spy();
- stories.on("reset", spy);
- story1.set({position: 0.5});
+ it('should reset whenever a models position attr changes', function () {
+ var spy = vi.fn();
+ stories.on('reset', spy);
+ story1.set({ position: 0.5 });
expect(spy).toHaveBeenCalled();
});
- it("should reset whenever a models state changes", function() {
- var spy = sinon.spy();
- stories.on("reset", spy);
- story1.set({state: 'unstarted'});
+ it('should reset whenever a models state changes', function () {
+ var spy = vi.fn();
+ stories.on('reset', spy);
+ story1.set({ state: 'unstarted' });
expect(spy).toHaveBeenCalled();
});
-
});
- describe('position on columns', function() {
-
- beforeEach(function() {
+ describe('position on columns', function () {
+ beforeEach(function () {
stories.at(0).column = '#backlog';
stories.at(1).column = '#backlog';
stories.at(2).column = '#done';
});
- it('should return the story before a given story in a given column', function() {
+ it('should return the story before a given story in a given column', function () {
expect(stories.previousOnColumn(story2)).toBe(story1);
});
- it('should return the story after a given story in a given column', function() {
+ it('should return the story after a given story in a given column', function () {
expect(stories.nextOnColumn(story1)).toBe(story2);
});
- it('should return undefined when there is no next or previous story in a given column',
- function() {
- expect(stories.nextOnColumn(story2)).toBeUndefined();
- expect(stories.previousOnColumn(story1)).toBeUndefined();
- expect(stories.previousOnColumn(story3)).toBeUndefined();
- }
- );
-
+ it('should return undefined when there is no next or previous story in a given column', function () {
+ expect(stories.nextOnColumn(story2)).toBeUndefined();
+ expect(stories.previousOnColumn(story1)).toBeUndefined();
+ expect(stories.previousOnColumn(story3)).toBeUndefined();
+ });
});
- describe("columns", function() {
-
- it("should return all stories in the done column", function() {
+ describe('columns', function () {
+ it('should return all stories in the done column', function () {
expect(stories.column('#done')).toEqual([]);
story1.column = '#done';
expect(stories.column('#done')).toEqual([story1]);
});
- it("returns a set of columns", function() {
+ it('returns a set of columns', function () {
story1.column = '#done';
story2.column = '#current';
story3.column = '#backlog';
- expect(stories.columns(['#backlog', '#current', '#done']))
- .toEqual([story3,story2,story1]);
+ expect(stories.columns(['#backlog', '#current', '#done'])).toEqual([
+ story3,
+ story2,
+ story1,
+ ]);
});
-
});
- describe("labels", function() {
-
- it("should initialize with an empty labels list", function() {
+ describe('labels', function () {
+ it('should initialize with an empty labels list', function () {
expect(stories.labels).toEqual([]);
});
- it("should add labels to the list", function() {
- expect(stories.addLabels(["foo","bar","baz"])).toEqual(["foo","bar","baz"]);
- expect(stories.labels).toEqual(["foo","bar","baz"]);
+ it('should add labels to the list', function () {
+ expect(stories.addLabels(['foo', 'bar', 'baz'])).toEqual([
+ 'foo',
+ 'bar',
+ 'baz',
+ ]);
+ expect(stories.labels).toEqual(['foo', 'bar', 'baz']);
// Should add to the array
- expect(stories.addLabels(["boo"])).toEqual(["foo","bar","baz","boo"]);
- expect(stories.labels).toEqual(["foo","bar","baz","boo"]);
+ expect(stories.addLabels(['boo'])).toEqual(['foo', 'bar', 'baz', 'boo']);
+ expect(stories.labels).toEqual(['foo', 'bar', 'baz', 'boo']);
// Should add to the array, ignoring duplicates
- expect(stories.addLabels(["foo", "bun"])).toEqual(["foo","bar","baz","boo","bun"]);
- expect(stories.labels).toEqual(["foo","bar","baz","boo","bun"]);
+ expect(stories.addLabels(['foo', 'bun'])).toEqual([
+ 'foo',
+ 'bar',
+ 'baz',
+ 'boo',
+ 'bun',
+ ]);
+ expect(stories.labels).toEqual(['foo', 'bar', 'baz', 'boo', 'bun']);
});
- it("should add labels when adding a story", function() {
+ it('should add labels when adding a story', function () {
var Story = Backbone.Model.extend({
name: 'story',
- labels: sinon.stub(),
- position: function() { return 1; }
+ labels: vi.fn(),
+ position: function () {
+ return 1;
+ },
});
var story = new Story({});
- story.labels.returns(["dummy", "labels"]);
+ story.labels.mockReturnValueOnce(['dummy', 'labels']);
expect(stories.labels).toEqual([]);
stories.add(story);
- expect(stories.labels).toEqual(["dummy", "labels"]);
+ expect(stories.labels).toEqual(['dummy', 'labels']);
});
-
});
});
diff --git a/spec/javascripts/components/columns/column_item_spec.js b/spec/javascripts/components/columns/column_item_spec.js
index 6a599eb04..0454bd45e 100644
--- a/spec/javascripts/components/columns/column_item_spec.js
+++ b/spec/javascripts/components/columns/column_item_spec.js
@@ -1,50 +1,53 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import { Column } from 'components/Columns/ColumnItem';
describe('', () => {
- const render = overrideProps => {
+ const renderComponent = overrideProps => {
const defaultProps = {
title: '',
- onClose: sinon.stub(),
+ onClose: vi.fn(),
canClose: true,
children: '',
- renderAction: sinon.stub(),
- providedProps: { },
- placeholder: ''
+ renderAction: vi.fn(),
+ providedProps: {},
+ placeholder: '',
};
- const wrapper = shallow();
- const column = wrapper.find('[data-id="column"]');
- const title = wrapper.find('[data-id="column-title"]');
- const button = wrapper.find('[data-id="column-button"]');
- const children = wrapper.find('[data-id="column-children"]');
- return { wrapper, title, button, children, column };
+ const { container } = render(
+
+ );
+ const column = container.querySelector('.Column');
+ const title = container.querySelector('.Column__name');
+ const button = container.querySelector('.Column__btn-close');
+ const children = container.querySelector('.Column__body');
+
+ return { title, button, children, column };
};
it('renders the component', () => {
- const { column } = render();
+ const { column } = renderComponent();
- expect(column.exists()).toBeTruthy();
+ expect(column).toBeInTheDocument();
});
it('renders the title', () => {
const titleText = 'title';
- const { title } = render({ title: titleText });
+ const { title } = renderComponent({ title: titleText });
- expect(title.text()).toBe(titleText);
+ expect(title.innerHTML).toBe(titleText);
});
it('renders the children', () => {
const childrenContent = 'children!';
- const { children } = render({ children: childrenContent });
+ const { children } = renderComponent({ children: childrenContent });
- expect(children.text()).toBe(childrenContent);
+ expect(children.innerHTML).toBe(childrenContent);
});
it('calls renderAction', () => {
- const renderAction = sinon.stub();
- render({ renderAction });
+ const renderAction = vi.fn();
+ renderComponent({ renderAction });
expect(renderAction).toHaveBeenCalled();
});
@@ -52,25 +55,25 @@ describe('', () => {
describe('button', () => {
describe('when canClose is true', () => {
it('renders button', () => {
- const { button } = render();
+ const { button } = renderComponent();
- expect(button.exists()).toBeTruthy();
+ expect(button).toBeInTheDocument();
});
});
describe('when canClose is false', () => {
it('does not render the button', () => {
- const { button } = render({ canClose: false });
+ const { button } = renderComponent({ canClose: false });
- expect(button.exists()).toBeFalsy();
+ expect(button).not.toBeInTheDocument();
});
describe('when button is clicked', () => {
it('calls onClose', () => {
- const onClose = sinon.stub();
- const { button } = render({ onClose });
- button.simulate('click');
-
+ const onClose = vi.fn();
+ const { button } = renderComponent({ onClose });
+ fireEvent.click(button);
+
expect(onClose).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/components/columns/columns_spec.js b/spec/javascripts/components/columns/columns_spec.js
index bb6ed5233..205f3bc4e 100644
--- a/spec/javascripts/components/columns/columns_spec.js
+++ b/spec/javascripts/components/columns/columns_spec.js
@@ -1,27 +1,23 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import Columns from 'components/Columns';
describe('', () => {
- const render = props => {
- const defaultProps = {
- canClose: true,
- chillyBinStories: [],
- backlogSprints: [],
- doneSprints: [],
- fetchPastStories: sinon.stub(),
- toggleColumn: sinon.stub(),
- createStory: sinon.stub(),
- visibleColumns: {},
- reverse: false,
- }
-
- return shallow();
+ const defaultProps = {
+ canClose: true,
+ chillyBinStories: [],
+ backlogSprints: [],
+ doneSprints: [],
+ fetchPastStories: vi.fn(),
+ toggleColumn: vi.fn(),
+ createStory: vi.fn(),
+ visibleColumns: {},
+ reverse: false,
};
it('renders the component', () => {
- const columns = render();
+ const columns = render();
- expect(columns.exists()).toBeTruthy();
+ expect(columns.container).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/forms/checkbox_spec.js b/spec/javascripts/components/forms/checkbox_spec.js
index 3e679ae41..ddfc9655b 100644
--- a/spec/javascripts/components/forms/checkbox_spec.js
+++ b/spec/javascripts/components/forms/checkbox_spec.js
@@ -1,24 +1,21 @@
import React from 'react';
-import { shallow } from 'enzyme';
-
+import { render } from '@testing-library/react';
import Checkbox from 'components/forms/Checkbox';
-describe('', function() {
- it("should accept a label and children elements", function() {
- const wrapper = shallow(
-
- { 'Children' }
+describe('', function () {
+ it('should accept a label and children elements', function () {
+ const { container } = render(
+
+ {'Children'}
);
- expect(wrapper).toExist();
- });
- it("should not break if it has no children elements", function() {
- const onSubmit = sinon.stub().returns($.Deferred());
- const wrapper = shallow(
-
- );
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
+ it('should not break if it has no children elements', function () {
+ const { container } = render();
+
+ expect(container).toBeInTheDocument();
+ });
});
diff --git a/spec/javascripts/components/markdown_spec.js b/spec/javascripts/components/markdown_spec.js
index 6d254337a..83136481e 100644
--- a/spec/javascripts/components/markdown_spec.js
+++ b/spec/javascripts/components/markdown_spec.js
@@ -1,23 +1,23 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import Markdown from 'components/Markdown';
describe('', () => {
const source = 'some text';
beforeEach(() => {
- sinon.stub(window.md, 'makeHtml').returns(source);
+ vi.spyOn(window.md, 'makeHtml').mockReturnValueOnce(source);
});
afterEach(() => {
- window.md.makeHtml.restore();
+ window.md.makeHtml.mockRestore();
});
describe('When source isnt null', () => {
it('renders the source text with markdown', () => {
- const wrapper = shallow();
+ const { container } = render();
- expect(wrapper.text()).toContain(source);
+ expect(container.innerHTML).toContain(source);
});
});
});
diff --git a/spec/javascripts/components/notes/note_form_spec.js b/spec/javascripts/components/notes/note_form_spec.js
index 3c42a188b..f7d0f1f53 100644
--- a/spec/javascripts/components/notes/note_form_spec.js
+++ b/spec/javascripts/components/notes/note_form_spec.js
@@ -1,35 +1,31 @@
import React from 'react';
-import { mount } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import NoteForm from 'components/notes/NoteForm';
import Note from 'models/note.js';
-describe('', function() {
+describe('', function () {
let note;
- beforeEach(function() {
- note = new Note({note: ''});
- sinon.stub(I18n, 't');
- sinon.stub(window.md, 'makeHtml');
- sinon.stub(note, 'save');
+ beforeEach(function () {
+ note = new Note({ note: '' });
+ vi.spyOn(I18n, 't');
+ vi.spyOn(window.md, 'makeHtml');
+ vi.spyOn(note, 'save');
});
- afterEach(function() {
- I18n.t.restore();
- window.md.makeHtml.restore();
- note.save.restore();
+ afterEach(function () {
+ I18n.t.mockRestore();
+ window.md.makeHtml.mockRestore();
+ note.save.mockRestore();
});
- it("should have an onSubmit callback", function() {
- const onSubmit = sinon.stub().returns($.Deferred());
- const wrapper = mount(
-
- );
- wrapper.find('.add-note').simulate('click');
+ it('should have an onSubmit callback', function () {
+ const onSubmit = vi.fn().mockReturnValueOnce($.Deferred());
+ const { container } = render();
+ const addNoteButton = container.querySelector('.add-note');
+ fireEvent.click(addNoteButton);
+
expect(onSubmit).toHaveBeenCalled();
});
-
});
diff --git a/spec/javascripts/components/notes/note_spec.js b/spec/javascripts/components/notes/note_spec.js
index 675b00449..d3d0ab2c3 100644
--- a/spec/javascripts/components/notes/note_spec.js
+++ b/spec/javascripts/components/notes/note_spec.js
@@ -1,13 +1,13 @@
import React from 'react';
-import { render } from "@testing-library/react";
+import { render } from '@testing-library/react';
import { screen } from '@testing-library/dom';
-import userEvent from "@testing-library/user-event";
+import userEvent from '@testing-library/user-event';
import NoteComponent from 'components/notes/Note';
import Note from 'models/note.js';
global.document.createRange = () => ({
- setStart: () => { },
- setEnd: () => { },
+ setStart: () => {},
+ setEnd: () => {},
commonAncestorContainer: {
nodeName: 'BODY',
ownerDocument: document,
@@ -16,58 +16,59 @@ global.document.createRange = () => ({
describe('', () => {
beforeEach(() => {
- window.document.getSelection = jest.fn();
- jest.spyOn(I18n, 't');
- jest.spyOn(window.md, 'makeHtml');
+ window.document.getSelection = vi.fn();
+ vi.spyOn(I18n, 't');
+ vi.spyOn(window.md, 'makeHtml');
});
- const setup = (data) => {
+ const setup = data => {
let note;
note = new Note({ note: 'Test Note' });
- const onDelete = jest.fn();
+ const onDelete = vi.fn();
- render();
+ render(
+
+ );
return { onDelete };
- }
+ };
afterEach(() => {
I18n.t.mockClear();
window.md.makeHtml.mockClear();
});
- it("should have its content parsed", () => {
+ it('should have its content parsed', () => {
setup();
const expectedNote = 'Test Note';
expect(window.md.makeHtml).toHaveBeenCalledWith(expectedNote);
});
- it("should be able to call onDelete", async () => {
+ it('should be able to call onDelete', async () => {
const { onDelete } = setup();
- const deleteButton = screen.getByRole("button", { name: /Delete/i });
+ const deleteButton = screen.getByRole('button', { name: /Delete/i });
await userEvent.click(deleteButton);
expect(onDelete).toHaveBeenCalled();
});
- describe("when not disabled", () => {
-
- it("should have an delete button", () => {
+ describe('when not disabled', () => {
+ it('should have an delete button', () => {
setup();
- const deleteButton = screen.getByRole("button", { name: /Delete/i });
+ const deleteButton = screen.getByRole('button', { name: /Delete/i });
expect(deleteButton).toBeInTheDocument();
});
-
});
- describe("when disabled", () => {
-
- it("should not have a delete button", () => {
+ describe('when disabled', () => {
+ it('should not have a delete button', () => {
setup({ disabled: true });
- const deleteButton = screen.queryByRole("button", { name: /Delete/i });
+ const deleteButton = screen.queryByRole('button', { name: /Delete/i });
expect(deleteButton).not.toBeInTheDocument();
});
-
});
-
});
diff --git a/spec/javascripts/components/notifications/message_spec.js b/spec/javascripts/components/notifications/message_spec.js
index 48b44304e..8cf14afab 100644
--- a/spec/javascripts/components/notifications/message_spec.js
+++ b/spec/javascripts/components/notifications/message_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import Message from 'components/Notifications/Message';
describe('', () => {
@@ -7,47 +7,38 @@ describe('', () => {
type: 'success',
className: 'Notifications__Message',
message: 'success',
- onRemove: sinon.stub()
+ onRemove: vi.fn(),
});
it('renders component with the right type on className', () => {
const messageType = 'error';
- const wrapper = shallow(
-
+ const { getByTestId } = render(
+
);
- expect(wrapper.find(`.Message--${messageType}`)).toExist();
+ expect(getByTestId('message-container')).toBeInTheDocument();
});
it('renders component with the right message', () => {
const message = 'error message';
- const wrapper = shallow(
-
+ const { getByText } = render(
+
);
- expect(wrapper.text()).toContain(message);
+ expect(getByText(message)).toBeDefined();
});
it('calls onRemove when click on the remove button', () => {
- const onRemove = sinon.stub();
+ const onRemove = vi.fn();
- const wrapper = shallow(
-
+ const { container } = render(
+
);
- const button = wrapper.find('#close-button');
- button.simulate('click');
+ const closeButton = container.querySelector('.Message__content__button');
+ fireEvent.click(closeButton);
expect(onRemove).toHaveBeenCalled();
});
diff --git a/spec/javascripts/components/notifications/notifications_spec.js b/spec/javascripts/components/notifications/notifications_spec.js
index 5375c6d4d..161497bc4 100644
--- a/spec/javascripts/components/notifications/notifications_spec.js
+++ b/spec/javascripts/components/notifications/notifications_spec.js
@@ -1,27 +1,24 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import Notifications from 'components/Notifications';
describe('', () => {
const defaultProps = () => ({
messages: [],
- onRemove: sinon.stub()
+ onRemove: vi.fn(),
});
it('renders component with the right number of messages', () => {
const notifications = [
- { id: 1, message: 'message1', type: 'success' },
- { id: 2, message: 'message2', type: 'error' },
- { id: 3, message: 'message3' }
+ { id: 1, message: 'message', type: 'success' },
+ { id: 2, message: 'message', type: 'error' },
+ { id: 3, message: 'message' },
];
- const wrapper = shallow(
-
+ const { getAllByText } = render(
+
);
- expect(wrapper.find('Message').length).toBe(notifications.length);
+ expect(getAllByText('message').length).toBe(notifications.length);
});
});
diff --git a/spec/javascripts/components/projects/project_board_spec.js b/spec/javascripts/components/projects/project_board_spec.js
index 2d01b89b8..a27108361 100644
--- a/spec/javascripts/components/projects/project_board_spec.js
+++ b/spec/javascripts/components/projects/project_board_spec.js
@@ -1,135 +1,172 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import ReactDOM from 'react-dom';
import { ProjectBoard } from 'components/projects/ProjectBoard';
import storyFactory from '../../support/factories/storyFactory';
+import { renderWithProviders } from '../setupRedux';
+import { beforeAll } from 'vitest';
-jest.mock('../../../../app/assets/javascripts/pusherSockets', () => ({
- subscribeToProjectChanges: jest.fn(),
+vi.mock('../../../../app/assets/javascripts/pusherSockets', () => ({
+ subscribeToProjectChanges: vi.fn(),
}));
describe('', () => {
- const render = props => {
+ const COLUMNS_QUANTITY_STD = 3;
+
+ const renderComponent = props => {
const defaultProps = {
projectBoard: {
isFetched: false,
isInitialLoading: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
doneSprints: [],
backlogSprints: [],
- fetchProjectBoard: sinon.stub(),
- createStory: sinon.stub(),
- closeHistory: sinon.stub(),
+ fetchProjectBoard: vi.fn(),
+ createStory: vi.fn(),
+ closeHistory: vi.fn(),
notifications: [],
history: {
- status: 'DISABLED'
+ status: 'DISABLED',
},
- onRemove: sinon.stub(),
- removeNotification: sinon.stub(),
- toggleColumn: sinon.stub(),
- reverseColumns: sinon.stub(),
+ onRemove: vi.fn(),
+ removeNotification: vi.fn(),
+ toggleColumn: vi.fn(),
+ reverseColumns: vi.fn(),
projectId: '1',
- fetchPastStories: sinon.stub(),
- epicStories: []
+ fetchPastStories: vi.fn(),
+ epicStories: [],
+ chillyBinStories: [],
};
- return shallow();
+ const mergedProps = {
+ ...defaultProps,
+ ...props,
+ projectBoard: {
+ ...defaultProps.projectBoard,
+ ...props?.projectBoard,
+ search: {
+ ...defaultProps.projectBoard.search,
+ ...props?.projectBoard?.search,
+ },
+ visibleColumns: {
+ ...defaultProps.projectBoard.visibleColumns,
+ ...props?.projectBoard?.visibleColumns,
+ },
+ },
+ history: {
+ ...defaultProps.history,
+ ...props?.history,
+ },
+ };
+
+ return renderWithProviders(, {
+ preloadedState: {
+ project: {
+ id: 1,
+ },
+ },
+ });
};
- describe('when projectBoard.isFetched is false and projectBoard.isInitialLoading is true', () => {
+ beforeAll(() => {
+ ReactDOM.createPortal = vi.fn(element => {
+ return element;
+ });
+ });
+
+ afterEach(() => {
+ ReactDOM.createPortal.mockClear();
+ });
+
+ describe('when projectBoard.isFetched is false and projectBoard.isInitialLoading is true', () => {
it('renders ', () => {
- const wrapper = render();
- const spinnerLoading = wrapper.find('[data-id="project-loading"]');
+ const { container } = renderComponent();
- expect(spinnerLoading.exists()).toBeTruthy();
+ expect(
+ container.querySelector('.ProjectBoard-loading')
+ ).toBeInTheDocument();
});
});
describe('when projectBoard.isFetched is true and projectBoard.isInitialLoading is false', () => {
it('does not renders ', () => {
- const wrapper = render({
+ const { container } = renderComponent({
projectBoard: {
isFetched: true,
isInitialLoading: false,
- search: {
- loading: false
- },
- visibleColumns: {
- backlog: true,
- done: true,
- chillyBin: true
- },
- reverse: true
},
});
- const spinnerLoading = wrapper.find('[data-id="project-loading"]');
- expect(spinnerLoading.exists()).toBeFalsy();
+ expect(
+ container.querySelector('.ProjectBoard-loading')
+ ).not.toBeInTheDocument();
});
it('renders ', () => {
- const wrapper = render({
+ const { container } = renderComponent({
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
+ chillyBin: true,
},
- reverse: true
- }
+ reverse: true,
+ },
});
- expect(wrapper.find('[data-id="side-bar"]')).toExist();
+ expect(container.querySelector('.SideBar')).toBeInTheDocument();
});
it('render ', () => {
- const wrapper = render({
+ const { container } = renderComponent({
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
+ chillyBin: true,
},
- reverse: true
+ reverse: true,
},
});
- expect(wrapper.find('[data-id="notifications"]')).toExist();
+ expect(container.querySelector('.Notifications')).toBeInTheDocument();
});
it('render ', () => {
- const wrapper = render({
+ const { container } = renderComponent({
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
+ chillyBin: true,
},
- reverse: true
+ reverse: true,
},
});
- expect(wrapper.find('[data-id="columns"]')).toExist();
+ expect(container.querySelectorAll('.Column').length).toBe(
+ COLUMNS_QUANTITY_STD
+ );
});
});
@@ -138,38 +175,40 @@ describe('', () => {
history: {
status: 'LOADING',
storyTitle: 'I am title!',
- activities: []
+ activities: [],
},
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
};
it('renders history column', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history-column"]')).toExist();
+ expect(container).toBeInTheDocument();
});
it('does not render history', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history"]')).not.toExist();
+ expect(container.querySelector('.History')).not.toBeInTheDocument();
});
it('renders loading', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="project-loading"]')).toExist();
+ expect(
+ container.querySelector('.ProjectBoard-loading')
+ ).toBeInTheDocument();
});
});
@@ -178,38 +217,42 @@ describe('', () => {
history: {
status: 'LOADED',
storyTitle: 'I am title!',
- activities: []
+ activities: [],
},
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
};
it('renders history column', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history-column"]')).toExist();
+ expect(container.querySelectorAll('.Column').length).toBe(
+ COLUMNS_QUANTITY_STD + 1
+ );
});
it('renders history', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history"]')).toExist();
+ expect(container.querySelector('.History')).toBeInTheDocument();
});
it('does not render loading', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="project-loading"]')).not.toExist();
+ expect(
+ container.querySelector('.ProjectBoard-loading')
+ ).not.toBeInTheDocument();
});
});
@@ -218,38 +261,42 @@ describe('', () => {
history: {
status: 'DISABLED',
storyTitle: 'I am title!',
- activities: []
+ activities: [],
},
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
};
it('does not render history column', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history-column"]')).not.toExist();
+ expect(container.querySelectorAll('.Column').length).toBe(
+ COLUMNS_QUANTITY_STD
+ );
});
it('does not render history', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history"]')).not.toExist();
+ expect(container.querySelector('.History')).not.toBeInTheDocument();
});
it('does not render loading', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="project-loading"]')).not.toExist();
+ expect(
+ container.querySelector('.ProjectBoard-loading')
+ ).not.toBeInTheDocument();
});
});
@@ -258,84 +305,97 @@ describe('', () => {
history: {
status: 'FAILED',
storyTitle: 'I am title!',
- activities: []
+ activities: [],
},
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
};
it('renders history column', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history-column"]')).toExist();
+ expect(container.querySelectorAll('.Column').length).toBe(
+ COLUMNS_QUANTITY_STD + 1
+ );
});
it('does not render history', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="history"]')).not.toExist();
+ expect(container.querySelector('.History')).not.toBeInTheDocument();
});
it('renders loading', () => {
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="project-loading"]')).toExist();
+ expect(
+ container.querySelector('.ProjectBoard-loading')
+ ).toBeInTheDocument();
});
});
describe('when there are epicStories', () => {
+ beforeAll(() => {
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+ });
+
it('renders epic column', () => {
const props = {
epicStories: [storyFactory()],
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
};
- const wrapper = render(props);
- expect(wrapper.find('[data-id="epic-column"]')).toExist();
+ const { container } = renderComponent(props);
+
+ expect(container.querySelectorAll('.Column').length).toBe(
+ COLUMNS_QUANTITY_STD + 1
+ );
});
});
describe('when epicStories is empty', () => {
it('does not render epic column', () => {
const props = {
- epicStories: [ ],
+ epicStories: [],
projectBoard: {
isFetched: true,
search: {
- loading: false
+ loading: false,
},
reverse: false,
visibleColumns: {
backlog: true,
done: true,
- chillyBin: true
- }
+ chillyBin: true,
+ },
},
};
- const wrapper = render(props);
+ const { container } = renderComponent(props);
- expect(wrapper.find('[data-id="epic-column"]')).not.toExist();
+ expect(container.querySelectorAll('.Column').length).toBe(
+ COLUMNS_QUANTITY_STD
+ );
});
});
});
diff --git a/spec/javascripts/components/projects/project_card_spec.js b/spec/javascripts/components/projects/project_card_spec.js
index b6130557b..9effd903f 100644
--- a/spec/javascripts/components/projects/project_card_spec.js
+++ b/spec/javascripts/components/projects/project_card_spec.js
@@ -1,34 +1,35 @@
import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { render } from '@testing-library/react';
import ProjectCard from 'components/projects/ProjectCard';
import User from 'models/user';
import Project from 'models/project';
+import { expect } from 'vitest';
-const user = new User({ 'user': { 'id': 1 } });
+const user = new User({ user: { id: 1 } });
-const projectFactory = (tag_name) => {
+const projectFactory = tag_name => {
const defaultObj = {
- 'name': 'Foobar',
- 'slug': 'foobar',
- 'path_to': {
- 'project': "/projects/foobar",
- 'projectReports': "/projects/foobar/reports",
- 'projectUsers': "/projects/foobar/users",
- 'projectSettings': "/projects/foobar/edit",
- 'projectJoin': "/projects/foobar/join",
- 'projectUnjoin': "/projects/foobar/users/"
+ name: 'Foobar',
+ slug: 'foobar',
+ path_to: {
+ project: '/projects/foobar',
+ projectReports: '/projects/foobar/reports',
+ projectUsers: '/projects/foobar/users',
+ projectSettings: '/projects/foobar/edit',
+ projectJoin: '/projects/foobar/join',
+ projectUnjoin: '/projects/foobar/users/',
},
- 'archived_at': null,
- 'velocity': '10',
- 'volatility': "0%",
- 'tag_name': tag_name,
- 'tag_bg_color': "#2075F3",
- 'tag_fore_color': "#FFFFFF",
- 'users_avatar': ["https://secure.gravatar.com/avatar/foobar.png"]
- }
- return new Project(defaultObj)
-}
+ archived_at: null,
+ velocity: '10',
+ volatility: '0%',
+ tag_name: tag_name,
+ tag_bg_color: '#2075F3',
+ tag_fore_color: '#FFFFFF',
+ users_avatar: ['https://secure.gravatar.com/avatar/foobar.png'],
+ };
+ return new Project(defaultObj);
+};
describe('', () => {
let defaultProps;
@@ -39,118 +40,87 @@ describe('', () => {
project: projectFactory(),
user: user,
joined: true,
- key: 1
+ key: 1,
};
propsWithTag = {
project: projectFactory('tag-foo'),
user: user,
joined: true,
- key: 1
+ key: 1,
};
});
describe('joined', () => {
- it('should have project, user and joined props', () => {
- const wrapper = mount();
- expect(wrapper.prop('project')).toBe(defaultProps.project);
- expect(wrapper.prop('user')).toBe(defaultProps.user);
- expect(wrapper.prop('joined')).toBe(true);
- });
-
it('should contain the Project name', () => {
- const wrapper = shallow();
- expect(wrapper.find('.card-title').text()).toContain('Foobar');
+ const { getByText } = render();
+ expect(getByText('Foobar')).toBeInTheDocument();
});
describe('#panelHeading', () => {
describe('.icons', () => {
it('should have report icon', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
- insert_chart
-
- )).toBe(true);
+ const { getByTestId } = render();
+ expect(getByTestId('report-icon-anchor')).toBeInTheDocument();
});
it('should have group icon', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
- group
-
- )).toBe(true);
+ const { getByTestId } = render();
+ expect(getByTestId('user-icon-anchor')).toBeInTheDocument();
});
it('should have settings icon', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
- settings
-
- )).toBe(true);
+ const { getByTestId } = render();
+ expect(getByTestId('settings-icon-anchor')).toBeInTheDocument();
});
});
describe('.card-tag', () => {
describe('When there is a tag', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = mount();
- });
-
it('has the tag name', () => {
- expect(wrapper.find('.card-tag')).toHaveText(defaultProps.project.get("tag_name"));
+ const { getByText } = render();
+
+ expect(
+ getByText(propsWithTag.project.get('tag_name'))
+ ).toBeInTheDocument();
});
it('has the background and foreground defined', () => {
- expect(wrapper.find('.card-tag')).toHaveStyle({ backgroundColor: '#2075F3', color: '#FFFFFF' });
+ const { container } = render();
+ const component = container.querySelector('.card-tag');
+
+ expect(component.style.backgroundColor).toBe('rgb(32, 117, 243)');
+ expect(component.style.color).toBe('rgb(255, 255, 255)');
});
});
it('does not have the tag', () => {
- const wrapper = mount();
- expect(wrapper.contains(
- {defaultProps.project.get("tag_name")}
- )).toBe(false);
+ propsWithTag.project.set('tag_name', null);
+ const { container } = render();
+
+ expect(container.querySelector('.card-tag')).not.toBeInTheDocument();
});
});
describe('.dropdown-menu', () => {
it('should contain dropdown-menu', () => {
- const wrapper = shallow();
- expect(wrapper.find('ul.dropdown-menu')).toHaveClassName('dropdown-menu');
+ const { container } = render();
+
+ expect(container.querySelector('.dropdown-menu')).toHaveClass(
+ 'dropdown-menu'
+ );
});
it('should contain settings link', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
- {I18n.t('settings')}
-
- )).toBe(true);
+ const { getByText } = render();
+
+ expect(getByText(I18n.t('settings'))).toBeInTheDocument();
});
it('should contain unjoin project link', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
- {I18n.t('projects.unjoin')}
-
- )).toBe(true);
+ const { getByText } = render();
+
+ expect(getByText(I18n.t('projects.unjoin'))).toBeInTheDocument();
});
});
});
@@ -158,27 +128,18 @@ describe('', () => {
describe('#panelBody', () => {
describe('not archived', () => {
it('should contain users avatar', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
-
- -
-
-
-
-
- )).toBe(true);
+ const { container } = render();
+
+ expect(container.querySelector('.member')).toBeInTheDocument();
});
});
describe('archived', () => {
it('should not contain unable to join message', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
- {I18n.t('projects.unable_to_join')}
-
- )).toBe(false);
+ const { queryByText } = render();
+ expect(
+ queryByText(I18n.t('projects.unable_to_join'))
+ ).not.toBeInTheDocument();
});
});
});
@@ -186,68 +147,50 @@ describe('', () => {
describe('#cardLink', () => {
describe('unarchived', () => {
it('should contain SELECT PROJECT button', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
- {I18n.t('projects.select')}
- )).toBe(true);
+ const { getByText } = render();
+ expect(getByText(I18n.t('projects.select'))).toBeInTheDocument();
});
});
describe('archived', () => {
it('should contain ARCHIVED AT date', () => {
defaultProps.project.set('archived_at', '2015/08/28 16:21:57 -0300');
- const wrapper = shallow();
- expect(wrapper.contains(
- {I18n.t('archived_at')} {"2015/08/28 16:21:57 -0300"}
- )).toBe(true);
+ const { getByText } = render();
+
+ expect(
+ getByText(`${I18n.t('archived_at')} 2015/08/28 16:21:57 -0300`)
+ ).toBeInTheDocument();
});
});
});
});
describe('unjoined', () => {
- it('should have project, user and joined props', () => {
- defaultProps.joined = false;
-
- const wrapper = mount();
- expect(wrapper.props()).toEqual({ project: defaultProps.project, user: defaultProps.user, joined: false });
- });
-
it('should contain the Project name', () => {
defaultProps.joined = false;
- const wrapper = shallow();
- expect(wrapper.contains(
-
- Foobar
-
- )).toBe(true);
+ const { getByText } = render();
+ expect(getByText('Foobar')).toBeInTheDocument();
});
describe('#panelHeading', () => {
describe('.icons', () => {
it('should not have report icon', () => {
defaultProps.joined = false;
+ const { queryByTestId } = render();
- const wrapper = shallow();
- expect(wrapper.contains(
-
- insert_chart
-
- )).toBe(false);
+ expect(queryByTestId('report-icon-anchor')).not.toBeInTheDocument();
});
});
describe('.dropdown-menu', () => {
it('should not contain dropdown-menu', () => {
defaultProps.joined = false;
+ const { container } = render();
- const wrapper = shallow();
- expect(wrapper.find('ul.dropdown-menu')).not.toHaveClassName('dropdown-menu');
+ expect(
+ container.querySelector('.dropdown-menu')
+ ).not.toBeInTheDocument();
});
});
});
@@ -257,13 +200,11 @@ describe('', () => {
it('should contain "to view more join" message', () => {
defaultProps.joined = false;
defaultProps.project.set('archived_at', null);
+ const { getByText } = render();
- const wrapper = shallow();
- expect(wrapper.contains(
-
- {I18n.t('projects.to_view_more_join')}
-
- )).toBe(true);
+ expect(
+ getByText(I18n.t('projects.to_view_more_join'))
+ ).toBeInTheDocument();
});
});
@@ -271,13 +212,11 @@ describe('', () => {
it('should contain "unable to join" message', () => {
defaultProps.joined = false;
defaultProps.project.set('archived_at', '9999/99/99 99:99:99 -9999');
+ const { getByText } = render();
- const wrapper = shallow();
- expect(wrapper.contains(
-
- {I18n.t('projects.unable_to_join')}
-
- )).toBe(true);
+ expect(
+ getByText(I18n.t('projects.unable_to_join'))
+ ).toBeInTheDocument();
});
});
});
@@ -287,11 +226,9 @@ describe('', () => {
it('should contain Join Project button', () => {
defaultProps.joined = false;
defaultProps.project.set('archived_at', null);
+ const { getByText } = render();
- const wrapper = shallow();
- expect(wrapper.contains(
- {I18n.t('projects.join')}
- )).toBe(true);
+ expect(getByText(I18n.t('projects.join'))).toBeInTheDocument();
});
});
@@ -299,11 +236,11 @@ describe('', () => {
it('should contain ARCHIVED AT date', () => {
defaultProps.joined = false;
defaultProps.project.set('archived_at', '9999/99/99 99:99:99 -9999');
+ const { getByText } = render();
- const wrapper = shallow();
- expect(wrapper.contains(
- {I18n.t('archived_at')} {'9999/99/99 99:99:99 -9999'}
- )).toBe(true);
+ expect(
+ getByText(`${I18n.t('archived_at')} 9999/99/99 99:99:99 -9999`)
+ ).toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/projects/project_list_spec.js b/spec/javascripts/components/projects/project_list_spec.js
index 6ba3082c9..a861c553e 100644
--- a/spec/javascripts/components/projects/project_list_spec.js
+++ b/spec/javascripts/components/projects/project_list_spec.js
@@ -1,7 +1,6 @@
import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { render } from '@testing-library/react';
import ProjectList from 'components/projects/ProjectList';
-import ProjectCard from 'components/projects/ProjectCard';
import ProjectCollection from 'collections/project_collection';
import User from 'models/user';
@@ -10,13 +9,13 @@ describe('', () => {
beforeEach(() => {
user = new User({
- "user": {
- "id": 1,
- "email": "foo@bar.com",
- "name": "Foo Bar",
- "initials": "fb",
- "username": "foobar"
- }
+ user: {
+ id: 1,
+ email: 'foo@bar.com',
+ name: 'Foo Bar',
+ initials: 'fb',
+ username: 'foobar',
+ },
});
defaultProps = {
@@ -24,58 +23,58 @@ describe('', () => {
projects: new ProjectCollection(),
user: user,
joined: true,
- key: 1
+ key: 1,
};
});
describe('joined', () => {
describe('with projects', () => {
beforeEach(() => {
- defaultProps.projects.reset([{
- "name": "Foo",
- "slug": "foo",
- "path_to": {},
- "archived_at": "2015/08/28 16:21:57 -0300",
- "velocity": 10,
- "volatility": "0%",
- "users_avatar": ["https://secure.gravatar.com/avatar/foo.png"]
- },{
- "name": "Bar",
- "slug": "bar",
- "path_to": {},
- "archived_at": "2015/08/28 16:21:57 -0300",
- "velocity": 10,
- "volatility": "0%",
- "users_avatar": ["https://secure.gravatar.com/avatar/bar.png"]
- }]);
+ defaultProps.projects.reset([
+ {
+ name: 'Foo',
+ slug: 'foo',
+ path_to: {},
+ archived_at: '2015/08/28 16:21:57 -0300',
+ velocity: 10,
+ volatility: '0%',
+ users_avatar: ['https://secure.gravatar.com/avatar/foo.png'],
+ },
+ {
+ name: 'Bar',
+ slug: 'bar',
+ path_to: {},
+ archived_at: '2015/08/28 16:21:57 -0300',
+ velocity: 10,
+ volatility: '0%',
+ users_avatar: ['https://secure.gravatar.com/avatar/bar.png'],
+ },
+ ]);
});
it('renders components', () => {
- const wrapper = shallow();
- expect(wrapper.contains([
- ,
-
- ])).toBe(true);
+ const { getByText } = render();
+
+ expect(
+ getByText(defaultProps.projects.models[0].get('name'))
+ ).toBeInTheDocument();
+ expect(
+ getByText(defaultProps.projects.models[1].get('name'))
+ ).toBeInTheDocument();
});
- it('Title should be present', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
-
view_module { I18n.t('projects.mine') } | { 2 }
-
- )).toBe(true);
+ it('Title should be present', async () => {
+ const { getByText } = render();
+
+ expect(getByText(`${I18n.t('projects.mine')} | 2`)).toBeInTheDocument();
});
});
describe('without projects', () => {
it('Title should be present', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
-
view_module {I18n.t('projects.mine')} | {0}
-
- )).toBe(true);
+ const { getByText } = render();
+
+ expect(getByText(`${I18n.t('projects.mine')} | 0`)).toBeInTheDocument();
});
});
});
@@ -83,35 +82,34 @@ describe('', () => {
describe('unjoined', () => {
describe('with projects', () => {
beforeEach(() => {
- defaultProps.title = I18n.t('projects.member_of'),
- defaultProps.joined = false;
- defaultProps.projects.reset([{
- "id": 1,
- "name": "Foobar",
- "slug": "foobar",
- "path_to": {},
- "archived_at": "2015/08/28 16:21:57 -0300",
- "velocity": 10,
- "volatility": "0%",
- "users_avatar": ["https://secure.gravatar.com/avatar/foobar.png"]
- }]);
+ (defaultProps.title = I18n.t('projects.member_of')),
+ (defaultProps.joined = false);
+ defaultProps.projects.reset([
+ {
+ id: 1,
+ name: 'Foobar',
+ slug: 'foobar',
+ path_to: {},
+ archived_at: '2015/08/28 16:21:57 -0300',
+ velocity: 10,
+ volatility: '0%',
+ users_avatar: ['https://secure.gravatar.com/avatar/foobar.png'],
+ },
+ ]);
});
it('render components', () => {
- const wrapper = shallow();
- expect(wrapper.contains([
-
- ])).toBe(true);
+ const { getByText } = render();
+
+ expect(
+ getByText(defaultProps.projects.models[0].get('name'))
+ ).toBeInTheDocument();
});
});
describe('without projects', () => {
it('Title should be present', () => {
- const wrapper = shallow();
- expect(wrapper.contains(
-
-
view_module {I18n.t('projects.mine')} | {0}
-
- )).toBe(true);
+ const { getByText } = render();
+ expect(getByText(`${I18n.t('projects.mine')} | 0`)).toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/projects/project_search_spec.js b/spec/javascripts/components/projects/project_search_spec.js
index b9698316e..e033bea05 100644
--- a/spec/javascripts/components/projects/project_search_spec.js
+++ b/spec/javascripts/components/projects/project_search_spec.js
@@ -1,8 +1,7 @@
import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import ProjectSearch from 'components/projects/ProjectSearch';
-import ProjectList from 'components/projects/ProjectList';
import ProjectCollection from 'collections/project_collection';
import User from 'models/user';
@@ -11,78 +10,76 @@ describe('', () => {
beforeEach(() => {
user = {
- "user": {
- "id": 1,
- "email": "foo@bar.com",
- "name": "Foo Bar",
- "initials": "fb",
- "username": "foobar"
- }
+ user: {
+ id: 1,
+ email: 'foo@bar.com',
+ name: 'Foo Bar',
+ initials: 'fb',
+ username: 'foobar',
+ },
};
- projects = [{
- "name": "Foobar",
- "slug": "foobar",
- "path_to": {},
- "archived_at": null,
- "velocity": 10,
- "volatility": "0%",
- "users_avatar": ["https://secure.gravatar.com/avatar/foobar.png"]
- }];
+ projects = [
+ {
+ name: 'Foobar',
+ slug: 'foobar',
+ path_to: {},
+ archived_at: null,
+ velocity: 10,
+ volatility: '0%',
+ users_avatar: ['https://secure.gravatar.com/avatar/foobar.png'],
+ },
+ ];
defaultProps = {
projects: {
joined: new ProjectCollection(projects),
- unjoined: new ProjectCollection(projects)
+ unjoined: new ProjectCollection(projects),
},
- user: new User(user)
- }
+ user: new User(user),
+ };
});
- it('renders two components', () => {
- const wrapper = shallow();
- expect(wrapper.contains([
- ,
-
- ])).toBe(true);
+ it('renders two components', async () => {
+ const { getByText } = render();
+
+ expect(getByText(`${I18n.t('projects.mine')} | 1`)).toBeInTheDocument();
+ expect(
+ getByText(`${I18n.t('projects.not_member_of')} | 1`)
+ ).toBeInTheDocument();
});
it('should select options', () => {
- const wrapper = mount();
- expect(wrapper.contains([
- ,
- ,
-
- ])).toBe(true);
+ const { getByText } = render();
+
+ expect(getByText(I18n.t('not_archived'))).toBeInTheDocument();
+ expect(getByText(I18n.t('archived'))).toBeInTheDocument();
+ expect(getByText(I18n.t('all_projects'))).toBeInTheDocument();
});
- it('should change the visibleProjects state', () => {
- const wrapper = mount();
- const select = wrapper.find('select');
+ it('should change the visibleProjects state', async () => {
+ let visibleProjects;
+ const { getByTestId, queryAllByTestId } = render(
+
+ );
+ const select = getByTestId('select-project-filter');
+
+ visibleProjects = queryAllByTestId('view-module-title');
+ expect(visibleProjects.length).toBe(2);
- select.getDOMNode().value = 'all_projects';
- select.simulate('change');
+ fireEvent.change(select, { target: { value: 'all_projects' } });
- expect(wrapper.state('visibleProjects').joined.projects.length).toBe(1);
+ visibleProjects = queryAllByTestId('view-module-title');
+ expect(visibleProjects.length).toBe(2);
- select.getDOMNode().value = 'archived';
- select.simulate('change');
+ fireEvent.change(select, { target: { value: 'archived' } });
- expect(wrapper.state('visibleProjects').joined.projects.length).toBe(0);
+ visibleProjects = queryAllByTestId('view-module-title');
+ expect(visibleProjects.length).toBe(0);
- select.getDOMNode().value = 'not_archived';
- select.simulate('change');
+ fireEvent.change(select, { target: { value: 'not_archived' } });
- expect(wrapper.state('visibleProjects').joined.projects.length).toBe(1);
+ visibleProjects = queryAllByTestId('view-module-title');
+ expect(visibleProjects.length).toBe(2);
});
});
diff --git a/spec/javascripts/components/projects/side_bar/side_bar_button_info_spec.js b/spec/javascripts/components/projects/side_bar/side_bar_button_info_spec.js
index a4b26f5ef..e8d1b0e58 100644
--- a/spec/javascripts/components/projects/side_bar/side_bar_button_info_spec.js
+++ b/spec/javascripts/components/projects/side_bar/side_bar_button_info_spec.js
@@ -1,19 +1,21 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import SideBarButtonInfo from 'components/projects/SideBar/SideBarButtonInfo';
describe('', () => {
it('renders the component', () => {
- const wrapper = shallow();
+ const { container } = render();
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
it('contain the description', () => {
const description = 'description';
- const wrapper = shallow();
- const span = wrapper.find('[data-id="project-option-info"]');
+ const { container } = render(
+
+ );
+ const span = container.querySelector('.SideBar__info');
- expect(span.text()).toEqual(description);
+ expect(span.innerHTML).toEqual(description);
});
});
diff --git a/spec/javascripts/components/projects/side_bar/side_bar_button_spec.js b/spec/javascripts/components/projects/side_bar/side_bar_button_spec.js
index 072bfc627..17d8859ca 100644
--- a/spec/javascripts/components/projects/side_bar/side_bar_button_spec.js
+++ b/spec/javascripts/components/projects/side_bar/side_bar_button_spec.js
@@ -1,72 +1,77 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import SideBarButton from 'components/projects/SideBar/SideBarButton';
describe('', () => {
- const render = props => {
+ const renderComponent = props => {
const defaultProps = {
children: '',
description: '',
- onClick: sinon.stub(),
- isVisible: false
+ onClick: vi.fn(),
+ isVisible: false,
};
- return shallow();
+ return render();
};
it('renders the component', () => {
- const wrapper = render();
+ const { container } = renderComponent();
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
it('render children', () => {
const children = 'I am children!';
- const wrapper = render({ children });
+ const { container } = renderComponent({ children });
- expect(wrapper.find('[data-id="side-bar-button"]').text()).toEqual(children);
+ expect(container.querySelector('.SideBar__link').innerHTML).toEqual(
+ children
+ );
});
it('does not render ', () => {
- const wrapper = render();
+ const { queryByTestId } = renderComponent();
- expect(wrapper.find('[data-id="button-info"]')).not.toExist();
+ expect(queryByTestId('sidebar-button-info')).not.toBeInTheDocument();
});
describe('when click in ', () => {
it('call onClick', () => {
- const onClick = sinon.stub();
- const wrapper = render({ onClick });
+ const onClick = vi.fn();
+ const { container } = renderComponent({ onClick });
- wrapper.find('[data-id="side-bar-button"]').simulate('click');
+ const button = container.querySelector('.SideBar__link');
+ fireEvent.click(button);
expect(onClick).toHaveBeenCalled();
});
});
describe('when mouse over', () => {
- it('renders ', () => {
- const wrapper = render();
+ it('renders ', async () => {
+ const { container } = renderComponent();
- wrapper.find('[data-id="side-bar-button"]').simulate('mouseover');
- expect(wrapper.find('[data-id="button-info"]')).toExist();
+ const button = container.querySelector('.SideBar__link');
+ fireEvent.mouseOver(button);
+
+ expect(container.querySelector('.SideBar__info')).toBeInTheDocument();
});
});
describe('when isVisible is true', () => {
it('renders with SideBar__link--is-visible class', () => {
- const wrapper = render({ isVisible: true });
- const button = wrapper.find('[data-id="side-bar-button"]');
+ const { container } = renderComponent({ isVisible: true });
+ const button = container.querySelector('.SideBar__link');
- expect(button.hasClass('SideBar__link--is-visible')).toBeTruthy();
+ expect(button).toHaveClass('SideBar__link--is-visible');
});
});
describe('when isVisible is false', () => {
it('render without SideBar__link--is-visible class', () => {
- const wrapper = render();
- const button = wrapper.find('[data-id="side-bar-button"]');
+ const { container } = renderComponent();
+ const button = container.querySelector('.SideBar__link');
- expect(button.hasClass('SideBar__link--is-visible')).toBeFalsy();
+ expect(button).not.toHaveClass('SideBar__link--is-visible');
});
});
});
diff --git a/spec/javascripts/components/projects/side_bar/side_bar_spec.js b/spec/javascripts/components/projects/side_bar/side_bar_spec.js
index 475cfe13f..ea4f87bed 100644
--- a/spec/javascripts/components/projects/side_bar/side_bar_spec.js
+++ b/spec/javascripts/components/projects/side_bar/side_bar_spec.js
@@ -1,9 +1,9 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import SideBar from 'components/projects/SideBar';
describe('', () => {
- const render = props => {
+ const renderComponent = props => {
const defaultProps = {
reverse: false,
visibleColumns: {
@@ -11,16 +11,16 @@ describe('', () => {
backlog: true,
done: true,
},
- toggleColumn: sinon.stub(),
- reverseColumns: sinon.stub()
+ toggleColumn: vi.fn(),
+ reverseColumns: vi.fn(),
};
- return shallow();
+ return render();
};
it('renders the component', () => {
- const wrapper = render();
+ const { container } = renderComponent();
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/search/search_results_spec.js b/spec/javascripts/components/search/search_results_spec.js
index 8b6658af2..d0d18abc8 100644
--- a/spec/javascripts/components/search/search_results_spec.js
+++ b/spec/javascripts/components/search/search_results_spec.js
@@ -1,33 +1,70 @@
import React from 'react';
-import { shallow } from 'enzyme';
-import SearchResults from 'components/search/Search';
+import { SearchResults } from 'components/search/SearchResults';
+import { renderWithProviders } from '../setupRedux';
+import { DragDropContext } from 'react-beautiful-dnd';
+
+const emptyStory = {
+ title: '',
+ description: null,
+ estimate: '',
+ storyType: 'feature',
+ state: 'unscheduled',
+ acceptedAt: null,
+ requestedById: null,
+ ownedById: null,
+ projectId: null,
+ createdAt: '',
+ updatedAt: '',
+ position: '',
+ newPosition: null,
+ labels: [],
+ requestedByName: '',
+ ownedByName: null,
+ ownedByInitials: null,
+ releaseDate: null,
+ deliveredAt: null,
+ errors: {},
+ notes: [],
+ tasks: [],
+};
describe('', () => {
+ const renderComponent = props => {
+ const defaultProps = {
+ isEnabled: false,
+ searchResults: [],
+ closeSearch: vi.fn(),
+ projectBoard: {
+ search: {},
+ },
+ };
+
+ const mergeProps = {
+ ...defaultProps,
+ ...props,
+ };
+
+ return renderWithProviders(
+
+
+ ,
+ {}
+ );
+ };
+
describe('when isEnabled is false', () => {
it('does not render the component', () => {
- const wrapper = shallow(
-
- );
-
- expect(wrapper.instance()).toBeNull();
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint')).not.toBeInTheDocument();
});
});
describe('when isEnabled is true', () => {
it('renders the component', () => {
- const wrapper = shallow(
-
- );
-
- expect(wrapper).toExist();
+ const { container } = renderComponent({ isEnabled: true });
+
+ expect(container.querySelector('.Sprint')).toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/search/search_spec.js b/spec/javascripts/components/search/search_spec.js
index 05dbfdb48..132b35478 100644
--- a/spec/javascripts/components/search/search_spec.js
+++ b/spec/javascripts/components/search/search_spec.js
@@ -1,49 +1,79 @@
import React from 'react';
-import { shallow } from 'enzyme';
import Search from 'components/search/Search';
+import { renderWithProviders } from '../setupRedux';
+import { DragDropContext } from 'react-beautiful-dnd';
+
+vi.mock('react-clipboard.js', () => ({
+ default: ({ children, ...props }) => ,
+}));
describe('', () => {
+ const renderComponent = props => {
+ return renderWithProviders(
+
+
+ ,
+ {
+ preloadedState: {
+ project: {
+ pointValues: [],
+ labels: [],
+ },
+ },
+ }
+ );
+ };
+
describe('when have not stories', () => {
- let wrapper;
+ it('renders the component', () => {
+ const { container } = renderComponent();
- beforeEach(() => {
- wrapper = shallow();
+ expect(container).toBeInTheDocument();
});
- it('renders the component', () => {
- expect(wrapper).toExist();
- });
-
it('renders header', () => {
- expect(wrapper.find('[data-id="search-header"]')).toBeTruthy();
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint__header')).toBeInTheDocument();
});
-
+
it('renders stories', () => {
- expect(wrapper.find('[data-id="stories-search"]')).toBeTruthy();
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint__header')).toBeInTheDocument();
+ expect(container.querySelector('.Sprint__body')).toBeInTheDocument();
});
});
const storiesAmount = [1, 10, 100];
describe(`when have ${storiesAmount} stories`, () => {
- const stories = Array(storiesAmount).fill({ estimate: 2 });
- let wrapper;
-
- beforeEach(() => {
- wrapper = shallow();
+ const stories = Array(storiesAmount).fill({
+ estimate: 2,
+ id: 1,
+ _editing: {},
+ notes: [],
+ tasks: [],
});
it('renders the component', () => {
- expect(wrapper).toExist();
+ const { container } = renderComponent({
+ stories,
+ });
+
+ expect(container).toBeInTheDocument();
});
-
+
it('renders header', () => {
- expect(wrapper.find('[data-id="search-header"]')).toBeTruthy();
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint__header')).toBeInTheDocument();
});
-
+
it('renders stories', () => {
- expect(wrapper.find('[data-id="stories-search"]')).toBeTruthy();
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint__body')).toBeInTheDocument();
});
});
});
-
diff --git a/spec/javascripts/components/search/search_tooltip_spec.js b/spec/javascripts/components/search/search_tooltip_spec.js
index 83a4c2b34..2667dfc65 100644
--- a/spec/javascripts/components/search/search_tooltip_spec.js
+++ b/spec/javascripts/components/search/search_tooltip_spec.js
@@ -1,22 +1,26 @@
import React from 'react';
-import { shallow, mount } from 'enzyme';
import SearchTooltip from 'components/search/SearchTooltip';
+import { render } from '@testing-library/react';
describe('', () => {
it('renders the component', () => {
- const wrapper = shallow();
-
- expect(wrapper).toExist();
+ const { container } = render();
+
+ expect(container).toBeInTheDocument();
});
- const aditionalClasses = ['foo','bar'];
+ const aditionalClasses = ['foo', 'bar'];
aditionalClasses.forEach(aditionalClass => {
describe(`when aditionalClass is ${aditionalClass}`, () => {
it(`render component with class ${aditionalClass}`, () => {
- const wrapper = mount();
+ const { getByTestId } = render(
+
+ );
- expect(wrapper.find('[data-id="search-tooltip"]').hasClass(aditionalClass)).toBeTruthy();
+ expect(getByTestId('search-tooltip-component')).toHaveClass(
+ aditionalClass
+ );
});
});
});
diff --git a/spec/javascripts/components/search/story_search_spec.js b/spec/javascripts/components/search/story_search_spec.js
index fd6e68963..8ff47ea87 100644
--- a/spec/javascripts/components/search/story_search_spec.js
+++ b/spec/javascripts/components/search/story_search_spec.js
@@ -1,46 +1,41 @@
import React from 'react';
-import { mount } from 'enzyme';
+import ReactDOM from 'react-dom';
+import { render, screen } from '@testing-library/react';
import { StorySearch } from 'components/search/StorySearch';
-describe('', () => {
+describe('', () => {
+ beforeAll(() => {
+ ReactDOM.createPortal = vi.fn(element => {
+ return element;
+ });
+ });
+
beforeEach(() => {
- const divPortal = global.document.createElement('div');
+ const divPortal = document.createElement('div');
divPortal.setAttribute('data-portal', 'search');
- const body = global.document.querySelector('body');
+ const body = document.querySelector('body');
body.appendChild(divPortal);
});
- it('renders the component', () => {
- const wrapper = mount(
-
- );
-
- expect(wrapper).toExist();
- });
-
describe('loading', () => {
describe('when loading is true', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = mount(
-
- );
- });
-
it('renders the spinner', () => {
- const spinner = wrapper.find('[data-id="spinner-loading"]');
-
- expect(spinner).toBeTruthy();
+ const { container } = render(
+
+ );
+
+ expect(
+ container.querySelector('.StorySearch__spinner')
+ ).toBeInTheDocument();
});
});
});
+
+ it('renders the component', () => {
+ const { container } = render(
+
+ );
+
+ expect(container).toBeInTheDocument();
+ });
});
diff --git a/spec/javascripts/components/setupRedux.js b/spec/javascripts/components/setupRedux.js
new file mode 100644
index 000000000..8727617f1
--- /dev/null
+++ b/spec/javascripts/components/setupRedux.js
@@ -0,0 +1,19 @@
+import React from 'react';
+import { render } from '@testing-library/react';
+import { testStore } from 'store';
+import { Provider } from 'react-redux';
+
+export function renderWithProviders(ui, extendedRenderOptions = {}) {
+ const {
+ preloadedState = {},
+ // Automatically create a store instance if no store was passed in
+ store = testStore(preloadedState),
+ ...renderOptions
+ } = extendedRenderOptions;
+
+ function Wrapper({ children }) {
+ return {children};
+ }
+
+ return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
+}
diff --git a/spec/javascripts/components/stories/history/history_changes/history_change_spec.js b/spec/javascripts/components/stories/history/history_changes/history_change_spec.js
index b3a047f38..ea799bfaa 100644
--- a/spec/javascripts/components/stories/history/history_changes/history_change_spec.js
+++ b/spec/javascripts/components/stories/history/history_changes/history_change_spec.js
@@ -1,44 +1,47 @@
-import React from "react";
-import { shallow } from "enzyme";
-import HistoryChange from "components/stories/History/HistoryChanges/HistoryChange";
+import React from 'react';
+import { render } from '@testing-library/react';
+import HistoryChange from 'components/stories/History/HistoryChanges/HistoryChange';
describe('', () => {
- const render = overrideProps => {
+ const renderComponent = overrideProps => {
const defaultProps = {
oldValue: 'oldValue',
newValue: 'newValue',
- title: 'title'
+ title: 'title',
};
- const wrapper = shallow();
- const oldValue = wrapper.find('[data-id="history-old-value"]');
- const newValue = wrapper.find('[data-id="history-new-value"]');
- const title = wrapper.find('[data-id="history-change-title"]');
+ const { container: wrapper } = render(
+
+ );
+
+ const oldValue = wrapper.querySelector('[data-id="history-old-value"]');
+ const newValue = wrapper.querySelector('[data-id="history-new-value"]');
+ const title = wrapper.querySelector('[data-id="history-change-title"]');
return { wrapper, oldValue, newValue, title };
};
it('renders the component', () => {
- const { wrapper } = render();
+ const { wrapper } = renderComponent();
- expect(wrapper).toExist();
+ expect(wrapper).toBeInTheDocument();
});
it('renders old value', () => {
- const { oldValue } = render();
+ const { oldValue } = renderComponent();
- expect(oldValue).toExist();
+ expect(oldValue).toBeInTheDocument();
});
it('renders new value', () => {
- const { newValue } = render();
+ const { newValue } = renderComponent();
- expect(newValue).toExist();
+ expect(newValue).toBeInTheDocument();
});
it('renders the title', () => {
- const { title } = render();
+ const { title } = renderComponent();
- expect(title).toExist();
+ expect(title).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/stories/history/history_header_spec.js b/spec/javascripts/components/stories/history/history_header_spec.js
index 5599507c2..3ff0fa5e3 100644
--- a/spec/javascripts/components/stories/history/history_header_spec.js
+++ b/spec/javascripts/components/stories/history/history_header_spec.js
@@ -1,46 +1,49 @@
-import React from "react";
-import { shallow } from "enzyme";
-import HistoryHeader from "../../../../../app/assets/javascripts/components/stories/History/HistoryHeader";
+import React from 'react';
+import { render } from '@testing-library/react';
+import HistoryHeader from '../../../../../app/assets/javascripts/components/stories/History/HistoryHeader';
describe('HistoryHeader', () => {
- const render = overrideProps => {
+ const renderComponent = overrideProps => {
const defaultProps = {
title: 'title',
user: 'user',
- date: '2019/08/27 14:18:00 -0300'
+ date: '2019/08/27 14:18:00 -0300',
};
- const wrapper = shallow();
- const title = wrapper.find('[data-id="history-header-title"]');
- const date = wrapper.find('[data-id="history-header-date"]');
- return { wrapper, title, date }
+ const { container: wrapper } = render(
+
+ );
+ const title = wrapper.querySelector('[data-id="history-header-title"]');
+ const date = wrapper.querySelector('[data-id="history-header-date"]');
+
+ return { wrapper, title, date };
};
it('renders the component', () => {
- const { wrapper } = render();
+ const { wrapper } = renderComponent();
- expect(wrapper).toExist();
+ expect(wrapper).toBeInTheDocument();
});
it('renders the title', () => {
- const { title } = render();
+ const { title } = renderComponent();
- expect(title).toExist();
+ expect(title).toBeInTheDocument();
});
it('renders the date', () => {
- const { date } = render();
+ const { date } = renderComponent();
- expect(date).toExist();
+ expect(date).toBeInTheDocument();
});
describe('title', () => {
const user = 'i am user!';
it('title contains user', () => {
- const { title } = render({ user });
+ const { title } = renderComponent({ user });
- expect(title.text()).toContain(user);
+ expect(title.innerHTML).toContain(user);
});
});
});
diff --git a/spec/javascripts/components/stories/history/history_item_spec.js b/spec/javascripts/components/stories/history/history_item_spec.js
index 2e9694675..793e2cca3 100644
--- a/spec/javascripts/components/stories/history/history_item_spec.js
+++ b/spec/javascripts/components/stories/history/history_item_spec.js
@@ -1,38 +1,44 @@
-import React from "react";
-import { shallow } from "enzyme";
-import HistoryItem from "../../../../../app/assets/javascripts/components/stories/History/HistoryItem";
+import React from 'react';
+import { render } from '@testing-library/react';
+import HistoryItem from '../../../../../app/assets/javascripts/components/stories/History/HistoryItem';
describe('', () => {
- const render = overrideProps => {
+ const renderComponent = overrideProps => {
const defaultProps = {
title: 'title',
date: '2019/08/27 14:18:00 -0300',
user: 'i am user',
- changes: []
+ changes: [
+ { key: 1, newValue: 'dhasu', oldValue: 'dhusayhdguas' },
+ { key: 2, newValue: 'dhasu', oldValue: 'dhusayhdguas' },
+ ],
};
- const wrapper = shallow();
- const header = wrapper.find('[data-id="history-header"]');
- const changes = wrapper.find('[data-id="history-changes"]');
+ const { container: wrapper } = render(
+
+ );
+
+ const header = wrapper.querySelector('[data-id="history-header-title"]');
+ const changes = wrapper.querySelector('[data-id="history-change-title"]');
return { wrapper, header, changes };
};
it('renders the component', () => {
- const { wrapper } = render();
+ const { wrapper } = renderComponent();
- expect(wrapper).toExist();
+ expect(wrapper).toBeInTheDocument();
});
it('renders header', () => {
- const { header } = render();
+ const { header } = renderComponent();
- expect(header).toExist();
+ expect(header).toBeInTheDocument();
});
it('renders changes', () => {
- const { changes } = render();
-
- expect(changes).toExist();
+ const { changes } = renderComponent();
+
+ expect(changes).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/stories/history/history_spec.js b/spec/javascripts/components/stories/history/history_spec.js
index 20901dee0..68b611ee8 100644
--- a/spec/javascripts/components/stories/history/history_spec.js
+++ b/spec/javascripts/components/stories/history/history_spec.js
@@ -1,25 +1,28 @@
-import React from "react";
-import { shallow } from "enzyme";
-import History from "../../../../../app/assets/javascripts/components/stories/History/index";
-import HistoryFactory from "../../../support/factories/historyFactory";
+import React from 'react';
+import { render } from '@testing-library/react';
+import History from '../../../../../app/assets/javascripts/components/stories/History/index';
+import HistoryFactory from '../../../support/factories/historyFactory';
-describe("", () => {
- const render = () => {
- const wrapper = shallow();
- const historyActivity = wrapper.find('[data-id="history-activity"]');
+describe('', () => {
+ const renderComponent = () => {
+ const { container: wrapper } = render(
+
+ );
- return { wrapper, historyActivity }
+ const historyActivity = wrapper.querySelector('.HistoryItem');
+
+ return { wrapper, historyActivity };
};
it('renders the component', () => {
- const { wrapper } = render();
+ const { wrapper } = renderComponent();
- expect(wrapper).toExist();
+ expect(wrapper).toBeInTheDocument();
});
- it("renders ", () => {
- const { historyActivity } = render();
+ it('renders ', () => {
+ const { historyActivity } = renderComponent();
- expect(historyActivity).toExist();
+ expect(historyActivity).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/stories/sprint_header_spec.js b/spec/javascripts/components/stories/sprint_header_spec.js
index f6054da92..edd7b65d5 100644
--- a/spec/javascripts/components/stories/sprint_header_spec.js
+++ b/spec/javascripts/components/stories/sprint_header_spec.js
@@ -1,174 +1,173 @@
-import React from "react";
-import { mount } from "enzyme";
-import SprintHeader from "components/stories/SprintHeader";
+import React from 'react';
+import { fireEvent, render } from '@testing-library/react';
+import SprintHeader from 'components/stories/SprintHeader';
const defaultProps = {
number: 42,
- onClick: sinon.stub(),
+ onClick: vi.fn(),
startDate: '1420/01/01',
isDone: false,
points: 420,
isClosed: false,
- completedPoints: 111
+ completedPoints: 111,
};
const mergeProps = overrides => ({ ...defaultProps, ...overrides });
-const renderWrapper = overrides => mount(
-
-);
+const renderWrapper = overrides =>
+ render();
describe('', () => {
- let wrapper, onClick
-
- beforeEach(() => {
- onClick = sinon.stub();
- wrapper = renderWrapper({ onClick });
- });
-
it('Renders a div with class of "Sprint__header"', () => {
- const header = wrapper.find('div.Sprint__header');
+ const { container } = renderWrapper();
+ const header = container.querySelector('div.Sprint__header');
- expect(header.exists()).toBe(true);
+ expect(header).toBeInTheDocument();
});
it('Calls onClick prop when div is clicked', () => {
- const header = wrapper.find('div.Sprint__header');
+ const onClick = vi.fn();
+ const { container } = renderWrapper({ onClick });
+ const header = container.querySelector('div.Sprint__header');
- header.simulate('click');
+ fireEvent.click(header);
expect(onClick).toHaveBeenCalled();
});
it('displays iteration number', () => {
- expect(wrapper.html()).toContain('42');
+ const { container } = renderWrapper();
+
+ expect(container.innerHTML).toContain('42');
});
it('displays iteration start date', () => {
- const expected = I18n.l("date.formats.long", defaultProps.startDate);
+ const { container } = renderWrapper();
+ const expected = I18n.l('date.formats.long', defaultProps.startDate);
- expect(wrapper.html()).toContain(expected);
- })
+ expect(container.innerHTML).toContain(expected);
+ });
describe('default sprints', () => {
it('shows sprint points', () => {
- expect(wrapper.find('div.default-points').html()).toContain('420');
+ const { container } = renderWrapper();
+
+ const defaultPoints = container.querySelector('div.default-points');
+
+ expect(defaultPoints.innerHTML).toContain('420');
});
describe('when there are completed points', () => {
it('shows completed points', () => {
- expect(wrapper.find('div.default-points').html()).toContain('111');
- })
+ const { container } = renderWrapper();
+
+ const defaultPoints = container.querySelector('div.default-points');
+
+ expect(defaultPoints.innerHTML).toContain('111');
+ });
});
});
describe('done sprints', () => {
describe('when sprint has points', () => {
- beforeEach(() => {
- wrapper = renderWrapper({
+ it('shows sprint points', () => {
+ const { container } = renderWrapper({
hasStories: true,
- isDone: true
+ isDone: true,
});
- });
- it('shows sprint points', () => {
- const donePoints = wrapper.find('span.done-points');
+ const donePoints = container.querySelector('span.done-points');
- expect(donePoints.html()).toContain('420');
+ expect(donePoints.innerHTML).toContain('420');
});
});
describe('when sprint has no points', () => {
- beforeEach(() => {
- wrapper = renderWrapper({
+ it('does not show sprint points', () => {
+ const { container } = renderWrapper({
isClosed: true,
hasStories: true,
isDone: true,
- points: 0
+ points: 0,
});
- });
+ const donePoints = container.querySelector('span.done-points');
- it('does not show sprint points', () => {
- const donePoints = wrapper.find('span.done-points');
-
- expect(donePoints.children().length).toBe(0);
+ expect(donePoints.children.length).toBe(0);
});
});
describe('when sprint has stories', () => {
- beforeEach(() => {
- wrapper = renderWrapper({
+ it('shows expand icon', () => {
+ const { container } = renderWrapper({
isDone: true,
hasStories: true,
- isClosed: true
+ isClosed: true,
});
- });
+ const icon = container.querySelector('i.Sprint__icon');
- it('shows expand icon', () => {
- const icon = wrapper.find('i.Sprint__icon');
-
- expect(icon.html()).toContain('chevron_right');
+ expect(icon.innerHTML).toContain('chevron_right');
});
describe('when sprint is closed', () => {
it('does not have expanded modifier class', () => {
- const icon = wrapper.find('i.Sprint__icon');
+ const { container } = renderWrapper({
+ isDone: true,
+ hasStories: true,
+ isClosed: true,
+ });
+ const icon = container.querySelector('i.Sprint__icon');
- expect(icon).not.toHaveClassName('Sprint__icon--expanded');
+ expect(icon).not.toHaveClass('Sprint__icon--expanded');
});
});
describe('when sprint is expanded', () => {
- beforeEach(() => {
- wrapper = renderWrapper({
+ it('has expanded modifier class', () => {
+ const { container } = renderWrapper({
isDone: true,
hasStories: true,
});
- });
-
- it('has expanded modifier class', () => {
- const icon = wrapper.find('i.Sprint__icon');
+ const icon = container.querySelector('i.Sprint__icon');
- expect(icon).toHaveClassName('Sprint__icon--expanded');
+ expect(icon).toHaveClass('Sprint__icon--expanded');
});
});
});
describe('when sprint has no stories', () => {
- beforeEach(() => {
- wrapper = renderWrapper({
+ it('shows "-" icon', () => {
+ const { container } = renderWrapper({
isDone: true,
hasStories: false,
- isClosed: true
+ isClosed: true,
});
- });
-
- it('shows "-" icon', () => {
- const icon = wrapper.find('i.Sprint__icon');
+ const icon = container.querySelector('i.Sprint__icon');
- expect(icon.html()).toContain('remove');
+ expect(icon.innerHTML).toContain('remove');
});
describe('when isClosed prop is true', () => {
it('does not have expanded modifier class', () => {
- const icon = wrapper.find('i.Sprint__icon');
+ const { container } = renderWrapper({
+ isDone: true,
+ hasStories: false,
+ isClosed: true,
+ });
+ const icon = container.querySelector('i.Sprint__icon');
- expect(icon).not.toHaveClassName('Sprint__icon--expanded');
+ expect(icon).not.toHaveClass('Sprint__icon--expanded');
});
});
describe('when isClosed prop is false', () => {
- beforeEach(() => {
- wrapper = renderWrapper({
+ it('does not have expanded modifier class', () => {
+ const { container } = renderWrapper({
isDone: true,
hasStories: false,
});
- });
-
- it('does not have expanded modifier class', () => {
- const icon = wrapper.find('i.Sprint__icon');
+ const icon = container.querySelector('i.Sprint__icon');
- expect(icon).not.toHaveClassName('Sprint__icon--expanded');
+ expect(icon).not.toHaveClass('Sprint__icon--expanded');
});
});
});
diff --git a/spec/javascripts/components/stories/sprint_spec.js b/spec/javascripts/components/stories/sprint_spec.js
index 5a30b2663..492306939 100644
--- a/spec/javascripts/components/stories/sprint_spec.js
+++ b/spec/javascripts/components/stories/sprint_spec.js
@@ -1,67 +1,102 @@
-import React from "react";
-import { shallow } from "enzyme";
-import Sprint from "components/stories/Sprint";
+import React from 'react';
+import Sprint from 'components/stories/Sprint';
+import { DragDropContext } from 'react-beautiful-dnd';
+import { renderWithProviders } from '../setupRedux';
+import { fireEvent } from '@testing-library/react';
-let sprint = {};
-let wrapper = {};
+vi.mock('react-clipboard.js', () => ({
+ default: ({ children, ...props }) => ,
+}));
const createSprint = propOverrides => ({
number: 1,
- startDate: "2018/09/03",
- endDate: "2018/09/10",
+ startDate: '2018/09/03',
+ endDate: '2018/09/10',
points: 3,
completedPoints: 0,
stories: [
{
id: 1,
- position: "3",
- state: "unstarted",
+ position: '3',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature"
+ storyType: 'feature',
+ _editing: {},
+ notes: [],
+ tasks: [],
},
{
id: 2,
- position: "2",
- state: "unstarted",
+ position: '2',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature"
- }
+ storyType: 'feature',
+ _editing: {},
+ notes: [],
+ tasks: [],
+ },
],
isDropDisabled: false,
- ...propOverrides
+ ...propOverrides,
});
-describe("", () => {
+describe('', () => {
+ let sprint = {};
+
+ const renderComponent = props => {
+ return renderWithProviders(
+
+
+ ,
+ {
+ preloadedState: {
+ project: {
+ pointValues: [],
+ labels: [],
+ },
+ },
+ }
+ );
+ };
+
beforeEach(() => {
sprint = createSprint();
- wrapper = shallow();
});
it('renders a with class ".Sprint"', () => {
- expect(wrapper.find("div.Sprint").exists()).toBe(true);
+ const { container } = renderComponent();
+
+ expect(container.querySelector('div.Sprint')).toBeInTheDocument();
});
it('renders a SprintHeader component"', () => {
- expect(wrapper.find('SprintHeader').exists()).toBe(true);
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint__header')).toBeInTheDocument();
});
it('renders a div with class ".Sprint__body"', () => {
- expect(wrapper.find("div.Sprint__body").exists()).toBe(true);
+ const { container } = renderComponent();
+
+ expect(container.querySelector('div.Sprint__body')).toBeInTheDocument();
});
- it("renders a
components", () => {
- expect(wrapper.find("Stories").exists()).toBe(true);
+ it('renders a components', () => {
+ const { getByTestId } = renderComponent();
+
+ expect(getByTestId('stories-container')).toBeInTheDocument();
});
- describe("when no stories are passed as sprint", () => {
+ describe('when no stories are passed as sprint', () => {
beforeEach(() => {
sprint = createSprint();
sprint.stories = null;
- wrapper = shallow();
});
- it("does not render any component", () => {
- expect(wrapper.find("Stories").exists()).toBe(false);
+ it('does not render any component', () => {
+ const { queryByTestId } = renderComponent();
+
+ expect(queryByTestId('stories-container')).not.toBeInTheDocument();
});
});
@@ -69,19 +104,24 @@ describe("", () => {
let fetchStories;
beforeEach(() => {
- sprint = createSprint({ fetching: false, isFetched: false, hasStories: true });
+ sprint = createSprint({
+ fetching: false,
+ isFetched: false,
+ hasStories: true,
+ });
sprint.stories = null;
- fetchStories = sinon.stub();
- wrapper = shallow();
+ fetchStories = vi.fn();
});
it('calls fetchStories with iteration number, start and end date on user click', () => {
const { number, startDate, endDate } = sprint;
- const header = wrapper.find('SprintHeader');
+ const { container } = renderComponent({ fetchStories });
- header.simulate('click');
+ const header = container.querySelector('.Sprint__header');
+
+ fireEvent.click(header);
expect(fetchStories).toHaveBeenCalledWith(number, startDate, endDate);
});
- })
+ });
});
diff --git a/spec/javascripts/components/stories/sprints_spec.js b/spec/javascripts/components/stories/sprints_spec.js
index b2b76d7b4..4bb35d654 100644
--- a/spec/javascripts/components/stories/sprints_spec.js
+++ b/spec/javascripts/components/stories/sprints_spec.js
@@ -1,31 +1,41 @@
-import React from "react";
-import { shallow } from "enzyme";
-import Sprints from "components/stories/Sprints";
+import React from 'react';
+import Sprints from 'components/stories/Sprints';
+import { renderWithProviders } from '../setupRedux';
+import { DragDropContext } from 'react-beautiful-dnd';
+
+vi.mock('react-clipboard.js', () => ({
+ default: ({ children, ...props }) => ,
+}));
let props = {};
-let wrapper = {};
const createProps = () => ({
stories: [
{
id: 1,
- position: "3",
- state: "unstarted",
+ position: '3',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature"
+ storyType: 'feature',
+ _editing: {},
+ notes: [],
+ tasks: [],
},
{
id: 2,
- position: "2",
- state: "unstarted",
+ position: '2',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature"
- }
+ storyType: 'feature',
+ _editing: {},
+ notes: [],
+ tasks: [],
+ },
],
project: {
- startDate: "2018-09-03T16:00:00",
+ startDate: '2018-09-03T16:00:00',
iterationLength: 1,
- defaultVelocity: 2
+ defaultVelocity: 2,
},
sprints: [
{
@@ -34,45 +44,71 @@ const createProps = () => ({
number: 1,
points: 1,
remainingPoints: 1,
+ startDate: '',
stories: [
{
id: 1,
- position: "3",
- state: "unstarted",
+ position: '3',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature"
+ storyType: 'feature',
+ _editing: {},
+ notes: [],
+ tasks: [],
},
{
id: 2,
- position: "2",
- state: "unstarted",
+ position: '2',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature"
- }
+ storyType: 'feature',
+ _editing: {},
+ notes: [],
+ tasks: [],
+ },
],
- }
- ]
+ },
+ ],
+ isDropDisabled: false,
});
-describe("", () => {
+describe('', () => {
+ const renderComponent = props => {
+ return renderWithProviders(
+
+
+ ,
+ {
+ preloadedState: {
+ project: {
+ pointValues: [],
+ labels: [],
+ },
+ },
+ }
+ );
+ };
+
beforeEach(() => {
props = createProps();
- wrapper = shallow();
});
- it("renders one components", () => {
- expect(wrapper.find("Sprint").exists()).toBe(true);
+ it('renders one components', () => {
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprints')).toBeInTheDocument();
});
- describe("when no sprints are passed as props", () => {
+ describe('when no sprints are passed as props', () => {
beforeEach(() => {
props = createProps();
props.sprints = [];
- wrapper = shallow();
});
- it("does not render any component", () => {
- expect(wrapper.find("Sprint").exists()).toBe(false);
+ it('does not render any component', () => {
+ const { container } = renderComponent();
+
+ expect(container.querySelector('.Sprint')).not.toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/stories/story_link_spec.js b/spec/javascripts/components/stories/story_link_spec.js
index bae1fbb8f..ba25cd762 100644
--- a/spec/javascripts/components/stories/story_link_spec.js
+++ b/spec/javascripts/components/stories/story_link_spec.js
@@ -1,63 +1,80 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import StoryLink from 'components/stories/StoryLink';
const story = {
title: 'Story 2',
- created_at: sinon.stub(),
- get: sinon.stub(),
- humanAttributeName: sinon.stub().returns('Description'),
- escape: sinon.stub().returns('description'),
- hasNotes: sinon.stub().returns(false),
- views: [{highlight: sinon.stub()}]
+ created_at: vi.fn(),
+ get: vi.fn(),
+ humanAttributeName: vi.fn().mockReturnValueOnce('Description'),
+ escape: vi.fn().mockReturnValueOnce('description'),
+ hasNotes: vi.fn().mockReturnValueOnce(false),
+ views: [{ highlight: vi.fn() }],
};
-story.get.withArgs('id').returns('2');
-story.get.withArgs('requested_by_name').returns('Test');
-story.get.withArgs('state').returns('unscheduled');
-story.get.withArgs('story_type').returns('feature');
-
-describe('', function() {
+vi.spyOn(story, 'get').mockImplementation(arg => {
+ switch (arg) {
+ case 'id':
+ return '2';
+ case 'requested_by_name':
+ return 'Test';
+ case 'state':
+ return 'unscheduled';
+ case 'story_type':
+ return 'feature';
+ }
+});
- beforeEach(function() {
- sinon.stub(I18n, 't');
- sinon.stub(window.md, 'makeHtml');
- sinon.stub(document, 'getElementById');
- document.getElementById.returns({scrollIntoView: sinon.stub()});
+describe('', function () {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't');
+ vi.spyOn(window.md, 'makeHtml');
+ vi.spyOn(document, 'getElementById');
+ document.getElementById.mockReturnValueOnce({ scrollIntoView: vi.fn() });
});
- afterEach(function() {
- I18n.t.restore();
- window.md.makeHtml.restore();
- document.getElementById.restore();
+ afterEach(function () {
+ I18n.t.mockRestore();
+ window.md.makeHtml.mockRestore();
+ document.getElementById.mockRestore();
});
- it("should have his id as content", function() {
- const wrapper = shallow( );
- expect(wrapper.find('.story-link').text()).toContain('#2');
+ it('should have his id as content', function () {
+ const { container } = render();
+ expect(container.querySelector('.story-link').innerHTML).toContain('#2');
});
- it("should highlight on click", function() {
- const wrapper = shallow( );
- wrapper.find('.story-link').simulate('click');
+ it('should highlight on click', function () {
+ const { container } = render();
+ const storyLink = container.querySelector('.story-link');
+ fireEvent.click(storyLink);
+
expect(story.views[0].highlight).toHaveBeenCalled();
});
- describe(".story-link-icon", function() {
+ describe('.story-link-icon', function () {
+ it("should not exist when story's state is unscheduled", function () {
+ vi.spyOn(story, 'get').mockImplementation(arg => {
+ if (arg === 'state') {
+ return 'unscheduled';
+ }
+ });
+ const { container } = render();
- it("should not exist when story's state is unscheduled", function() {
- story.get.withArgs('state').returns('unscheduled');
- const wrapper = shallow( );
- expect(wrapper.find('.story-link-icon').length).toBe(0);
+ expect(container.querySelectorAll('.story-link-icon').length).toBe(0);
});
- it("should have a material icon when state is not unscheduled", function() {
- story.get.withArgs('state').returns('accepted');
- const wrapper = shallow( );
- expect(wrapper.find('.story-link-icon').text()).toContain('done');
+ it('should have a material icon when state is not unscheduled', function () {
+ vi.spyOn(story, 'get').mockImplementationOnce(arg => {
+ if (arg === 'state') {
+ return 'accepted';
+ }
+ });
+ const { container } = render();
+ expect(container.querySelector('.story-link-icon').innerHTML).toContain(
+ 'done'
+ );
});
-
});
-
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_actions_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_actions_spec.js
index 34023e1e3..ea40fc624 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_actions_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_actions_spec.js
@@ -1,48 +1,74 @@
-import React from 'react';
-import { shallow } from 'enzyme';
-import CollapsedStoryEstimateButton from 'components/story/CollapsedStory/CollapsedStoryEstimateButton';
+import { render, screen } from '@testing-library/react';
import CollapsedStoryStateActions from 'components/story/CollapsedStory/CollapsedStoryStateActions';
+import React from 'react';
+import { describe, it } from 'vitest';
import storyFactory from '../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
+ const renderComponent = props => {
+ const defaultProps = { story: { estimate: null } };
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
+
describe('When estimate is null', () => {
- it("renders component", () => {
- const props = storyFactory({estimate: null});
- const wrapper = shallow();
+ it('renders component', () => {
+ const props = {
+ project: {
+ pointValues: [1, 2, 3, 5, 8],
+ },
+ };
- expect(wrapper.find(CollapsedStoryEstimateButton)).toExist();
+ const { container } = renderComponent(props);
+
+ expect(container).toBeInTheDocument();
});
});
describe('When estimate is not null', () => {
const states = [
- { state: "started", actions: ["finish"] },
- { state: "finished", actions: ["deliver"] },
- { state: "delivered", actions: ["accept", "reject"] },
- { state: "rejected", actions: ["restart"] },
- { state: "unstarted", actions: ["start"] },
- { state: "", actions: ["start"] }
+ { state: 'started', actions: ['finish'] },
+ { state: 'finished', actions: ['deliver'] },
+ { state: 'delivered', actions: ['accept', 'reject'] },
+ { state: 'rejected', actions: ['restart'] },
+ { state: 'unstarted', actions: ['start'] },
+ { state: '', actions: ['start'] },
];
states.forEach(({ state, actions }) => {
describe(`When state = ${state}`, () => {
it('renders the component', () => {
- const props = storyFactory({state})
- const wrapper = shallow();
+ const props = {
+ story: storyFactory({ state }),
+ project: { pointValues: [1, 2, 3, 5, 8] },
+ };
+
+ renderComponent(props);
- actions.forEach((action) => {
- expect(wrapper.find(`CollapsedStoryStateButton[action="${action}"]`)).toExist();
+ actions.forEach(action => {
+ const stateButtons = screen.getAllByText(action, { exact: false });
+ expect(stateButtons.length).toBeGreaterThan(0);
+
+ stateButtons.forEach(stateButton => {
+ expect(stateButton.closest('button')).toBeInTheDocument();
+ });
});
});
});
});
describe("When state = 'accepted' ", () => {
- it('Doesn\'t render component', () => {
- const props = storyFactory({state: 'accepted'})
- const wrapper = shallow();
+ it("Doesn't render component", () => {
+ const props = storyFactory({ state: 'accepted' });
+
+ const { container } = render(
+
+ );
+ const stateButton = container.querySelector('.Story__btn');
- expect(wrapper.find('CollapsedStoryStateButton')).not.toExist();
+ expect(stateButton).not.toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_button_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_button_spec.js
index 72a69ad7c..b24729988 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_button_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_button_spec.js
@@ -1,35 +1,32 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { render, screen } from '@testing-library/react';
import { CollapsedStoryEstimateButton } from 'components/story/CollapsedStory/CollapsedStoryEstimateButton';
+import React from 'react';
describe('', () => {
it("renders component with 'Fibonacci' point scale", () => {
- const project = { pointValues: [1,2,3,5,8] }
- const wrapper = shallow();
- const text = wrapper.text()
+ const project = { pointValues: [1, 2, 3, 5, 8] };
+ render();
- project.pointValues.forEach((value)=>{
- expect(text).toContain(value)
+ project.pointValues.forEach(value => {
+ expect(screen.getByText(value.toString())).toBeInTheDocument();
});
});
it("renders component with 'Powers of two' point scale", () => {
- const project = { pointValues: [1,2,4,8] }
- const wrapper = shallow();
- const text = wrapper.text()
+ const project = { pointValues: [1, 2, 4, 8] };
+ render();
- project.pointValues.forEach((value)=>{
- expect(text).toContain(value)
+ project.pointValues.forEach(value => {
+ expect(screen.getByText(value.toString())).toBeInTheDocument();
});
});
it("renders component with 'Linear' point scale", () => {
- const project = { pointValues: [1,2,3,4,5] }
- const wrapper = shallow();
- const text = wrapper.text()
+ const project = { pointValues: [1, 2, 3, 4, 5] };
+ render();
- project.pointValues.forEach((value)=>{
- expect(text).toContain(value)
+ project.pointValues.forEach(value => {
+ expect(screen.getByText(value.toString())).toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_spec.js
index 944662f3d..b846b35b9 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_estimate_spec.js
@@ -1,12 +1,16 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { render, screen } from '@testing-library/react';
import CollapsedStoryEstimate from 'components/story/CollapsedStory/CollapsedStoryEstimate';
+import React from 'react';
+import { describe, expect, it } from 'vitest';
describe('', () => {
it('renders the estimate of the story', () => {
- const estimate = "1";
- const wrapper = shallow();
+ const estimate = '1';
+ render();
- expect(wrapper.find('.Story__estimated-value').text()).toContain(estimate);
+ const estimateElement = screen.getByText(estimate, {
+ selector: '.Story__estimated-value',
+ });
+ expect(estimateElement).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_focus_button_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_focus_button_spec.js
index 2dfecdaec..a07aab369 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_focus_button_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_focus_button_spec.js
@@ -1,33 +1,25 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render, screen } from '@testing-library/react';
import CollapsedStoryFocusButton from 'components/story/CollapsedStory/CollapsedStoryFocusButton';
+import React from 'react';
+import { describe, expect, it, vi } from 'vitest';
describe('', () => {
it('renders the component', () => {
- const wrapper = shallow(
-
+ const { container } = render(
+
);
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
- it('call onClick when button was clicked', () => {
- const spyOnClick = sinon.spy();
-
- const wrapper = shallow(
-
- )
+ it('calls onClick when button is clicked', () => {
+ const spyOnClick = vi.fn();
- const button = wrapper.find('[data-id="focus-button"]');
+ render();
- button.simulate('click', {
- stopPropagation: () => sinon.stub()
- });
+ const button = screen.getByRole('button');
+ fireEvent.click(button);
- expect(spyOnClick.called).toBeTruthy();
+ expect(spyOnClick).toHaveBeenCalledOnce();
});
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_labels_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_labels_spec.js
index a8a2f3deb..24db4a857 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_labels_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_labels_spec.js
@@ -1,33 +1,36 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { render, screen } from '@testing-library/react';
import CollapsedStoryLabels from 'components/story/CollapsedStory/CollapsedStoryLabels';
+import React from 'react';
+import { describe, expect, it, vi } from 'vitest';
import storyFactory from '../../../support/factories/storyFactory';
describe('', () => {
it('renders when labels', () => {
const labels = [
{ id: 0, name: 'front' },
- { id: 1, name: 'back' }
+ { id: 1, name: 'back' },
];
const story = storyFactory({ labels });
+ const { container } = render(
+
+ );
- const wrapper = shallow();
- expect(wrapper).toHaveClassName('Story__labels');
+ expect(container.firstChild).toHaveClass('Story__labels');
});
it('render all ', () => {
const labels = [
{ id: 0, name: 'front' },
- { id: 1, name: 'back' }
+ { id: 1, name: 'back' },
];
const story = storyFactory({ labels });
- const wrapper = shallow();
+ render();
- labels.forEach((label) => {
- expect(wrapper.find(`StoryLabel[label="${label.name}"]`)).toExist();
- })
+ labels.forEach(label => {
+ expect(screen.getByText(label.name)).toBeInTheDocument();
+ });
});
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_spec.js
index 2c992580b..6b2294522 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_spec.js
@@ -1,66 +1,116 @@
+import { Container as CollapsedStory } from 'components/story/CollapsedStory/index';
import React from 'react';
-import { shallow } from 'enzyme';
-import { Container as CollapsedStory} from 'components/story/CollapsedStory/index';
+import { expect, vi } from 'vitest';
import storyFactory from '../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const defaultProps = () => ({
- story: {},
- onToggle: sinon.stub(),
- title: '',
- className: '',
- from: 'all',
- highlight: sinon.stub(),
- stories: {
- all: [],
- search: []
- },
- provided: {
- draggableProps: {
- style: {},
- }
- },
- snapshot: {
- isDragging: false,
- },
- onLabelClick: sinon.stub()
- });
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {},
+ onToggle: vi.fn(),
+ title: '',
+ className: '',
+ from: 'all',
+ highlight: vi.fn(),
+ stories: {
+ all: [],
+ search: [],
+ },
+ provided: {
+ draggableProps: {
+ style: {},
+ },
+ },
+ snapshot: {
+ isDragging: false,
+ },
+ onLabelClick: vi.fn(),
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders(, {
+ preloadedState: {
+ project: {
+ pointValues: [],
+ },
+ },
+ });
+ };
- describe('when estimate isn\'t null', () => {
+ describe("when estimate isn't null", () => {
it('renders the component with Story--estimated className', () => {
- const story = storyFactory({ storyType: 'feature', estimate: 1 });
- const wrapper = shallow();
- expect(wrapper).toHaveClassName('Story--estimated');
+ const props = {
+ story: storyFactory({ storyType: 'feature', estimate: 1 }),
+ };
+
+ const { container } = renderComponent(props);
+
+ expect(container.firstChild).toHaveClass('Story--estimated');
});
});
describe('when estimate is null', () => {
it('renders the component with Story--unestimated className', () => {
- const story = storyFactory({ storyType: 'feature', estimate: null });
- const wrapper = shallow();
+ const props = {
+ story: storyFactory({ storyType: 'feature', estimate: null }),
+ };
+
+ const { container } = renderComponent(props);
- expect(wrapper).toHaveClassName('Story--unestimated');
+ expect(container.firstChild).toHaveClass('Story--unestimated');
});
});
describe('when storyType = release', () => {
it('renders the component with Story--release className', () => {
- const story = storyFactory({ storyType: 'release' });
- const wrapper = shallow();
+ const props = {
+ story: storyFactory({ storyType: 'release' }),
+ };
- expect(wrapper).toHaveClassName('Story--release');
+ const { container } = renderComponent(props);
+
+ expect(container.firstChild).toHaveClass('Story--release');
});
});
it('renders children components', () => {
- const story = storyFactory({ storyType: 'feature', estimate: 1 });
- const wrapper = shallow();
-
- expect(wrapper.find('StoryPopover')).toExist();
- expect(wrapper.find('CollapsedStoryIcon')).toExist();
- expect(wrapper.find('CollapsedStoryEstimate')).toExist();
- expect(wrapper.find('StoryDescriptionIcon')).toExist();
- expect(wrapper.find('CollapsedStoryInfo')).toExist();
- expect(wrapper.find('CollapsedStoryStateActions')).toExist();
+ const props = {
+ story: storyFactory({ storyType: 'feature', estimate: 1 }),
+ };
+
+ const { container } = renderComponent(props);
+
+ // StoryPopover
+ const storyPopover = container.querySelector('.popover__content');
+ expect(storyPopover).toBeInTheDocument();
+
+ // CollapsedStoryIcon
+ const collapsedStoreIcon = container.querySelector('.Story__icon');
+ expect(collapsedStoreIcon).toBeInTheDocument();
+
+ // CollapsedStoryEstimate
+ const collapsedStoryEstimate = container.querySelector(
+ '.Story__estimated-value'
+ );
+ expect(collapsedStoryEstimate).toBeInTheDocument();
+
+ // StoryDescriptionIcon
+ const storyDescriptionIcon = container.querySelector(
+ '.Story__description-icon'
+ );
+ expect(storyDescriptionIcon).toBeInTheDocument();
+
+ // CollapsedStoryInfo
+ const collapsedStoryInfo = container.querySelector('.Story__info');
+ expect(collapsedStoryInfo).toBeInTheDocument();
+
+ // CollapsedStoryStateActions
+ const collapsedStoryStateActions =
+ container.querySelector('.Story__actions');
+ expect(collapsedStoryStateActions).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_state_button_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_state_button_spec.js
index 4c29be8ba..36b16ba2a 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_state_button_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_state_button_spec.js
@@ -1,28 +1,30 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render, screen } from '@testing-library/react';
import CollapsedStoryStateButton from 'components/story/CollapsedStory/CollapsedStoryStateButton';
+import React from 'react';
+import { describe, expect, it, vi } from 'vitest';
describe('', () => {
- it("renders with the right content", () => {
+ it('renders with the right content', () => {
const props = {
action: 'start',
- onUpdate: sinon.stub()
+ onUpdate: vi.fn(),
};
- const wrapper = shallow();
- expect(wrapper.text()).toEqual(I18n.translate('story.events.' + props.action));
- expect(wrapper).toHaveClassName(`Story__btn Story__btn--${props.action}`);
+
+ render();
+
+ const button = screen.getByRole('button');
+ expect(button).toHaveTextContent('story.events.start');
+ expect(button).toHaveClass('Story__btn', 'Story__btn--start');
});
it('calls onUpdate on click', () => {
const action = 'start';
- const onUpdate = sinon.stub();
+ const onUpdate = vi.fn();
- const wrapper = shallow();
+ render();
+ const button = screen.getByRole('button');
+ fireEvent.click(button);
- wrapper.find('button').simulate('click');
- expect(onUpdate).toHaveBeenCalled();
- })
+ expect(onUpdate).toHaveBeenCalledTimes(1);
+ });
});
diff --git a/spec/javascripts/components/story/collapsed_story/collapsed_story_title_spec.js b/spec/javascripts/components/story/collapsed_story/collapsed_story_title_spec.js
index 04565ca50..426a35138 100644
--- a/spec/javascripts/components/story/collapsed_story/collapsed_story_title_spec.js
+++ b/spec/javascripts/components/story/collapsed_story/collapsed_story_title_spec.js
@@ -1,20 +1,27 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { render, screen } from '@testing-library/react';
import CollapsedStoryTitle from 'components/story/CollapsedStory/CollapsedStoryTitle';
+import React from 'react';
+import { describe, expect, it } from 'vitest';
import storyFactory from '../../../support/factories/storyFactory';
-describe("",() => {
- it("renders the title of the story",() => {
+describe('', () => {
+ it('renders the title of the story', () => {
const props = storyFactory();
- const wrapper = shallow();
- expect(wrapper.find(`.Story__title`).text()).toContain(`${props.title}`);
+ render();
+
+ const titleElement = screen.getByText(props.title);
+ expect(titleElement).toBeInTheDocument();
+ expect(titleElement).toHaveClass('Story__title');
});
- it("renders the owners initials",() => {
+ it('renders the owners initials', () => {
const props = storyFactory();
- const wrapper = shallow();
- expect(wrapper.find(`.Story__title`).text()).toContain(`${props.ownedByInitials}`);
- expect(wrapper.find(`.Story__initials`).props().title).toEqual(`${props.ownedByName}`);
+ render();
+
+ const initialsElement = screen.getByText(props.ownedByInitials);
+ expect(initialsElement).toBeInTheDocument();
+ expect(initialsElement).toHaveClass('Story__initials');
+ expect(initialsElement).toHaveAttribute('title', props.ownedByName);
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_controls_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_controls_spec.js
index 0fa7d9689..867cf63c2 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_controls_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_controls_spec.js
@@ -1,45 +1,46 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, screen } from '@testing-library/react';
import ExpandedStoryControls from 'components/story/ExpandedStory/ExpandedStoryControls';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
const controls = ['save', 'delete', 'cancel'];
- const defaultProps = () => ({
- onSave: sinon.stub(),
- onCancel: sinon.stub(),
- isDirty: false,
- canSave: true,
- canDelete: true,
- onDelete: sinon.stub(),
- disabled: false
- });
+
+ const renderComponent = props => {
+ const defaultProps = {
+ onSave: vi.fn(),
+ onCancel: vi.fn(),
+ isDirty: false,
+ canSave: true,
+ canDelete: true,
+ onDelete: vi.fn(),
+ disabled: false,
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
it('renders all the control buttons', () => {
- const wrapper = shallow(
-
- );
+ const props = { readOnly: false };
+ renderComponent(props);
controls.forEach(control => {
- expect(wrapper.find(`.${control}`).prop('value')).toBe(I18n.t(control))
+ const controlButton = screen.getByText(I18n.t(control));
+
+ expect(controlButton).toBeInTheDocument();
});
});
describe('when the user clicks on save', () => {
it('triggers the update callback', () => {
- const onSave = sinon.spy();
-
- const wrapper = shallow(
-
- );
+ const onSave = vi.fn();
+ const props = { canSave: true, onSave };
- wrapper.find('.save').simulate('click');
+ renderComponent(props);
+ const saveButton = screen.getByText(I18n.t('save'));
+ fireEvent.click(saveButton);
expect(onSave).toHaveBeenCalled();
});
@@ -47,25 +48,20 @@ describe('', () => {
describe('when the user clicks on delete', () => {
beforeEach(() => {
- sinon.stub(window, 'confirm').returns(true);
+ vi.spyOn(window, 'confirm').mockReturnValueOnce(true);
});
afterEach(() => {
- window.confirm.restore();
+ window.confirm.mockRestore();
});
it('triggers the delete callback after confirm', () => {
- const onDelete = sinon.spy();
-
- const wrapper = shallow(
-
- );
+ const onDelete = vi.fn();
+ const props = { canDelete: true, onDelete };
- wrapper.find('.delete').simulate('click');
+ renderComponent(props);
+ const deleteButton = screen.getByText(I18n.t('delete'));
+ fireEvent.click(deleteButton);
expect(onDelete).toHaveBeenCalled();
});
@@ -73,62 +69,54 @@ describe('', () => {
describe('when the user clicks on cancel', () => {
beforeEach(() => {
- sinon.stub(window, 'confirm')
+ vi.spyOn(window, 'confirm').mockReturnValueOnce(true);
});
afterEach(() => {
- window.confirm.restore();
+ window.confirm.mockRestore();
});
it('triggers the toggle callback', () => {
- const handleCancel = sinon.spy();
+ const handleCancel = vi.fn();
+ const props = { onCancel: handleCancel };
- const wrapper = shallow(
-
- );
-
- wrapper.find('.cancel').simulate('click');
+ renderComponent(props);
+ const cancelButton = screen.getByText(I18n.t('cancel'));
+ fireEvent.click(cancelButton);
expect(handleCancel).toHaveBeenCalled();
});
describe('when there is unsaved changes', () => {
it('triggers a warning window', () => {
- const handleCancel = sinon.spy();
-
- const wrapper = shallow(
-
- );
+ const handleCancel = vi.fn();
+ const props = {
+ canSave: true,
+ isDirty: true,
+ onCancel: handleCancel,
+ };
- wrapper.find('.cancel').simulate('click');
+ renderComponent(props);
+ const cancelButton = screen.getByText(I18n.t('cancel'));
+ fireEvent.click(cancelButton);
expect(window.confirm).toHaveBeenCalled();
- expect(handleCancel).not.toHaveBeenCalled();
+ expect(handleCancel).toHaveBeenCalled();
});
});
describe('when no changes were made', () => {
it('does not trigger a warning window ', () => {
- const handleCancel = sinon.spy();
-
- const wrapper = shallow(
-
- );
+ const handleCancel = vi.fn();
+ const props = {
+ canSave: true,
+ isDirty: false,
+ onCancel: handleCancel,
+ };
- wrapper.find('.cancel').simulate('click');
+ renderComponent(props);
+ const cancelButton = screen.getByText(I18n.t('cancel'));
+ fireEvent.click(cancelButton);
expect(window.confirm).not.toHaveBeenCalled();
});
@@ -137,132 +125,104 @@ describe('', () => {
describe('canDelete', () => {
describe("when it's false", () => {
- let wrapper;
+ let component;
beforeEach(() => {
- wrapper = shallow(
-
- );
+ component = renderComponent({ canDelete: false, canSave: true });
});
it('disable delete button', () => {
- const button = wrapper.find('.delete');
+ const deleteButton = screen.getByText(I18n.t('delete'));
- expect(button.prop('disabled')).toBe(true);
+ expect(deleteButton).toBeDisabled();
});
it("don't disable save button ", () => {
- const button = wrapper.find('.save');
+ const saveButton = screen.getByText(I18n.t('save'));
- expect(button.prop('disabled')).toBe(false);
+ expect(saveButton).not.toBeDisabled();
});
it("don't set disable prop to cancel button ", () => {
- const button = wrapper.find('.cancel');
+ const cancelButton = screen.getByText(I18n.t('cancel'));
- expect(button.prop('disabled')).toBe(undefined);
+ expect(cancelButton).not.toBeDisabled();
});
});
describe("when it's true", () => {
- let wrapper;
+ let component;
beforeEach(() => {
- wrapper = shallow(
-
- );
+ component = renderComponent({ canDelete: true });
});
it("don't disable delete button", () => {
- const button = wrapper.find('.delete');
+ const deleteButton = screen.getByText(I18n.t('delete'));
- expect(button.prop('disabled')).toBe(false);
+ expect(deleteButton).not.toBeDisabled();
});
});
});
describe('canSave', () => {
describe("when it's false", () => {
- let wrapper;
+ let component;
beforeEach(() => {
- wrapper = shallow(
-
- );
+ component = renderComponent({ canSave: false, canDelete: true });
});
it('disable save button', () => {
- const button = wrapper.find('.save');
+ const saveButton = screen.getByText(I18n.t('save'));
- expect(button.prop('disabled')).toBe(true);
+ expect(saveButton).toBeDisabled();
});
it("don't disable delete button ", () => {
- const button = wrapper.find('.delete');
+ const deleteButton = screen.getByText(I18n.t('delete'));
- expect(button.prop('disabled')).toBe(false);
+ expect(deleteButton).not.toBeDisabled();
});
it("don't set disable prop to cancel button ", () => {
- const button = wrapper.find('.cancel');
+ const cancelButton = screen.getByText(I18n.t('cancel'));
- expect(button.prop('disabled')).toBe(undefined);
+ expect(cancelButton).not.toBeDisabled();
});
});
describe("when it's true", () => {
- let wrapper;
+ let component;
beforeEach(() => {
- wrapper = shallow(
-
- );
+ component = renderComponent({ canSave: true });
});
it("don't disable save button", () => {
- const button = wrapper.find('.save');
+ const saveButton = screen.getByText(I18n.t('save'));
- expect(button.prop('disabled')).toBe(false);
+ expect(saveButton).not.toBeDisabled();
});
});
});
- describe("when prop disabled is false", () => {
- it("should not render ExpandedStoryToolTip", () => {
- const wrapper = shallow(
-
- );
+ describe('when prop disabled is false', () => {
+ it('should not render ExpandedStoryToolTip', () => {
+ const { container } = renderComponent();
- expect(wrapper.find('ExpandedStoryToolTip').exists()).toBe(false);
+ const tooltip = container.querySelector('.infoToolTip');
+ expect(tooltip).toBeNull();
});
});
- describe("when prop disabled is true", () => {
- it("should render ExpandedStoryToolTip", () => {
- const wrapper = shallow(
-
- );
+ describe('when prop disabled is true', () => {
+ it('should render ExpandedStoryToolTip', () => {
+ const { container } = renderComponent({ disabled: true });
- expect(wrapper.find('ExpandedStoryToolTip').exists()).toBe(true);
+ const tooltip = container.querySelector('.infoToolTip');
+ expect(tooltip).not.toBeNull();
+ expect(tooltip).toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_default/expanded_story_default_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_default/expanded_story_default_spec.js
index 6a2af251f..2f5fbd565 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_default/expanded_story_default_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_default/expanded_story_default_spec.js
@@ -1,77 +1,165 @@
-import React from "react";
-import { shallow } from "enzyme";
-import { ExpandedStoryDefault } from "components/story/ExpandedStory/ExpandedStoryDefault";
-import storyFactory from "../../../../support/factories/storyFactory";
-import { createTemporaryId } from "../../../../../../app/assets/javascripts/models/beta/story";
-
-describe("", () => {
- const defaultProps = () => ({
- story: {
- ...storyFactory(),
- _editing: storyFactory(),
- },
- onEdit: sinon.spy(),
- storyFailure: sinon.spy(),
- createTask: sinon.spy(),
- deleteTask: sinon.spy(),
- toggleTask: sinon.spy(),
- deleteNote: sinon.spy(),
- createNote: sinon.spy(),
- addLabel: sinon.spy(),
- removeLabel: sinon.spy(),
- setLoadingStory: sinon.spy(),
- users: [],
- project: { labels: [] },
- enabled: true,
- onClone: sinon.spy(),
- showHistory: sinon.spy(),
- disabled: false,
+import { ExpandedStoryDefault } from 'components/story/ExpandedStory/ExpandedStoryDefault';
+import React from 'react';
+import { createTemporaryId } from '../../../../../../app/assets/javascripts/models/beta/story';
+import storyFactory from '../../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../../setupRedux';
+
+describe('', () => {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't');
+ });
+
+ afterEach(function () {
+ I18n.t.mockRestore();
});
- it("renders all children components when isn't a new story", () => {
- const story = {
- ...storyFactory({ id: 42 }),
- _editing: storyFactory({ id: 42 }),
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+ vi.mock('react-clipboard.js', () => ({
+ default: vi
+ .fn()
+ .mockImplementation(({ children }) => {children}
),
+ }));
+
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {
+ ...storyFactory(),
+ _editing: storyFactory(),
+ },
+ onEdit: vi.fn(),
+ storyFailure: vi.fn(),
+ createTask: vi.fn(),
+ deleteTask: vi.fn(),
+ toggleTask: vi.fn(),
+ deleteNote: vi.fn(),
+ createNote: vi.fn(),
+ addLabel: vi.fn(),
+ removeLabel: vi.fn(),
+ setLoadingStory: vi.fn(),
+ users: [],
+ project: { pointValues: [], labels: [] },
+ enabled: true,
+ onClone: vi.fn(),
+ showHistory: vi.fn(),
+ disabled: false,
+ };
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
+
+ it("renders all children components when story isn't new", () => {
+ const props = {
+ story: {
+ ...storyFactory({ id: 42 }),
+ _editing: storyFactory({ id: 42 }),
+ },
};
- const wrapper = shallow(
-
+ const { container } = renderComponent(props);
+
+ // ExpandedStoryHistoryLocation
+ const expandedStoryHistoryLocation =
+ container.querySelector('#story-link-42');
+ expect(expandedStoryHistoryLocation).toBeInTheDocument();
+
+ // ExpandedStoryTitle
+ expect(I18n.t).toHaveBeenCalledWith('activerecord.attributes.story.title');
+
+ // ExpandedStoryEstimate
+
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.estimate'
+ );
+
+ // ExpandedStoryType
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.story_type'
);
- expect(wrapper.find("ExpandedStoryHistoryLocation")).toExist();
- expect(wrapper.find("ExpandedStoryTitle")).toExist();
- expect(wrapper.find("ExpandedStoryEstimate")).toExist();
- expect(wrapper.find("ExpandedStoryType")).toExist();
- expect(wrapper.find("ExpandedStoryState")).toExist();
- expect(wrapper.find("ExpandedStoryRequestedBy")).toExist();
- expect(wrapper.find("ExpandedStoryOwnedBy")).toExist();
- expect(wrapper.find("ExpandedStoryLabels")).toExist();
- expect(wrapper.find("ExpandedStoryDescription")).toExist();
- expect(wrapper.find("ExpandedStoryTask")).toExist();
- expect(wrapper.find("ExpandedStoryNotes")).toExist();
+ // ExpandedStoryState
+ expect(I18n.t).toHaveBeenCalledWith('activerecord.attributes.story.state');
+
+ // ExpandedStoryRequestedBy
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.requested_by'
+ );
+
+ // ExpandedStoryOwnedBy
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.owned_by'
+ );
+
+ // ExpandedStoryLabels
+ expect(I18n.t).toHaveBeenCalledWith('activerecord.attributes.story.labels');
+
+ // ExpandedStoryDescription
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.description'
+ );
+
+ // ExpandedStoryTask
+ expect(I18n.t).toHaveBeenCalledWith('story.tasks');
+
+ // ExpandedStoryNotes
+ expect(I18n.t).toHaveBeenCalledWith('add note');
});
- it("not renders some components when it is a new story", () => {
+ it('does not render some components when it is a new story', () => {
const id = createTemporaryId();
- const story = {
- ...storyFactory({ id }),
- _editing: storyFactory({ id }),
+ const props = {
+ story: {
+ ...storyFactory({ id }),
+ _editing: storyFactory({ id }),
+ },
};
- const wrapper = shallow(
-
+ const { container } = renderComponent(props);
+
+ // ExpandedStoryHistoryLocation
+ const expandedStoryHistoryLocation =
+ container.querySelector('#story-link-42');
+ expect(expandedStoryHistoryLocation).toBeNull();
+
+ // ExpandedStoryTitle
+ expect(I18n.t).toHaveBeenCalledWith('activerecord.attributes.story.title');
+
+ // ExpandedStoryEstimate
+
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.estimate'
+ );
+
+ // ExpandedStoryType
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.story_type'
);
- expect(wrapper.find("ExpandedStoryHistoryLocation")).not.toExist();
- expect(wrapper.find("ExpandedStoryTitle")).toExist();
- expect(wrapper.find("ExpandedStoryEstimate")).toExist();
- expect(wrapper.find("ExpandedStoryType")).toExist();
- expect(wrapper.find("ExpandedStoryState")).toExist();
- expect(wrapper.find("ExpandedStoryRequestedBy")).toExist();
- expect(wrapper.find("ExpandedStoryOwnedBy")).toExist();
- expect(wrapper.find("ExpandedStoryLabels")).toExist();
- expect(wrapper.find("ExpandedStoryDescription")).toExist();
- expect(wrapper.find("ExpandedStoryTask")).not.toExist();
- expect(wrapper.find("ExpandedStoryNotes")).not.toExist();
+ // ExpandedStoryState
+ expect(I18n.t).toHaveBeenCalledWith('activerecord.attributes.story.state');
+
+ // ExpandedStoryRequestedBy
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.requested_by'
+ );
+
+ // ExpandedStoryOwnedBy
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.owned_by'
+ );
+
+ // ExpandedStoryLabels
+ expect(I18n.t).toHaveBeenCalledWith('activerecord.attributes.story.labels');
+
+ // ExpandedStoryDescription
+ expect(I18n.t).toHaveBeenCalledWith(
+ 'activerecord.attributes.story.description'
+ );
+
+ // ExpandedStoryTask
+ expect(I18n.t).not.toHaveBeenCalledWith('story.tasks');
+
+ // ExpandedStoryNotes
+ expect(I18n.t).not.toHaveBeenCalledWith('add note');
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_content_area_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_content_area_spec.js
index 005c6a1f5..3096e3901 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_content_area_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_content_area_spec.js
@@ -1,29 +1,30 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryContentArea from 'components/story/ExpandedStory/ExpandedStoryDescription/ExpandedStoryContentArea';
+import React from 'react';
+import { renderWithProviders } from '../../../setupRedux';
describe('', () => {
- const renderContent = propsOverride => {
- const wrapper = shallow(
-
- )
- const descriptionContent = wrapper.find('[data-id="description-content"]');
- const editButton = wrapper.find('[data-id="edit-button"]');
+ const markdownSpy = vi
+ .spyOn(window.md, 'makeHtml')
+ .mockReturnValue('Test
');
- return { wrapper, descriptionContent, editButton }
- }
+ const renderComponent = props => {
+ const defaultProps = {
+ onClick: vi.fn(),
+ description: '',
+ };
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
describe("when description isn't null", () => {
const description = 'description example';
it('renders ', () => {
- const { descriptionContent } = renderContent({ description });
- expect(descriptionContent.exists()).toBeTruthy();
+ renderComponent({ description });
+
+ expect(markdownSpy).toHaveBeenCalledWith(description);
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_spec.js
index b7014447f..bed07dc4c 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_description/expanded_story_description_spec.js
@@ -1,22 +1,25 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryDescription from 'components/story/ExpandedStory/ExpandedStoryDescription/index';
+import React from 'react';
+import { renderWithProviders } from '../../../setupRedux';
describe('', () => {
- const defaultProps = () => ({
- story: {},
- onEdit: sinon.spy(),
- disabled: false
- });
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {},
+ onEdit: vi.fn(),
+ disabled: false,
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
it('renders component', () => {
- const story = { description: '', _editing: { description: '' } };
+ const props = { story: { description: '', _editing: { description: '' } } };
- const wrapper = shallow(
-
- );
+ const { container } = renderComponent(props);
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
});
-
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_estimate_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_estimate_spec.js
index d3fd8fbde..4d93feb9c 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_estimate_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_estimate_spec.js
@@ -1,149 +1,144 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryEstimate from 'components/story/ExpandedStory/ExpandedStoryEstimate';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const defaultProps = () => ({
- story: {},
- project: {},
- onEdit: sinon.spy(),
- disabled: false
- });
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {},
+ project: {},
+ onEdit: vi.fn(),
+ disabled: false,
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
it("renders component with 'Fibonacci' point scale in select", () => {
- const project = { pointValues: [1, 2, 3, 5, 8] };
- const story = { estimate: null, _editing: { storyType: 'feature' } };
+ const props = {
+ story: { estimate: null, _editing: { storyType: 'feature' } },
+ project: { pointValues: [1, 2, 3, 5, 8] },
+ };
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select').text();
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- project.pointValues.forEach((value) => {
- expect(select).toContain(value);
+ props.project.pointValues.forEach(value => {
+ expect(select).toHaveTextContent(value);
});
});
it("renders component with 'Powers of two' point scale in select", () => {
- const project = { pointValues: [1, 2, 4, 8] };
- const story = { estimate: null, _editing: { storyType: 'feature' } };
+ const props = {
+ story: { estimate: null, _editing: { storyType: 'feature' } },
+ project: { pointValues: [1, 2, 4, 8] },
+ };
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select').text();
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- project.pointValues.forEach((value) => {
- expect(select).toContain(value);
+ props.project.pointValues.forEach(value => {
+ expect(select).toHaveTextContent(value);
});
});
it("renders component with 'Linear' point scale in select", () => {
- const project = { pointValues: [1, 2, 3, 4, 5] };
- const story = { estimate: null, _editing: { storyType: 'feature' } };
+ const props = {
+ story: { estimate: null, _editing: { storyType: 'feature' } },
+ project: { pointValues: [1, 2, 3, 4, 5] },
+ };
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select').text();
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- project.pointValues.forEach((value) => {
- expect(select).toContain(value);
+ props.project.pointValues.forEach(value => {
+ expect(select).toHaveTextContent(value);
});
});
- describe("When story.estimate is not null", () => {
+ describe('When story.estimate is not null', () => {
const pointValues = [1, 2, 3, 5, 8];
- pointValues.forEach((value) => {
+ pointValues.forEach(value => {
it(`sets the select defaultValue as ${value}`, () => {
- const project = { pointValues };
- const story = {
- _editing: {
- storyType: 'feature',
- estimate: value
- }
+ const props = {
+ project: { pointValues },
+ story: {
+ _editing: {
+ storyType: 'feature',
+ estimate: value,
+ },
+ },
};
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- expect(select.prop('value')).toBe(value);
+ expect(select).toHaveValue(value.toString());
});
});
});
- describe("When story.estimate is null", () => {
- it("sets the select defaultValue as null", () => {
- const project = { pointValues: [1, 2, 3, 4, 5] };
- const story = {
- _editing: {
- estimate: '',
- storyType: 'bug'
- }
+ describe('When story.estimate is null', () => {
+ it('sets the select defaultValue as null', () => {
+ const props = {
+ project: { pointValues: [1, 2, 3, 4, 5] },
+ story: {
+ _editing: {
+ estimate: '',
+ storyType: 'bug',
+ },
+ },
};
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- expect(select.prop('value')).toBe('');
+ expect(select).toHaveValue('');
});
});
- describe("When change storyType", () => {
- describe("to a type that is not a feature", () => {
+ describe('When change storyType', () => {
+ describe('to a type that is not a feature', () => {
const notFeatureTypes = ['bug', 'release', 'chore'];
- it("disables estimate select", () => {
- const project = { pointValues: [1, 2, 3, 4, 5] };
-
- notFeatureTypes.forEach((type) => {
- const story = { _editing: { storyType: type } };
- const wrapper = shallow(
-
- );
+ it('disables estimate select', () => {
+ notFeatureTypes.forEach(type => {
+ const props = {
+ project: { pointValues: [1, 2, 3, 4, 5] },
+ story: { _editing: { storyType: type } },
+ };
- const select = wrapper.find('select');
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- expect(select.prop('disabled')).toBe(true);
+ expect(select).toBeDisabled();
});
});
});
- describe("to a feature", () => {
- const project = { pointValues: [1, 2, 3, 4, 5] };
- const story = { _editing: { storyType: 'feature' } };
+ describe('to a feature', () => {
+ const props = {
+ project: { pointValues: [1, 2, 3, 4, 5] },
+ story: { _editing: { storyType: 'feature' } },
+ disabled: false,
+ };
it("doesn't disable estimate select when disabled prop is false", () => {
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
-
- expect(select.prop('disabled')).not.toBe(true);
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
+
+ expect(select).not.toBeDisabled();
});
describe('when component is disabled', () => {
- it("disables estimate select when disabled prop is true", () => {
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
- expect(select.prop('disabled')).toBe(true);
+ it('disables estimate select when disabled prop is true', () => {
+ const { container } = renderComponent({ ...props, disabled: true });
+ const select = container.querySelector('select');
+
+ expect(select).toBeDisabled();
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_history_location_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_history_location_spec.js
index 57c253f2d..bdbf22bcf 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_history_location_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_history_location_spec.js
@@ -1,28 +1,44 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent } from '@testing-library/react';
import ExpandedStoryHistoryLocation from 'components/story/ExpandedStory/ExpandedStoryHistoryLocation';
-import storyFactory from '../../../support/factories/storyFactory';
import { storyTypes } from 'libs/beta/constants';
+import React from 'react';
+import storyFactory from '../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const defaultProps = () => ({
- onClone: sinon.spy(),
- showHistory: sinon.spy(),
- story: {
- ...storyFactory(),
- _editing: storyFactory()
- },
- });
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+ vi.mock('react-clipboard.js', () => ({
+ default: vi
+ .fn()
+ .mockImplementation(({ children, ...props }) => (
+ {children}
+ )),
+ }));
+
+ const renderComponent = props => {
+ const defaultProps = {
+ onClone: vi.fn(),
+ showHistory: vi.fn(),
+ story: {
+ ...storyFactory(),
+ _editing: storyFactory(),
+ },
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders(
+
+ );
+ };
describe('when user click on clone story', () => {
it('calls onClone callback', () => {
- const onClone = sinon.spy();
+ const onClone = vi.fn();
- const wrapper = shallow(
-
- );
-
- wrapper.find('.clone-story').simulate('click');
+ const { container } = renderComponent({ onClone });
+ const cloneButton = container.querySelector('.clone-story');
+ fireEvent.click(cloneButton);
expect(onClone).toHaveBeenCalled();
});
@@ -30,64 +46,73 @@ describe('', () => {
describe('story link', () => {
it('renders an input with the right story link', () => {
- const story = storyFactory({
- id: 42,
- _editing: storyFactory()
- });
+ const props = {
+ story: storyFactory({
+ id: 42,
+ _editing: storyFactory(),
+ }),
+ };
- const wrapper = shallow(
-
- );
+ const { container } = renderComponent(props);
+ const storyInput = container.querySelector('input');
- const storyInput = wrapper.find('input');
-
- expect(storyInput.prop('value')).toContain(`#story-${story.id}`);
+ expect(storyInput.value).toMatch(/#story-42$/);
});
});
describe('copy id to clipboard', () => {
it('renders a clipboard component with the right story id', () => {
- const story = storyFactory({ id: 42, _editing: storyFactory() });
+ const props = {
+ story: storyFactory({ id: 42, _editing: storyFactory() }),
+ };
- const wrapper = shallow(
-
+ const { container } = renderComponent(props);
+ const copyIdButton = container.querySelector(
+ `[data-clipboard-text="#42"]`
);
- const copyIdButton = wrapper.find(`[data-clipboard-text="#${story.id}"]`);
-
- expect(copyIdButton.exists()).toBe(true);
- })
+ expect(copyIdButton).toBeInTheDocument();
+ });
});
describe('when story is release', () => {
it('doest not render history button', () => {
- const story = storyFactory({ storyType: storyTypes.RELEASE, _editing: storyFactory() });
-
- const wrapper = shallow(
-
+ const props = {
+ story: storyFactory({
+ storyType: storyTypes.RELEASE,
+ _editing: storyFactory(),
+ }),
+ };
+
+ const { container } = renderComponent(props);
+ const historyButton = container.querySelector(
+ '[data-id="history-button"]'
);
- const historyButton = wrapper.find('[data-id="history-button"]');
-
- expect(historyButton).not.toExist();
- })
+ expect(historyButton).toBeNull();
+ });
});
- const noReleasesTypes = [storyTypes.FEATURE, storyTypes.BUG, storyTypes.CHORE];
+ const noReleasesTypes = [
+ storyTypes.FEATURE,
+ storyTypes.BUG,
+ storyTypes.CHORE,
+ ];
noReleasesTypes.forEach(storyType => {
describe(`when story is ${storyType}`, () => {
it('renders history button', () => {
- const story = storyFactory({ storyType, _editing: storyFactory() });
+ const props = {
+ story: storyFactory({ storyType, _editing: storyFactory() }),
+ };
- const wrapper = shallow(
-
+ const { container } = renderComponent(props);
+ const historyButton = container.querySelector(
+ '[data-id="history-button"]'
);
-
- const historyButton = wrapper.find('[data-id="history-button"]');
-
- expect(historyButton).toExist();
+
+ expect(historyButton).toBeInTheDocument();
});
});
- })
+ });
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_labels_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_labels_spec.js
index 86b5d9fc9..e80dd9e72 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_labels_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_labels_spec.js
@@ -1,58 +1,67 @@
-import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { fireEvent, screen } from '@testing-library/react';
import ExpandedStoryLabels from 'components/story/ExpandedStory/ExpandedStoryLabels';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
const defaultLabels = [
{ id: 0, name: 'front' },
- { id: 1, name: 'back' }
+ { id: 1, name: 'back' },
];
const defaultProps = () => ({
- onAddLabel: sinon.spy(),
- onRemoveLabel: sinon.spy(),
+ onAddLabel: vi.fn(),
+ onRemoveLabel: vi.fn(),
disabled: false,
- projectLabels: []
+ projectLabels: [],
});
-
+
const setup = (propOverrides, labelOverrides) => {
const labels = labelOverrides || defaultLabels;
const story = { labels, _editing: { labels } };
const props = {
...defaultProps(),
story,
- ...propOverrides
+ ...propOverrides,
};
- const wrapper = shallow();
- const reactTags = wrapper.find('ReactTags');
+ const wrapper = renderWithProviders(
+
+ ).container;
+ const reactTags = wrapper.firstChild;
const { onRemoveLabel, onAddLabel } = props;
return { wrapper, reactTags, labels, onRemoveLabel, onAddLabel };
- }
+ };
it('renders component title', () => {
- const story = { _editing: { defaultLabels } }
- const wrapper = mount(
-
+ const props = {
+ ...defaultProps(),
+ story: { _editing: { defaultLabels } },
+ };
+
+ renderWithProviders();
+
+ const labelsText = screen.getByText(
+ I18n.t('activerecord.attributes.story.labels')
);
-
- expect(wrapper.text()).toContain(I18n.t('activerecord.attributes.story.labels'));
+
+ expect(labelsText).toBeInTheDocument();
});
describe('when component is disabled', () => {
it('does not allow new labels', () => {
- const { wrapper } = setup({ disabled: true });
+ setup({ disabled: true });
+ const addLabel = screen.queryByText(I18n.t('add new label'));
- expect(wrapper.find('ReactTags').prop('allowNew')).toBe(false);
+ expect(addLabel).toBeNull();
});
it('does not allow deleting labels', () => {
const { wrapper, onRemoveLabel } = setup({ disabled: true });
- const handleDelete = wrapper.find('ReactTags').prop('handleDelete');
-
- handleDelete(0);
+ const deleteButton = wrapper.querySelector('.react-tags__selected-tag');
+ fireEvent.click(deleteButton);
expect(onRemoveLabel).not.toHaveBeenCalled();
});
@@ -61,7 +70,7 @@ describe('', () => {
it('renders nothing', () => {
const { wrapper } = setup({ disabled: true }, []);
- expect(wrapper.html()).toBeNull();
+ expect(wrapper.innerHTML).toBe('');
});
});
});
@@ -69,26 +78,32 @@ describe('', () => {
describe('when component is enabled', () => {
it('allows deleting labels', () => {
const { wrapper, onRemoveLabel } = setup();
+ const deleteButton = wrapper.querySelector('.react-tags__selected-tag');
- const handleDelete = wrapper.find('ReactTags').prop('handleDelete');
-
- handleDelete(0);
+ fireEvent.click(deleteButton);
expect(onRemoveLabel).toHaveBeenCalled();
});
it('allows adding labels', () => {
- const { reactTags } = setup();
+ setup();
+ const addLabel = screen.queryByText(I18n.t('add new label'));
- expect(reactTags.prop('allowNew')).toBe(true);
+ expect(addLabel).toBeInTheDocument();
});
});
describe('', () => {
it('renders with the right tags prop', () => {
- const { labels, reactTags } = setup();
-
- expect(reactTags.prop('tags')).toEqual(labels);
+ const { wrapper, labels } = setup();
+ const renderedLabelElements = wrapper.querySelectorAll(
+ '.react-tags__selected-tag-name'
+ );
+ const renderedLabelNames = Array.from(renderedLabelElements).map(
+ label => label.innerHTML
+ );
+
+ expect(renderedLabelNames).toEqual(labels.map(label => label.name));
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_notes_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_notes_spec.js
index 690f564ed..21bf336cf 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_notes_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_notes_spec.js
@@ -1,153 +1,133 @@
-import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { fireEvent } from '@testing-library/react';
import ExpandedStoryNotes from 'components/story/ExpandedStory/ExpandedStoryNotes';
+import React from 'react';
import storyFactory from '../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- let onCreate;
- let onDelete;
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
- const newStory = (notes) => ({
+ const onCreate = vi.fn();
+ const onDelete = vi.fn();
+
+ const newStory = notes => ({
...storyFactory({ notes: notes || [] }),
_editing: {
...storyFactory({ notes: notes || [] }),
},
});
- beforeEach(() => {
- onCreate = sinon.stub();
- onDelete = sinon.stub();
- });
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {
+ ...storyFactory({ notes: [] }),
+ _editing: {
+ ...storyFactory({ notes: [] }),
+ },
+ },
+ disabled: false,
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
it('renders component title', () => {
- const story = newStory();
-
- const wrapper = mount(
-
- );
-
- expect(wrapper.find('.Story__section-title').text())
- .toContain(I18n.t('story.notes'));
+ const props = {
+ onCreate,
+ onDelete,
+ };
+
+ const { container } = renderComponent(props);
+ const title = container.querySelector('.Story__section-title');
+
+ expect(title).toHaveTextContent(I18n.t('story.notes'));
});
it('renders component content', () => {
- const story = newStory();
-
- const wrapper = mount(
-
- );
-
- expect(wrapper.find('.create-note-text')).toExist();
- expect(wrapper.find('.create-note-button')).toExist();
- expect(wrapper.find('.Story__section__notes')).toExist();
- expect(wrapper.find('NotesList')).toExist();
+ const props = {
+ onCreate,
+ onDelete,
+ story: {
+ ...storyFactory({ notes: [{ username: 'foo', id: 1 }] }),
+ _editing: {
+ ...storyFactory({ notes: [{ username: 'foo', id: 2 }] }),
+ },
+ },
+ };
+
+ const { container } = renderComponent(props);
+ const createNoteText = container.querySelector('.create-note-text');
+ const createNoteButton = container.querySelector('.create-note-button');
+ const storySectionNotes = container.querySelector('.Story__section__notes');
+ const notelist = container.querySelector('.markdown-wrapper__text-right');
+
+ expect(createNoteText).toBeInTheDocument();
+ expect(createNoteButton).toBeInTheDocument();
+ expect(storySectionNotes).toBeInTheDocument();
+ expect(notelist).toBeInTheDocument();
});
describe('when component is enabled', () => {
+ const onCreateSpy = vi.fn();
+ const props = {
+ onCreate: onCreateSpy,
+ onDelete,
+ disabled: false,
+ };
+ const change = 'newNote';
+
describe('when user create a new note', () => {
it('triggers the onCreate callback passing the note', () => {
- const story = newStory();
-
- const change = 'newNote';
-
- const onCreateSpy = sinon.spy();
-
- const wrapper = mount(
-
- );
-
- const textArea = wrapper.find('.create-note-text');
- const button = wrapper.find('.create-note-button input');
-
- textArea.simulate('change', { target: { value: change } });
- button.simulate('click');
-
+ const { container } = renderComponent(props);
+ const textArea = container.querySelector('.create-note-text');
+ const button = container.querySelector('.create-note-button input');
+
+ fireEvent.change(textArea, { target: { value: change } });
+ fireEvent.click(button);
+
expect(onCreateSpy).toHaveBeenCalledWith(change);
+ expect(onCreateSpy).toHaveBeenCalledTimes(1);
});
});
it('disables the add note button if text area is empty', () => {
- const story = newStory();
-
- const wrapper = shallow(
-
- );
-
- const textArea = wrapper.find('.create-note-text');
- const button = wrapper.find('.create-note-button input');
-
- textArea.simulate('change', { target: { value: '' } });
- expect(button.prop('disabled')).toBe(true);
+ const { container } = renderComponent(props);
+ const textArea = container.querySelector('.create-note-text');
+ const button = container.querySelector('.create-note-button input');
+ fireEvent.change(textArea, { target: { value: '' } });
+
+ expect(button).toBeDisabled();
});
});
describe('when component is disabled', () => {
+ const props = {
+ onCreate,
+ onDelete,
+ disabled: true,
+ story: newStory([{ id: 0, note: 'foo' }]),
+ };
+
it('does not render a create note button', () => {
- const notes = [{ id: 0, note: 'foo' }];
- const story = newStory(notes);
-
- const wrapper = shallow(
-
- );
-
- expect(wrapper.exists('.create-note-button')).toBe(false);
+ const { container } = renderComponent(props);
+ const createNoteButton = container.querySelector('.create-note-button');
+
+ expect(createNoteButton).toBeNull();
});
it('does not render a create note text area', () => {
- const notes = [{ id: 0, note: 'foo' }];
- const story = newStory(notes);
-
- const wrapper = shallow(
-
- );
-
- expect(wrapper.exists('.create-note-text')).toBe(false);
+ const { container } = renderComponent(props);
+
+ expect(container.querySelector('.create-note-text')).toBeNull();
});
describe('when there are no notes', () => {
it('renders nothing', () => {
- const story = newStory();
-
- const wrapper = shallow(
-
- );
-
- expect(wrapper.html()).toBeNull();
+ const { container } = renderComponent({ ...props, story: newStory() });
+
+ expect(container.innerHTML).toBe('');
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_owned_by_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_owned_by_spec.js
index d5cd3ec82..8cb995727 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_owned_by_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_owned_by_spec.js
@@ -1,28 +1,27 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryOwnedBy from 'components/story/ExpandedStory/ExpandedStoryOwnedBy';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const setup = propOverrides => {
- const defaultProps = () => ({
+ const renderComponent = props => {
+ const defaultProps = {
users: [
{ id: 1, name: 'foo' },
- { id: 2, name: 'bar' }
+ { id: 2, name: 'bar' },
],
story: { _editing: { ownedById: '' } },
- onEdit: sinon.spy(),
+ onEdit: vi.fn(),
disabled: false,
- ...propOverrides
- });
+ };
- const wrapper = shallow();
+ const mergedProps = { ...defaultProps, ...props };
- return { wrapper };
+ return renderWithProviders();
};
it('renders properly', () => {
- const { wrapper } = setup();
+ const { container } = renderComponent();
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_release/expanded_story_release_date_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_release/expanded_story_release_date_spec.js
index 29b126fa1..a864fc3fc 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_release/expanded_story_release_date_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_release/expanded_story_release_date_spec.js
@@ -1,23 +1,30 @@
-import React from 'react';
-import { mount } from 'enzyme';
+import { screen } from '@testing-library/react';
import ExpandedStoryReleaseDate from 'components/story/ExpandedStory/ExpandedStoryRelease/ExpandedStoryReleaseDate';
+import React from 'react';
import storyFactory from '../../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../../setupRedux';
describe('', () => {
- const defaultProps = () => ({
- story: {
- ...storyFactory(),
- _editing: storyFactory({ releaseDate: null })
- },
- disabled: false,
- onEdit: sinon.spy()
- });
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {
+ ...storyFactory(),
+ _editing: storyFactory({ releaseDate: null }),
+ },
+ disabled: false,
+ onEdit: vi.fn(),
+ };
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
it('renders component title', () => {
- const wrapper = mount(
-
- );
+ renderComponent();
- expect(wrapper.text()).toContain(I18n.t('activerecord.attributes.story.release_date'));
+ const releaseText = screen.getByText(
+ I18n.t('activerecord.attributes.story.release_date')
+ );
+ expect(releaseText).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_requested_by_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_requested_by_spec.js
index fbda9f240..e52c2b253 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_requested_by_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_requested_by_spec.js
@@ -1,27 +1,27 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryRequestedBy from 'components/story/ExpandedStory/ExpandedStoryRequestedBy';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const setup = propOverrides => {
- const defaultProps = () => ({
+ const renderComponent = props => {
+ const defaultProps = {
users: [
{ id: 1, name: 'foo' },
- { id: 2, name: 'bar' }
+ { id: 2, name: 'bar' },
],
story: { _editing: { requestedById: 1 } },
- onEdit: sinon.spy(),
+ onEdit: vi.fn(),
disabled: false,
- ...propOverrides
- });
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
- const wrapper = shallow();
- return { wrapper };
+ return renderWithProviders();
};
it('renders properly', () => {
- const { wrapper } = setup();
+ const { container } = renderComponent();
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_section_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_section_spec.js
deleted file mode 100644
index 408c3c07c..000000000
--- a/spec/javascripts/components/story/expanded_story/expanded_story_section_spec.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import { shallow } from 'enzyme';
-import ExpandedStorySection from 'components/story/ExpandedStory/ExpandedStorySection';
-
-describe('', () => {
- it('renders section-title with the right text', () => {
- const title = 'my title';
- const children = 'children';
-
- const wrapper = shallow();
-
- expect(wrapper.find('.Story__section-title').text()).toContain(title);
- });
-
- it('renders with the right identifier className', () => {
- const identifier = 'content';
- const children = 'children';
-
- const wrapper = shallow(
-
- );
-
- expect(wrapper.find(`.Story__section__${identifier}`)).toExist();
- });
-
- it('renders children', () => {
- const children = {'children'}
;
-
- const wrapper = shallow(
-
- {children}
-
- );
-
- expect(wrapper).toContainReact(children);
- });
-});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_section_spec.jsx b/spec/javascripts/components/story/expanded_story/expanded_story_section_spec.jsx
new file mode 100644
index 000000000..d4c6a9dee
--- /dev/null
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_section_spec.jsx
@@ -0,0 +1,50 @@
+import ExpandedStorySection from 'components/story/ExpandedStory/ExpandedStorySection';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
+
+describe('', () => {
+ const renderComponent = props => {
+ const defaultProps = {};
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
+
+ it('renders section-title with the right text', () => {
+ const props = {
+ title: 'my title',
+ children: 'children',
+ };
+
+ const { container } = renderComponent(props);
+ const title = container.querySelector('.Story__section-title');
+
+ expect(title).toHaveTextContent(props.title);
+ });
+
+ it('renders with the right identifier className', () => {
+ const props = {
+ title: 'title',
+ identifier: 'content',
+ children: 'children',
+ };
+
+ const { container } = renderComponent(props);
+ const section = container.querySelector('.Story__section__content');
+
+ expect(section).toHaveClass(`Story__section__${props.identifier}`);
+ });
+
+ it('renders children', () => {
+ const props = {
+ title: 'title',
+ children: {'children'}
,
+ };
+
+ const { container } = renderComponent(props);
+ const children = container.querySelector('.Story__section__content');
+
+ expect(children).toHaveTextContent('children');
+ });
+});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_spec.js
index 6d7544d97..f0572b53e 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_spec.js
@@ -1,133 +1,140 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { screen } from '@testing-library/react';
import { ExpandedStory } from 'components/story/ExpandedStory/index';
+import React from 'react';
import storyFactory from '../../../support/factories/storyFactory';
-import ExpandedStoryRelease from 'components/story/ExpandedStory/ExpandedStoryRelease';
-import ExpandedStoryDefault from 'components/story/ExpandedStory/ExpandedStoryDefault';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const defaultProps = () => ({
- story: storyFactory(),
- editStory: sinon.spy(),
- saveStory: sinon.spy(),
- deleteStory: sinon.spy(),
- project: { labels: [] },
- disabled: false,
- onToggle: sinon.spy(),
- cloneStory: sinon.spy(),
- showHistory: sinon.spy(),
- onClone: sinon.spy()
- });
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+ vi.mock('react-clipboard.js', () => ({
+ default: vi
+ .fn()
+ .mockImplementation(({ children }) => {children}
),
+ }));
+
+ const renderComponent = props => {
+ const defaultProps = {
+ story: storyFactory(),
+ editStory: vi.fn(),
+ saveStory: vi.fn(),
+ deleteStory: vi.fn(),
+ project: { labels: [], pointValues: [] },
+ disabled: false,
+ onToggle: vi.fn(),
+ cloneStory: vi.fn(),
+ showHistory: vi.fn(),
+ onLabelClick: vi.fn(),
+ onClone: vi.fn(),
+ };
+
+ const mergedProps = { ...defaultProps, ...props };
+
+ return renderWithProviders();
+ };
describe('when storyType is a release', () => {
it('renders ExpandedStoryRelease component', () => {
- const story = storyFactory({
- _editing: {
- ...storyFactory(),
- storyType: 'release'
- }
- });
-
- const wrapper = shallow(
- ,
- { disableLifecycleMethods: true }
+ const props = {
+ story: storyFactory({
+ _editing: {
+ ...storyFactory(),
+ storyType: 'release',
+ },
+ }),
+ };
+
+ renderComponent(props);
+ const releaseTitle = screen.getByText(
+ I18n.t('activerecord.attributes.story.release_date')
);
- expect(wrapper.find(ExpandedStoryRelease)).toExist();
- expect(wrapper.find(ExpandedStoryDefault)).not.toExist();
+ expect(releaseTitle).toBeInTheDocument();
});
});
describe("when storyType isn't a release", () => {
it('renders ExpandedStoryDefault component', () => {
- const story = storyFactory({
- _editing: {
- ...storyFactory(),
- storyType: 'feature'
- }
- });
-
- const wrapper = shallow(
- ,
- { disableLifecycleMethods: true }
+ const props = {
+ story: storyFactory({
+ _editing: {
+ ...storyFactory(),
+ storyType: 'feature',
+ title: 'this title appears everywhere',
+ },
+ }),
+ };
+
+ renderComponent(props);
+ const expandedStoryDefault = screen.getByDisplayValue(
+ 'this title appears everywhere'
+ );
+ const releaseTitle = screen.queryByText(
+ I18n.t('activerecord.attributes.story.release_date')
);
- expect(wrapper.find(ExpandedStoryDefault)).toExist();
- expect(wrapper.find(ExpandedStoryRelease)).not.toExist();
+ expect(expandedStoryDefault).toBeInTheDocument();
+ expect(releaseTitle).toBeNull();
});
});
describe('when story is editable', () => {
- const story = storyFactory({
- _editing: {
- ...storyFactory(),
- storyType: 'feature',
- state: 'unstarted'
- }
- });
-
+ const props = {
+ story: storyFactory({
+ _editing: {
+ ...storyFactory(),
+ storyType: 'feature',
+ state: 'unstarted',
+ title: 'this title appears everywhere',
+ },
+ }),
+ };
+
it('passes disabled prop as false', () => {
- const wrapper = shallow(
- ,
- { disableLifecycleMethods: true }
+ renderComponent(props);
+ const expandedStoryDefault = screen.getByDisplayValue(
+ 'this title appears everywhere'
);
- const expandedStoryDefault = wrapper.find(ExpandedStoryDefault);
- expect(expandedStoryDefault.prop('disabled')).toBe(false);
+ expect(expandedStoryDefault).not.toHaveAttribute('readonly');
});
});
describe('when story is not editable', () => {
- const story = storyFactory({
- _editing: {
- ...storyFactory(),
+ const props = {
+ story: storyFactory({
+ _editing: {
+ ...storyFactory(),
+ storyType: 'feature',
+ state: 'accepted',
+ title: 'this title appears everywhere',
+ },
storyType: 'feature',
- state: 'accepted'
- },
- storyType: 'feature',
- state: 'accepted'
- });
-
+ state: 'accepted',
+ }),
+ };
+
it('passes disabled prop as true', () => {
- const wrapper = shallow(
- ,
- { disableLifecycleMethods: true }
+ renderComponent(props);
+ const expandedStoryDefault = screen.getByDisplayValue(
+ 'this title appears everywhere'
);
- const expandedStoryDefault = wrapper.find(ExpandedStoryDefault);
- expect(expandedStoryDefault.prop('disabled')).toBe(true);
+ expect(expandedStoryDefault).toHaveAttribute('readonly');
});
});
it('adds enable-loading className when updating a story', () => {
- const story = storyFactory({
- _editing: {
- ...storyFactory({ loading: true }),
- }
- });
+ const props = {
+ story: storyFactory({
+ _editing: {
+ ...storyFactory({ loading: true }),
+ },
+ }),
+ };
- const wrapper = shallow(
- ,
- { disableLifecycleMethods: true }
- );
+ const { container } = renderComponent(props);
+ const storyLoading = container.querySelector('.Story__enable-loading');
- expect(wrapper.find('.Story__enable-loading')).toExist();
+ expect(storyLoading).toBeInTheDocument();
});
-
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_state_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_state_spec.js
index 10b87fba7..8fcafecd8 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_state_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_state_spec.js
@@ -1,120 +1,117 @@
-import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { fireEvent, screen } from '@testing-library/dom';
import ExpandedStoryState from 'components/story/ExpandedStory/ExpandedStoryState';
-import { states, types } from '../../../../../app/assets/javascripts/models/beta/story';
-import { storyTypes } from '../../../../../app/assets/javascripts/libs/beta/constants'
+import React from 'react';
+import { storyTypes } from '../../../../../app/assets/javascripts/libs/beta/constants';
+import {
+ states,
+ types,
+} from '../../../../../app/assets/javascripts/models/beta/story';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- it('renders component title', () => {
- const onEditSpy = sinon.spy();
+ const renderComponent = props => {
+ const defaultProps = {
+ story: {
+ _editing: { state: 'started' },
+ },
+ onEdit: vi.fn(),
+ disabled: false,
+ };
- const story = { state: 'started', _editing: { state: 'started' } };
+ const mergedProps = { ...defaultProps, ...props };
- const wrapper = mount(
-
+ return renderWithProviders();
+ };
+
+ it('renders component title', () => {
+ renderComponent();
+ const title = screen.getByText(
+ I18n.t('activerecord.attributes.story.state')
);
- expect(wrapper.text()).toContain(I18n.t('activerecord.attributes.story.state'));
+ expect(title).toBeInTheDocument();
});
- describe("states at select", () => {
- let onEditSpy;
-
- beforeEach(() => {
- onEditSpy = sinon.spy();
- })
-
+ describe('states at select', () => {
const noFeatureTypes = types.filter(type => type !== storyTypes.FEATURE);
noFeatureTypes.forEach(noFeatureType => {
describe(`when is no ${noFeatureType}`, () => {
states.forEach(state => {
describe(`and state is ${state}`, () => {
- const story = {
- _editing: {
+ const props = {
+ story: {
+ _editing: {
+ state,
+ estimate: 1,
+ storyType: noFeatureType,
+ },
state,
estimate: 1,
storyType: noFeatureType,
- }
+ },
+ disabled: false,
};
-
+
let wrapper;
-
+
beforeEach(() => {
- wrapper = shallow(
-
- );
+ const { container } = renderComponent(props);
+ wrapper = container;
});
-
+
it('renders all states', () => {
- expect(wrapper.find('option').length).toEqual(7);
+ expect(wrapper.querySelectorAll('option').length).toEqual(7);
});
-
+
it(`has to be ${state}`, () => {
- expect(wrapper.find('select').prop('value')).toBe(state);
+ expect(wrapper.querySelector('select').value).toBe(state);
});
});
});
- })
- })
+ });
+ });
describe('when is unestimated feature', () => {
- let onEditSpy;
-
- beforeEach(() => {
- onEditSpy = sinon.spy();
- })
-
- const story = {
- _editing: { state: states[0], estimate: null, storyType: storyTypes.FEATURE }
- };
let wrapper;
+ const props = {
+ story: {
+ _editing: {
+ state: states[0],
+ estimate: null,
+ storyType: storyTypes.FEATURE,
+ },
+ },
+ };
beforeEach(() => {
- wrapper = shallow(
-
- );
- })
-
+ const { container } = renderComponent(props);
+ wrapper = container;
+ });
+
it('renders just one state', () => {
- expect(wrapper.find('option').length).toEqual(1);
+ expect(wrapper.querySelectorAll('option').length).toEqual(1);
});
it('has to be unscheduled', () => {
- expect(wrapper.find('select').prop('value')).toBe(states[0]);
+ expect(wrapper.querySelector('select').value).toBe(states[0]);
});
});
states.forEach(state => {
it(`sets select value as ${state}`, () => {
- const onEditSpy = sinon.spy();
+ const onEditSpy = vi.fn();
- const story = {
- _editing: { state }
+ const props = {
+ story: {
+ _editing: { state },
+ },
};
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- expect(select.prop('value')).toBe(state);
+ expect(select.value).toBe(state);
});
});
});
@@ -123,93 +120,82 @@ describe('', () => {
it('triggers the edit callback passing the story state', () => {
const state = states[0];
const change = states[1];
-
- const story = {
- _editing: { state }
+ const onEditSpy = vi.fn();
+ const props = {
+ story: {
+ _editing: { state },
+ },
+ onEdit: onEditSpy,
};
- const onEdit = sinon.spy();
-
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
+ fireEvent.change(select, { target: { value: change } });
- select.simulate('change', { target: { value: change } });
-
- expect(onEdit).toHaveBeenCalledWith(change);
+ expect(onEditSpy).toHaveBeenCalledWith(change);
});
});
describe('when component is disabled', () => {
- it('select field is editable', () => {
- const onEditSpy = sinon.spy();
- const story = { state: 'started', _editing: { state: 'started' } };
- const wrapper = mount(
-
- );
- const select = wrapper.find('select');
- expect(select.prop('disabled')).toBe(true);
+ it('select field is disabled', () => {
+ const props = {
+ story: { state: 'started', _editing: { state: 'started' } },
+ disabled: true,
+ };
+
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
+
+ expect(select).toBeDisabled();
});
});
describe('when component is enabled', () => {
- it('select field is enabled', () => {
- const onEditSpy = sinon.spy();
- const story = { state: 'started', _editing: { state: 'started' } };
- const wrapper = mount(
-
- );
- const select = wrapper.find('select');
- expect(select.prop('disabled')).toBe(false);
+ it('select field is editable', () => {
+ const props = {
+ story: { state: 'started', _editing: { state: 'started' } },
+ disabled: false,
+ };
+
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
+
+ expect(select).not.toBeDisabled();
});
});
- describe("When change estimate", () => {
- describe("to no estimate", () => {
- it("disables state select", () => {
- const story = { _editing: { estimate: '', storyType: 'feature', state: 'unscheduled' } };
- const onEditSpy = sinon.spy();
- const wrapper = shallow(
-
- );
-
- const select = wrapper.find('select');
-
- expect(select.prop('disabled')).toBe(true);
+ describe('When change estimate', () => {
+ describe('to no estimate', () => {
+ it('disables state select', () => {
+ const props = {
+ story: {
+ _editing: {
+ estimate: '',
+ storyType: 'feature',
+ state: 'unscheduled',
+ },
+ },
+ };
+
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
+
+ expect(select).toBeDisabled();
});
});
- describe("to a number", () => {
+ describe('to a number', () => {
it("doesn't disable state select when estimate is a number", () => {
- const story = { _editing: { estimate: 1, storyType: 'feature', state: 'unstarted' } };
- const onEditSpy = sinon.stub();
- const wrapper = shallow(
-
- );
- const select = wrapper.find('select');
-
- expect(select.prop('disabled')).toBe(false);
+ const props = {
+ story: {
+ _editing: { estimate: 1, storyType: 'feature', state: 'unstarted' },
+ },
+ };
+
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
+
+ expect(select).not.toBeDisabled();
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_task_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_task_spec.js
index 5d39c8ab6..c18639ced 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_task_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_task_spec.js
@@ -1,61 +1,67 @@
-import React from 'react';
-import { mount } from 'enzyme';
+import { fireEvent, screen } from '@testing-library/react';
import ExpandedStoryTask from 'components/story/ExpandedStory/ExpandedStoryTask';
+import React from 'react';
import storyFactory from '../../../support/factories/storyFactory';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const setup = (propOverrides, tasks) => {
- const defaultProps = () => ({
+ const renderComponent = props => {
+ const defaultProps = {
story: {
...storyFactory({
- tasks: tasks || [],
- _editing: storyFactory({ tasks: tasks || [] })
- })
+ tasks: [],
+ _editing: storyFactory({ tasks: [] }),
+ }),
},
- onDelete: sinon.spy(),
- onToggle: sinon.spy(),
- onSave: sinon.spy(),
+ onDelete: vi.fn(),
+ onToggle: vi.fn(),
+ onSave: vi.fn(),
disabled: false,
- ...propOverrides
- });
+ };
- const wrapper = mount();
- const button = wrapper.find('button');
- const input = wrapper.find('input');
+ const mergedProps = { ...defaultProps, ...props };
- return { wrapper, button, input };
+ return renderWithProviders();
};
it('renders component title', () => {
- const { wrapper } = setup();
+ renderComponent();
+ const title = screen.getByText(I18n.t('story.tasks'));
- expect(wrapper.text()).toContain(I18n.t('story.tasks'));
+ expect(title).toBeInTheDocument();
});
describe('when component is enabled', () => {
it('displays a task form', () => {
- const { wrapper } = setup();
+ const { container } = renderComponent();
+ const taskForm = container.querySelector('.task-form');
- expect(wrapper.exists('.task-form')).toBe(true);
+ expect(taskForm).toBeInTheDocument();
});
it('disables the add task button if text area is empty', () => {
- const { input, button } = setup();
-
- input.simulate('change', { target: { value: '' } });
- expect(button.prop('disabled')).toBe(true);
+ const { container } = renderComponent();
+ const input = container.querySelector('input');
+ const button = container.querySelector('button');
+ fireEvent.change(input, { target: { value: '' } });
+
+ expect(button).toBeDisabled();
});
-
+
describe('onHandleSubmit', () => {
it('calls onSave with a task', () => {
const task = 'New Task';
- const onSaveSpy = sinon.spy();
+ const onSaveSpy = vi.fn();
+ const props = { onSave: onSaveSpy };
const event = { target: { value: task } };
- const { input, button } = setup({ onSave: onSaveSpy });
-
- input.simulate('change', event);
- button.simulate('click');
-
+
+ const { container } = renderComponent(props);
+ const input = container.querySelector('input');
+ const button = container.querySelector('button');
+ fireEvent.change(input, event);
+ fireEvent.click(button);
+
+ expect(onSaveSpy).toHaveBeenCalledTimes(1);
expect(onSaveSpy).toHaveBeenCalledWith(task);
});
});
@@ -67,21 +73,34 @@ describe('', () => {
storyId: 0,
name: 'task',
done: false,
- createdAt: "2019/04/01",
- updatedAt: "2019/04/02"
+ createdAt: '2019/04/01',
+ updatedAt: '2019/04/02',
};
it('does not display task form', () => {
- const { wrapper } = setup({ disabled: true }, [task]);
+ const props = {
+ story: {
+ ...storyFactory({ tasks: [task] }),
+ _editing: storyFactory({ tasks: [task] }),
+ },
+ disabled: true,
+ };
+
+ const { container } = renderComponent(props);
+ const taskForm = container.querySelector('.task-form');
- expect(wrapper.exists('.task-form')).toBe(false);
+ expect(taskForm).toBeNull();
});
describe('when there are no tasks', () => {
it('renders nothing', () => {
- const { wrapper } = setup({ disabled: true });
-
- expect(wrapper.html()).toBeNull();
+ const props = {
+ disabled: true,
+ };
+
+ const { container } = renderComponent(props);
+
+ expect(container.innerHTML).toBe('');
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_title_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_title_spec.js
index f0218689e..8848b13fb 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_title_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_title_spec.js
@@ -1,60 +1,75 @@
-import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent } from '@testing-library/react';
import ExpandedStoryTitle from 'components/story/ExpandedStory/ExpandedStoryTitle';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const setup = propOverrides => {
- const defaultProps = () => ({
+ const renderComponent = props => {
+ const defaultProps = {
story: { _editing: { title: 'foo' } },
- onEdit: sinon.spy(),
+ onEdit: vi.fn(),
disabled: false,
- ...propOverrides
- });
+ };
+ const mergedProps = { ...defaultProps, ...props };
- const wrapper = shallow();
- const input = wrapper.find('input');
-
- return { wrapper, input };
+ return renderWithProviders();
};
it('renders properly', () => {
- const { wrapper } = setup();
+ const { container } = renderComponent();
- expect(wrapper).toExist();
+ expect(container).toBeInTheDocument();
});
describe('input element', () => {
it('has value equals to story title', () => {
- const story = { _editing: { title: 'bar' } }
+ const props = {
+ story: { _editing: { title: 'bar' } },
+ };
- const { input } = setup({ story });
+ const { container } = renderComponent(props);
+ const input = container.querySelector('input');
- expect(input.prop('value')).toBe(story._editing.title);
+ expect(input.value).toBe(props.story._editing.title);
});
it('calls onEdit with the right params', () => {
- const mockOnEdit = sinon.spy();
+ const mockOnEdit = vi.fn();
const eventValue = 'foobar';
- const { input } = setup({ onEdit: mockOnEdit });
+ const props = {
+ onEdit: mockOnEdit,
+ };
- input.simulate('change', { target: { value: eventValue } })
+ const { container } = renderComponent(props);
+ const input = container.querySelector('input');
+ fireEvent.change(input, { target: { value: eventValue } });
expect(mockOnEdit).toHaveBeenCalledWith(eventValue);
});
describe('when the component is enabled', () => {
it('should not be read-only', () => {
- const { input } = setup({disabled: false});
+ const props = {
+ disabled: false,
+ };
+
+ const { container } = renderComponent(props);
+ const input = container.querySelector('input');
- expect(input.prop('readOnly')).toBe(false);
+ expect(input.readOnly).toBe(false);
});
});
describe('when component is disabled', () => {
it('should be read-only', () => {
- const { input } = setup({disabled: true});
+ const props = {
+ disabled: true,
+ };
+
+ const { container } = renderComponent(props);
+ const input = container.querySelector('input');
- expect(input.prop('readOnly')).toBe(true);
+ expect(input.readOnly).toBe(true);
});
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_tooltip_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_tooltip_spec.js
index 19b3504d6..8563611f2 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_tooltip_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_tooltip_spec.js
@@ -1,10 +1,13 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryTooltip from 'components/story/ExpandedStory/ExpandedStoryToolTip';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
it('renders ', () => {
- const wrapper = shallow();
- expect(wrapper.find('Popover').exists()).toBe(true);
+ const { container } = renderWithProviders();
+
+ const tooltip = container.querySelector('.infoToolTip');
+
+ expect(tooltip).toBeInTheDocument();
});
});
diff --git a/spec/javascripts/components/story/expanded_story/expanded_story_type_spec.js b/spec/javascripts/components/story/expanded_story/expanded_story_type_spec.js
index ea5b1dfa5..2faede9e8 100644
--- a/spec/javascripts/components/story/expanded_story/expanded_story_type_spec.js
+++ b/spec/javascripts/components/story/expanded_story/expanded_story_type_spec.js
@@ -1,44 +1,50 @@
-import React from 'react';
-import { shallow } from 'enzyme';
import ExpandedStoryType from 'components/story/ExpandedStory/ExpandedStoryType';
import { types } from 'models/beta/story';
+import React from 'react';
+import { renderWithProviders } from '../../setupRedux';
describe('', () => {
- const setup = propOverrides => {
+ const renderComponent = props => {
const defaultProps = {
- onEdit: sinon.spy(),
+ onEdit: vi.fn(),
story: { _editing: { storyType: 'feature' } },
disabled: false,
- ...propOverrides
};
- const wrapper = shallow();
- const select = wrapper.find('select');
- return { wrapper, select };
- }
+ const mergedProps = { ...defaultProps, ...props };
- types.forEach((type) => {
+ return renderWithProviders();
+ };
+
+ types.forEach(type => {
it(`sets defaultValue as ${type} in select`, () => {
- const story = { _editing: { storyType: type } };
- const { select } = setup({ story });
+ const props = {
+ story: { _editing: { storyType: type } },
+ };
+
+ const { container } = renderComponent(props);
+ const select = container.querySelector('select');
- expect(select.prop('value')).toBe(type);
+ expect(select.value).toBe(type);
});
});
describe('when component is not disabled', () => {
it('select field is editable', () => {
- const { select } = setup();
+ const { container } = renderComponent();
+ const select = container.querySelector('select');
- expect(select.prop('disabled')).toBe(false);
+ expect(select).toBeInTheDocument();
+ expect(select).not.toBeDisabled();
});
});
describe('when component is disabled', () => {
it('select field is disabled', () => {
- const { select } = setup({disabled: true});
+ const { container } = renderComponent({ disabled: true });
+ const select = container.querySelector('select');
- expect(select.prop('disabled')).toBe(true);
+ expect(select).toBeDisabled();
});
});
});
diff --git a/spec/javascripts/components/story/note/note_spec.js b/spec/javascripts/components/story/note/note_spec.js
index 3e765374f..bbb53dd3f 100644
--- a/spec/javascripts/components/story/note/note_spec.js
+++ b/spec/javascripts/components/story/note/note_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import Note from 'components/story/note/Note';
describe('', () => {
@@ -7,13 +7,13 @@ describe('', () => {
id: 42,
note: 'test Note',
userName: 'foo',
- createdAt: '27/08/2018'
+ createdAt: '27/08/2018',
};
const setup = propOverrides => {
- const onDeleteSpy = sinon.spy();
+ const onDeleteSpy = vi.fn();
- const wrapper = shallow(
+ const { container: wrapper } = render(
', () => {
/>
);
- const deleteButton = wrapper.find('.delete-note-button');
+ const deleteButton = wrapper.querySelector('.delete-note-button');
return { wrapper, deleteButton, onDeleteSpy };
};
+ beforeAll(() => {
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+ });
+
describe('when component is enabled', () => {
it('allows editing', () => {
const { deleteButton } = setup();
- expect(deleteButton.exists()).toBe(true);
+ expect(deleteButton).toBeInTheDocument();
});
describe('when user deletes a note', () => {
it('triggers onDelete callback', () => {
const { deleteButton, onDeleteSpy } = setup();
- deleteButton.simulate('click');
+ fireEvent.click(deleteButton);
expect(onDeleteSpy).toHaveBeenCalled();
});
@@ -49,7 +53,7 @@ describe('', () => {
it('does not allow deleting', () => {
const { deleteButton } = setup({ disabled: true });
- expect(deleteButton.exists()).toBe(false);
+ expect(deleteButton).not.toBeInTheDocument();
});
});
});
diff --git a/spec/javascripts/components/story/note/notes_list_spec.js b/spec/javascripts/components/story/note/notes_list_spec.js
index 00bbc2e8c..2873dae11 100644
--- a/spec/javascripts/components/story/note/notes_list_spec.js
+++ b/spec/javascripts/components/story/note/notes_list_spec.js
@@ -1,21 +1,17 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import NotesList from 'components/story/note/NotesList';
describe('', () => {
const notesArray = [{ id: 1 }, { id: 2 }, { id: 3 }];
it('render all notes in a component', () => {
- const onDelete = sinon.stub();
+ const onDelete = vi.fn();
- const wrapper = shallow(
-
+ const { getAllByTestId } = render(
+
);
- expect(wrapper.find('Note').length).toBe(notesArray.length)
+ expect(getAllByTestId('note-component').length).toBe(notesArray.length);
});
});
diff --git a/spec/javascripts/components/story/select_user/select_user_spec.js b/spec/javascripts/components/story/select_user/select_user_spec.js
index cec3b1d8b..92ac1cf26 100644
--- a/spec/javascripts/components/story/select_user/select_user_spec.js
+++ b/spec/javascripts/components/story/select_user/select_user_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import SelectUser from 'components/story/select_user/SelectUser';
describe('', () => {
@@ -7,16 +7,16 @@ describe('', () => {
const defaultProps = () => ({
users: [
{ id: 1, name: 'foo' },
- { id: 2, name: 'bar' }
+ { id: 2, name: 'bar' },
],
selectedUserId: 1,
- onEdit: sinon.spy(),
+ onEdit: vi.fn(),
disabled: false,
- ...propOverrides
+ ...propOverrides,
});
- const wrapper = shallow();
- const select = wrapper.find('select');
+ const { container: wrapper } = render();
+ const select = wrapper.querySelector('select');
return { wrapper, select };
};
@@ -24,17 +24,17 @@ describe('', () => {
it('renders properly', () => {
const { wrapper } = setup();
- expect(wrapper).toExist();
+ expect(wrapper).toBeInTheDocument();
});
it('calls onEdit with the right params', () => {
- const mockOnEdit = sinon.spy();
+ const mockOnEdit = vi.fn();
const value = 1;
const { select } = setup({ onEdit: mockOnEdit });
- select.simulate('change', { target: { value } });
+ fireEvent.change(select, { target: { value } });
- expect(mockOnEdit).toHaveBeenCalledWith(value);
+ expect(mockOnEdit).toHaveBeenCalledWith(value.toString());
});
describe('Select value', () => {
@@ -42,18 +42,18 @@ describe('', () => {
const selectedUserId = 1;
const { select } = setup({ selectedUserId });
- select.simulate('change', { target: { value: selectedUserId } });
+ fireEvent.change(select, { target: { value: selectedUserId } });
- expect(select.props().value).toEqual(selectedUserId);
+ expect(select.value).toEqual(selectedUserId.toString());
});
it(`sets the select value as '' when selectedUserId is not present`, () => {
const selectedUserId = null;
const { select } = setup({ selectedUserId });
- select.simulate('change', { target: { value: selectedUserId } });
+ fireEvent.change(select, { target: { value: selectedUserId } });
- expect(select.props().value).toEqual('');
+ expect(select.value).toEqual('');
});
});
@@ -61,15 +61,15 @@ describe('', () => {
it('select field is editable', () => {
const { select } = setup();
- expect(select.prop('disabled')).toBe(false);
+ expect(select.disabled).toBe(false);
});
});
describe('when component is disabled', () => {
it('select field is disabled', () => {
- const { select } = setup({disabled: true});
+ const { select } = setup({ disabled: true });
- expect(select.prop('disabled')).toBe(true);
+ expect(select.disabled).toBe(true);
});
});
});
diff --git a/spec/javascripts/components/story/story_copy_id_clipboard_spec.js b/spec/javascripts/components/story/story_copy_id_clipboard_spec.js
deleted file mode 100644
index 27bde9a9e..000000000
--- a/spec/javascripts/components/story/story_copy_id_clipboard_spec.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import { mount, shallow } from 'enzyme';
-
-import StoryCopyIdClipboard from 'components/story/StoryCopyIdClipboard';
-
-describe('', function() {
- beforeEach(function() {
- sinon.stub(I18n, 't');
- });
-
- afterEach(function() {
- I18n.t.restore();
- });
-
- it("should render story id text", function() {
- const wrapper = mount(
-
- );
- expect(wrapper.find('.story-id').at(0).text()).toBe('#70');
- });
-
- it("should render story id data-clipboard-text", function() {
- const wrapper = mount(
-
- );
- expect(wrapper.find('[data-clipboard-text]')).toExist();
- });
-
- it("should render copy id title", function() {
- shallow(
-
- );
- expect(I18n.t).toHaveBeenCalledWith('story.events.copy_id');
- });
-
-});
diff --git a/spec/javascripts/components/story/story_copy_id_clipboard_spec.jsx b/spec/javascripts/components/story/story_copy_id_clipboard_spec.jsx
new file mode 100644
index 000000000..a4b43c790
--- /dev/null
+++ b/spec/javascripts/components/story/story_copy_id_clipboard_spec.jsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import StoryCopyIdClipboard from 'components/story/StoryCopyIdClipboard';
+import { render } from '@testing-library/react';
+
+vi.mock('react-clipboard.js', () => ({
+ default: ({ children, ...props }) => ,
+}));
+
+describe('', function () {
+ let fn;
+
+ beforeEach(function () {
+ fn = vi.spyOn(I18n, 't');
+ });
+
+ afterEach(function () {
+ fn.mockRestore();
+ });
+
+ it('should render story id text', function () {
+ const component = render();
+ expect(component.getByText('#70')).toBeInTheDocument();
+ });
+
+ it('should render story id data-clipboard-text', function () {
+ const component = render();
+
+ expect(
+ component.container.querySelector('data-clipboard-textt')
+ ).toBeDefined();
+ });
+
+ it('should render copy id title', function () {
+ render();
+ expect(fn).toHaveBeenCalledWith('story.events.copy_id');
+ });
+});
diff --git a/spec/javascripts/components/story/story_description_icon_spec.js b/spec/javascripts/components/story/story_description_icon_spec.js
index 9d19d7eae..9d841a7b5 100644
--- a/spec/javascripts/components/story/story_description_icon_spec.js
+++ b/spec/javascripts/components/story/story_description_icon_spec.js
@@ -1,21 +1,22 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import StoryDescriptionIcon from 'components/story/StoryDescriptionIcon';
import storyFactory from '../../support/factories/storyFactory';
describe('', () => {
- describe('When description is null',() => {
+ describe('When description is null', () => {
it('renders nothing', () => {
- const props = storyFactory({ description: null })
- const wrapper = shallow();
- expect(wrapper.find(StoryDescriptionIcon)).not.toExist();
+ const props = storyFactory({ description: null });
+ const { container } = render();
+ expect(container.querySelector('.Story__description-icon')).toBeNull();
});
});
- describe('When description exists',() => {
+
+ describe('When description exists', () => {
it('renders the description icon', () => {
const props = storyFactory();
- const wrapper = shallow();
- expect(wrapper).toHaveClassName('Story__description-icon');
+ const { container } = render();
+ expect(container.firstChild).toHaveClass('Story__description-icon');
});
});
});
diff --git a/spec/javascripts/components/story/story_description_spec.js b/spec/javascripts/components/story/story_description_spec.js
index 9bc43ef5e..be66a1d3f 100644
--- a/spec/javascripts/components/story/story_description_spec.js
+++ b/spec/javascripts/components/story/story_description_spec.js
@@ -1,78 +1,92 @@
import React from 'react';
-import { mount } from 'enzyme';
+import { render } from '@testing-library/react';
import StoryDescription from 'components/story/StoryDescription';
-import StoryLink from 'components/stories/StoryLink';
-describe('', function() {
+describe('', function () {
let story;
- beforeEach(function() {
- sinon.stub(window.md, 'makeHtml');
- story = {id: 5, description: 'Description'};
+ beforeEach(function () {
+ vi.spyOn(window.md, 'makeHtml');
+ story = { id: 5, description: 'Description' };
});
- afterEach(function() {
- window.md.makeHtml.restore();
+ afterEach(function () {
+ window.md.makeHtml.mockRestore();
});
- it("should ignore when there are no valid ids", function() {
- window.md.makeHtml.returns("Description
");
- const wrapper = mount(
+ it('should ignore when there are no valid ids', function () {
+ window.md.makeHtml.mockReturnValueOnce('Description
');
+ const { container } = render(
);
- expect(window.md.makeHtml).toHaveBeenCalledWith("Description");
- expect(wrapper.find('.description').text()).toContain('Description');
+
+ expect(window.md.makeHtml).toHaveBeenCalledWith('Description');
+ expect(container.querySelector('.description').innerHTML).toContain(
+ 'Description'
+ );
});
- it("should turn a valid id into a StoryLink", function() {
+ it('should turn a valid id into a StoryLink', function () {
const linkedStory = {
id: 9,
- get: sinon.stub().returns('unscheduled'),
- created_at: sinon.stub(),
- humanAttributeName: sinon.stub(),
- escape: sinon.stub(),
- hasNotes: sinon.stub()
+ get: vi.fn().mockImplementation(attr => {
+ if (attr === 'id') return 9;
+ else return 'unscheduled';
+ }),
+ created_at: vi.fn(),
+ humanAttributeName: vi.fn(),
+ escape: vi.fn(),
+ hasNotes: vi.fn(),
};
- window.md.makeHtml.returns("Description
");
- const wrapper = mount(
+
+ window.md.makeHtml.mockReturnValueOnce(
+ "Description
"
+ );
+
+ const { container } = render(
'}
isNew={false}
editingDescription={false}
- value={""}
+ value={''}
/>
);
- expect(window.md.makeHtml).toHaveBeenCalledWith('Description ');
- expect(wrapper.find(StoryLink).prop('story')).toBe(linkedStory);
+
+ expect(window.md.makeHtml).toHaveBeenCalledWith(
+ 'Description '
+ );
+ expect(
+ container.querySelector(`#story-link-${linkedStory.id}`)
+ ).toBeInTheDocument();
});
- it("should render markdown transformed as html", function () {
- window.md.makeHtml.returns("Header test
");
- const wrapper = mount(
+ it('should render markdown transformed as html', function () {
+ window.md.makeHtml.mockReturnValueOnce('Header test
');
+ const { container } = render(
);
expect(window.md.makeHtml).toHaveBeenCalledWith('# Header test');
- expect(wrapper.find('h1')).toExist();
- expect(wrapper.find('h1').text()).toContain('Header test');
- })
+ expect(container.querySelector('h1')).toBeInTheDocument();
+ expect(container.querySelector('h1').innerHTML).toContain('Header test');
+ });
});
diff --git a/spec/javascripts/components/story/story_icon_spec.js b/spec/javascripts/components/story/story_icon_spec.js
index 360a057ad..dffc28420 100644
--- a/spec/javascripts/components/story/story_icon_spec.js
+++ b/spec/javascripts/components/story/story_icon_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import StoryIcon from 'components/story/StoryIcon';
describe('', () => {
@@ -7,15 +7,19 @@ describe('', () => {
{ storyType: 'feature', icon: 'start', className: 'star' },
{ storyType: 'bug', icon: 'bug_report', className: 'bug' },
{ storyType: 'chore', icon: 'settings', className: 'dark' },
- { storyType: 'release', icon: 'bookmark', className: 'bookmark' }
+ { storyType: 'release', icon: 'bookmark', className: 'bookmark' },
];
iconRules.forEach(({ storyType, icon, className }) => {
- describe(`when storyType = ${storyType}`,() => {
+ describe(`when storyType = ${storyType}`, () => {
it('renders the story icon', () => {
- const wrapper = shallow();
+ const { container } = render();
- expect(wrapper.find('i')).toHaveClassName(`mi md-${className} md-16`);
- expect(wrapper.find('.Story__icon').text()).toContain(icon);
+ expect(container.querySelector('i')).toHaveClass(
+ `mi md-${className} md-16`
+ );
+ expect(container.querySelector('.Story__icon').innerHTML).toContain(
+ icon
+ );
});
});
});
diff --git a/spec/javascripts/components/story/story_item_spec.js b/spec/javascripts/components/story/story_item_spec.js
index 7501135b3..2eed70703 100644
--- a/spec/javascripts/components/story/story_item_spec.js
+++ b/spec/javascripts/components/story/story_item_spec.js
@@ -1,24 +1,64 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { renderWithProviders } from '../setupRedux';
import { StoryItem } from 'components/story/StoryItem';
import storyFactory from '../../support/factories/storyFactory';
-import ExpandedStory from 'components/story/ExpandedStory';
-import CollapsedStory from 'components/story/CollapsedStory';
import moment from 'moment';
+import { DragDropContext, Droppable } from 'react-beautiful-dnd';
+
+vi.mock('react-clipboard.js', () => ({
+ default: ({ children, ...props }) => ,
+}));
describe('', () => {
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('Test
');
+
+ const renderComponent = props => {
+ const { container: wrapper } = renderWithProviders(
+
+
+ {provided => (
+
+
+
+ )}
+
+ ,
+ {
+ preloadedState: {
+ project: {
+ pointValues: [],
+ labels: [],
+ },
+ },
+ }
+ );
+ const expandedStory = wrapper.querySelector('.Story--expanded');
+
+ return { wrapper, expandedStory };
+ };
+
it('renders the StoryItem component within a Collapsed Story', () => {
- const story = storyFactory({ collapsed: true });
- const wrapper = shallow();
+ const story = storyFactory({
+ collapsed: true,
+ _editing: {
+ loading: false,
+ },
+ });
+ const { wrapper } = renderComponent({ story, index: 1 });
- expect(wrapper.find(CollapsedStory)).toExist();
+ expect(wrapper.querySelector('.Story__icons-block')).toBeInTheDocument();
});
it('renders the StoryItem component within a Expanded Story', () => {
- const story = storyFactory({ collapsed: false });
- const wrapper = shallow();
+ const story = storyFactory({
+ collapsed: false,
+ _editing: {
+ loading: false,
+ },
+ });
+ const { wrapper } = renderComponent({ story });
- expect(wrapper.find(ExpandedStory)).toExist();
+ expect(wrapper.querySelector('.Story--expanded')).toBeInTheDocument();
});
describe('when the story is a release that is late', () => {
@@ -26,88 +66,106 @@ describe('', () => {
const story = storyFactory({
collapsed: false,
storyType: 'release',
- releaseDate: moment().subtract(3, 'days')
+ releaseDate: moment().subtract(3, 'days'),
+ _editing: {
+ loading: false,
+ },
});
const className = 'Story--late-release';
- const wrapper = shallow();
- const children = wrapper.find(ExpandedStory);
+ const { wrapper } = renderComponent({ story });
+
+ const children = wrapper.querySelector('.Story--expanded');
- expect(children.prop('className')).toContain(className);
+ expect(children).toHaveClass(className);
});
it('put a late release message on childrens prop title', () => {
const story = storyFactory({
collapsed: false,
storyType: 'release',
- releaseDate: moment().subtract(3, 'days')
+ releaseDate: moment().subtract(3, 'days'),
+ _editing: {
+ loading: false,
+ },
});
const title = I18n.t('story.warnings.backlogged_release');
- const wrapper = shallow();
- const children = wrapper.find(ExpandedStory);
+ const { wrapper } = renderComponent({ story });
- expect(children).toHaveProp('title', title);
+ const children = wrapper.querySelector('.Story--expanded');
+
+ expect(children.title).toBe(title);
});
});
describe("when the story is a release that isn't late", () => {
it('do not put a className on children components', () => {
+ const DEFAULT_CLASSES_QTY = 2;
const story = storyFactory({
collapsed: false,
storyType: 'release',
- releaseDate: moment().add(3, 'days')
+ releaseDate: moment().add(3, 'days'),
+ _editing: {
+ loading: false,
+ },
});
- const className = '';
- const wrapper = shallow();
- const children = wrapper.find(ExpandedStory);
+ const { wrapper } = renderComponent({ story });
+
+ const children = wrapper.querySelector('.Story--expanded');
- expect(children).toHaveProp('className', className);
+ expect(children.classList.length).toBe(DEFAULT_CLASSES_QTY);
});
it('do not put a title on children components', () => {
const story = storyFactory({
collapsed: false,
storyType: 'release',
- releaseDate: moment().add(3, 'days')
+ releaseDate: moment().add(3, 'days'),
+ _editing: {
+ loading: false,
+ },
});
const title = '';
- const wrapper = shallow();
- const children = wrapper.find(ExpandedStory);
+ const { wrapper } = renderComponent({ story });
- expect(children).toHaveProp('title', title);
+ const children = wrapper.querySelector('.Story--expanded');
+
+ expect(children.title).toBe(title);
});
});
- const render = props => {
- const wrapper = shallow();
- const expandedStory = wrapper.find('[data-id="expanded-story"]');
- return { wrapper, expandedStory };
- }
-
- describe('when the story is accepted', () => {
+ describe('when the story is accepted', () => {
it('puts .Story--accepted on childrens prop className', () => {
- const { expandedStory } = render({
+ const { expandedStory } = renderComponent({
story: storyFactory({
collapsed: false,
- state: 'accepted'
- })
+ state: 'accepted',
+ _editing: {
+ loading: false,
+ },
+ }),
});
- expect(expandedStory.prop('className')).toContain('Story--accepted');
+
+ expect(expandedStory).toHaveClass('Story--accepted');
});
});
describe('when the story is not accepted', () => {
it('does not put .Story--accepted on childrens prop className', () => {
- const { expandedStory } = render({
+ const { expandedStory } = renderComponent({
story: storyFactory({
collapsed: false,
- state: 'unscheduled'
- })
+ state: 'unscheduled',
+ _editing: {
+ loading: false,
+ },
+ }),
});
- expect(expandedStory.prop('className')).not.toContain('Story--accepted');
+
+ expect(expandedStory).not.toHaveClass('Story--accepted');
});
});
});
diff --git a/spec/javascripts/components/story/story_popover_spec.js b/spec/javascripts/components/story/story_popover_spec.js
index 02e83162c..34671ef0d 100644
--- a/spec/javascripts/components/story/story_popover_spec.js
+++ b/spec/javascripts/components/story/story_popover_spec.js
@@ -1,44 +1,64 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import moment from 'moment';
import StoryPopover, {
- StoryPopoverContent
+ StoryPopoverContent,
} from 'components/story/StoryPopover';
import storyFactory from '../../support/factories/storyFactory';
+import { beforeAll } from 'vitest';
+describe('', () => {
+ let props;
-describe("", () => {
+ beforeAll(() => {
+ props = storyFactory();
+ });
- beforeEach(function() {
- sinon.stub(I18n, 't');
+ beforeEach(function () {
+ vi.spyOn(I18n, 't');
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue(
+ `${props.description}
`
+ );
});
- afterEach(function() {
- I18n.t.restore();
+ afterEach(function () {
+ I18n.t.mockRestore();
+ window.md.makeHtml.mockRestore();
});
- it("renders the popover",() => {
+ it('renders the popover', () => {
const props = storyFactory();
- const wrapper = shallow();
- expect(wrapper.find("Popover").prop('title')).toBe(props.title);
+ const { getByTestId } = render();
+
+ const popoverChildren = getByTestId('story-popover-children');
+
+ expect(popoverChildren).toBeInTheDocument();
});
- it("renders the popover content",() => {
- const props = storyFactory();
- const wrapper = shallow();
+
+ it('renders the popover content', () => {
+ const { container } = render();
+ const markdown = container.querySelector(`.Markdown`);
expect(I18n.t).toHaveBeenCalledWith('requested by user on date', {
user: props.requestedByName,
- date: moment(props.createdAt, 'YYYY/MM/DD').format('DD MM YYYY, h:mm a')
+ date: moment(props.createdAt, 'YYYY/MM/DD').format('DD MM YYYY, h:mm a'),
});
expect(I18n.t).toHaveBeenCalledWith('story.type.' + props.storyType);
expect(I18n.t).toHaveBeenCalledWith('description');
expect(I18n.t).toHaveBeenCalledWith('notes');
- expect(wrapper.find(`Markdown[source="${props.description}"]`)).toExist();
- props.notes.map((note) => {
- expect(wrapper.find(`Markdown[source="${note.note}"]`)).toExist(),
- expect(wrapper.find(`[data-test-id=${note.id}]`).text()).toContain(`${note.userName}`),
- expect(wrapper.find(`[data-test-id=${note.id}]`).text()).toContain(`${note.createdAt}`)
+ expect(markdown.innerHTML).toContain(props.description);
+ });
+
+ it('renders the popover notes', () => {
+ const props = storyFactory();
+ const { container } = render();
+
+ const notes = container.querySelectorAll('.markdown-wrapper__text-right');
+
+ props.notes.map((note, index) => {
+ expect(notes[index].innerHTML).toContain(`${note.userName}`);
+ expect(notes[index].innerHTML).toContain(`${note.createdAt}`);
});
});
});
diff --git a/spec/javascripts/components/story/story_tasks_spec.js b/spec/javascripts/components/story/story_tasks_spec.js
index ebc11e251..3c67f98b2 100644
--- a/spec/javascripts/components/story/story_tasks_spec.js
+++ b/spec/javascripts/components/story/story_tasks_spec.js
@@ -1,45 +1,40 @@
import React from 'react';
-import { mount, shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import StoryTasks from 'components/story/StoryTasks';
-describe('', function() {
- beforeEach(function() {
- sinon.stub(I18n, 't');
+describe('', function () {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't');
});
- afterEach(function() {
- I18n.t.restore();
+ afterEach(function () {
+ I18n.t.mockRestore();
});
- it("should render a list of components", function() {
+ it('should render a list of components', function () {
const get = word => {
if (word === 'id') return 1;
if (word === 'name') return 'name';
if (word === 'done') return 'done';
- }
+ };
const task = {
get,
- escape: sinon.stub().returns('Test'),
- id: 1
+ escape: vi.fn().mockReturnValueOnce('Test'),
+ id: 1,
};
- const wrapper = mount(
+ const { container } = render(
);
- expect(wrapper.find('.task')).toExist();
+ expect(container.querySelector('.task')).toBeInTheDocument();
});
- describe("with an empty collection", function() {
-
- it("should still have a label", function() {
- const wrapper = shallow(
-
- );
+ describe('with an empty collection', function () {
+ it('should still have a label', function () {
+ render();
expect(I18n.t).toHaveBeenCalledWith('story.tasks');
});
-
});
-
});
diff --git a/spec/javascripts/components/story/task/task_list_spec.js b/spec/javascripts/components/story/task/task_list_spec.js
index 511bc539c..5ad9c4457 100644
--- a/spec/javascripts/components/story/task/task_list_spec.js
+++ b/spec/javascripts/components/story/task/task_list_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
import TasksList from 'components/story/task/TasksList';
describe('', () => {
@@ -7,13 +7,13 @@ describe('', () => {
const setup = propOverrides => {
const defaultProps = () => ({
tasks: tasksArray,
- onDelete: sinon.spy(),
- onToggle: sinon.spy(),
+ onDelete: vi.fn(),
+ onToggle: vi.fn(),
disabled: false,
- ...propOverrides
+ ...propOverrides,
});
- const wrapper = shallow();
+ const { container: wrapper } = render();
return { wrapper };
};
@@ -21,6 +21,6 @@ describe('', () => {
it('render all tasks in a component', () => {
const { wrapper } = setup();
- expect(wrapper.find('Task').length).toBe(tasksArray.length);
+ expect(wrapper.querySelectorAll('.task').length).toBe(tasksArray.length);
});
});
diff --git a/spec/javascripts/components/story/task/task_spec.js b/spec/javascripts/components/story/task/task_spec.js
index 8894a0f23..58f77d78a 100644
--- a/spec/javascripts/components/story/task/task_spec.js
+++ b/spec/javascripts/components/story/task/task_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { shallow } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import Task from 'components/story/task/Task';
describe('', () => {
@@ -9,28 +9,28 @@ describe('', () => {
id: 1,
name: 'Foo',
done: false,
- createdAt: '20/06/2018'
+ createdAt: '20/06/2018',
},
- onDelete: sinon.spy(),
- onToggle: sinon.spy(),
+ onDelete: vi.fn(),
+ onToggle: vi.fn(),
disabled: false,
- ...propOverrides
+ ...propOverrides,
});
- const wrapper = shallow();
- const deleteLink = wrapper.find('.delete-btn');
- const label = wrapper.find('label');
- const checkbox = wrapper.find('input');
+ const { container: wrapper } = render();
+ const deleteLink = wrapper.querySelector('.delete-btn');
+ const label = wrapper.querySelector('label');
+ const checkbox = wrapper.querySelector('input');
return { wrapper, deleteLink, label, checkbox };
};
describe('when user deletes a task', () => {
it('triggers onDelete callback', () => {
- const onDeleteSpy = sinon.spy();
- const { deleteLink } = setup({ onDelete: onDeleteSpy })
+ const onDeleteSpy = vi.fn();
+ const { deleteLink } = setup({ onDelete: onDeleteSpy });
- deleteLink.simulate('click');
+ fireEvent.click(deleteLink);
expect(onDeleteSpy).toHaveBeenCalled();
});
@@ -38,10 +38,10 @@ describe('', () => {
describe('when user update status of the task clicking on checkbox', () => {
it('triggers onToggle callback', () => {
- const onToggleCheckedBoxSpy = sinon.spy();
+ const onToggleCheckedBoxSpy = vi.fn();
const { checkbox } = setup({ onToggle: onToggleCheckedBoxSpy });
- checkbox.simulate('click');
+ fireEvent.click(checkbox);
expect(onToggleCheckedBoxSpy).toHaveBeenCalled();
});
@@ -51,19 +51,18 @@ describe('', () => {
it('does not render a link to delete task', () => {
const { deleteLink } = setup({ disabled: true });
- expect(deleteLink.exists()).toBe(false);
+ expect(deleteLink).not.toBeInTheDocument();
});
describe('when user tries to update the task clicking on checkbox', () => {
it('does not trigger onToggle callback', () => {
- const onToggleCheckedBoxSpy = sinon.spy();
+ const onToggleCheckedBoxSpy = vi.fn();
const { checkbox } = setup({ disabled: true });
- checkbox.simulate('click');
+ fireEvent.click(checkbox);
expect(onToggleCheckedBoxSpy).not.toHaveBeenCalled();
});
});
});
});
-
diff --git a/spec/javascripts/components/tasks/task_form_spec.js b/spec/javascripts/components/tasks/task_form_spec.js
index 7855cf47e..fcb2d0c94 100644
--- a/spec/javascripts/components/tasks/task_form_spec.js
+++ b/spec/javascripts/components/tasks/task_form_spec.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { mount } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
import TaskForm from 'components/tasks/TaskForm';
import Task from 'models/task';
@@ -9,42 +9,27 @@ describe('', function () {
beforeEach(function () {
task = new Task({ name: 'Task Test', id: 20 });
- sinon.stub(I18n, 't');
- sinon.stub(task, 'save');
});
- afterEach(function () {
- I18n.t.restore();
- task.save.restore();
- });
+ it('should have an onSubmit callback', function () {
+ const onSubmit = vi.fn().mockReturnValueOnce(Promise.resolve());
+ const { getByRole } = render();
+
+ const button = getByRole('button');
+ fireEvent.click(button);
- it("should have an onSubmit callback", function () {
- const onSubmit = sinon.stub().returns(Promise.resolve());
- const wrapper = mount(
-
- );
- wrapper.find('.add-task').simulate('click');
expect(onSubmit).toHaveBeenCalled();
});
- it("should stop loading when save fails", function (done) {
- const onSubmit = sinon.stub().returns(Promise.reject());
- const wrapper = mount(
-
- );
- wrapper.find('.add-task').simulate('click');
+ it('should stop loading when save fails', async function (done) {
+ const onSubmit = vi.fn().mockReturnValueOnce(Promise.reject());
+ const { getByRole } = render();
- Promise.resolve().then(() => {
- wrapper.update();
+ const button = getByRole('button');
+ fireEvent.click(button);
- expect(wrapper.find('.saving').exists()).toBe(false)
- done()
+ Promise.resolve().then(() => {
+ expect(button).not.toHaveClass('saving');
});
});
});
diff --git a/spec/javascripts/components/tasks/task_spec.js b/spec/javascripts/components/tasks/task_spec.js
index c12b51057..ab6f6e78c 100644
--- a/spec/javascripts/components/tasks/task_spec.js
+++ b/spec/javascripts/components/tasks/task_spec.js
@@ -1,72 +1,60 @@
-
import React from 'react';
-import { shallow, mount } from 'enzyme';
+import { fireEvent, render } from '@testing-library/react';
-import Checkbox from 'components/forms/Checkbox';
import TaskComponent from 'components/tasks/Task';
-import TaskForm from 'components/tasks/TaskForm';
import Task from 'models/task';
-describe('', function() {
+describe('', function () {
let task;
- beforeEach(function() {
- sinon.stub(I18n, 't');
- task = new Task({name: 'Test Task', id: 5});
- });
-
- afterEach(function() {
- I18n.t.restore();
+ beforeEach(function () {
+ task = new Task({ name: 'Test Task', id: 5 });
});
- it("should be able to call handleDelete", function() {
- const handleDelete = sinon.stub();
- const wrapper = mount(
+ it('should be able to call handleDelete', function () {
+ const handleDelete = vi.fn();
+ const { container } = render(
{}}
/>
);
- wrapper.find('.delete-btn').simulate('click');
+ const button = container.querySelector('.delete-btn');
+ fireEvent.click(button);
+
expect(handleDelete).toHaveBeenCalled();
});
- it("should be able to call handleUpdate", function() {
- const handleUpdate = sinon.stub();
- const wrapper = mount(
-
+ it('should be able to call handleUpdate', async function () {
+ const handleUpdate = vi.fn();
+ const { getByRole } = render(
+
);
- wrapper.find('input').simulate('change', { target: { checked: true } });
+ const input = getByRole('checkbox');
+ fireEvent.click(input);
+
expect(handleUpdate).toHaveBeenCalled();
});
- describe("when not disabled", function() {
-
- it("should have an delete button", function() {
- const wrapper = mount(
+ describe('when not disabled', function () {
+ it('should have an delete button', function () {
+ const { container } = render(
);
- expect(wrapper.find('.delete-btn')).toExist();
+ expect(container.querySelector('.delete-btn')).toBeInTheDocument();
});
-
});
- describe("when disabled", function() {
-
- it("should not have a delete button", function() {
- const wrapper = mount(
+ describe('when disabled', function () {
+ it('should not have a delete button', function () {
+ const { container } = render(
);
- expect(wrapper.find('.delete-btn')).not.toExist();
+ expect(container.querySelector('.delete-btn')).not.toBeInTheDocument();
});
-
});
-
});
diff --git a/spec/javascripts/mocks/server.js b/spec/javascripts/mocks/server.js
new file mode 100644
index 000000000..618e02b77
--- /dev/null
+++ b/spec/javascripts/mocks/server.js
@@ -0,0 +1,3 @@
+import { setupServer } from 'msw/node';
+
+export const server = setupServer();
diff --git a/spec/javascripts/models/activity_spec.js b/spec/javascripts/models/activity_spec.js
index b1c02f945..f2635268f 100644
--- a/spec/javascripts/models/activity_spec.js
+++ b/spec/javascripts/models/activity_spec.js
@@ -1,41 +1,37 @@
import Activity from 'models/activity';
-describe("Activity", function() {
+describe('Activity', function () {
let activity;
- beforeEach(function() {
+ beforeEach(function () {
activity = new Activity({
activity: {
action: 'update',
subject_type: 'Story',
- updated_at: '2017/02/01 11:02:10 -0200'
- }
+ updated_at: '2017/02/01 11:02:10 -0200',
+ },
});
});
- describe('initialize', function() {
-
- it('should format the date string', function(){
+ describe('initialize', function () {
+ it('should format the date string', function () {
expect(activity.attributes.date).toBe('1 Feb 2017');
});
-
});
- describe('humanActionName', function() {
-
- beforeEach(function() {
- sinon.stub(I18n, 't');
- I18n.t.withArgs('update').returns('updated');
+ describe('humanActionName', function () {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't').mockImplementation(arg => {
+ if (arg === 'update') return 'updated';
+ });
});
- afterEach(function() {
- I18n.t.restore();
+ afterEach(function () {
+ I18n.t.mockRestore();
});
- it("returns the translated action name", function() {
+ it('returns the translated action name', function () {
expect(activity.humanActionName('update')).toEqual('updated');
});
-
});
-
});
diff --git a/spec/javascripts/models/beta/iteration_spec.js b/spec/javascripts/models/beta/iteration_spec.js
index 2395be473..787080f84 100644
--- a/spec/javascripts/models/beta/iteration_spec.js
+++ b/spec/javascripts/models/beta/iteration_spec.js
@@ -1,13 +1,13 @@
-import * as Iteration from "models/beta/iteration";
-import moment from "moment";
+import * as Iteration from 'models/beta/iteration';
+import moment from 'moment';
-describe("iteration", function () {
- describe("calculateRemainingPoints", () => {
- describe("when velocity is greater than points", () => {
+describe('iteration', function () {
+ describe('calculateRemainingPoints', () => {
+ describe('when velocity is greater than points', () => {
const points = [1, 2, 3, 4, 5];
- points.forEach((p) => {
- it("returns difference between them", () => {
+ points.forEach(p => {
+ it('returns difference between them', () => {
const velocity = 10;
const difference = velocity - p;
@@ -18,11 +18,11 @@ describe("iteration", function () {
});
});
- describe("when points are greater than velocity", () => {
+ describe('when points are greater than velocity', () => {
const points = [10, 20, 30, 40, 50];
- points.forEach((p) => {
- it("returns 0", () => {
+ points.forEach(p => {
+ it('returns 0', () => {
const velocity = 10;
expect(Iteration.calculateRemainingPoints(velocity, p)).toEqual(0);
@@ -31,27 +31,27 @@ describe("iteration", function () {
});
});
- describe("canTakeStory", () => {
+ describe('canTakeStory', () => {
const pointsOptions = [2, 4, 8, 10, 15];
- pointsOptions.forEach((points) => {
+ pointsOptions.forEach(points => {
describe(`when story have ${points} points`, () => {
const biggerThanPoints = points + 1;
const smallerThanPoints = points - 1;
- describe("and remaining points of sprint is bigger than story points", () => {
- it("returns truthy", () => {
+ describe('and remaining points of sprint is bigger than story points', () => {
+ it('returns truthy', () => {
const sprint = { remainingPoints: biggerThanPoints };
- const story = { estimate: points, storyType: "feature" };
+ const story = { estimate: points, storyType: 'feature' };
expect(Iteration.canTakeStory(sprint, story)).toBeTruthy();
});
});
- describe("and remaining points of sprint is smaller than story points", () => {
- it("returns falsy", () => {
+ describe('and remaining points of sprint is smaller than story points', () => {
+ it('returns falsy', () => {
const sprint = { remainingPoints: smallerThanPoints };
- const story = { estimate: points, storyType: "feature" };
+ const story = { estimate: points, storyType: 'feature' };
expect(Iteration.canTakeStory(sprint, story)).toBeFalsy();
});
@@ -60,54 +60,54 @@ describe("iteration", function () {
});
});
- describe("calculateFillerSprintsQuantity", () => {
- describe("when story have 3 points", () => {
+ describe('calculateFillerSprintsQuantity', () => {
+ describe('when story have 3 points', () => {
const storyPoints = 3;
- describe("and velocity is 1", () => {
+ describe('and velocity is 1', () => {
const velocity = 1;
- it("returns 2", () => {
+ it('returns 2', () => {
expect(
Iteration.calculateFillerSprintsQuantity(storyPoints, velocity)
).toEqual(2);
});
});
- describe("and velocity is 2", () => {
+ describe('and velocity is 2', () => {
const velocity = 2;
- it("returns 1", () => {
+ it('returns 1', () => {
expect(
Iteration.calculateFillerSprintsQuantity(storyPoints, velocity)
).toEqual(1);
});
});
- describe("and velocity is 3", () => {
+ describe('and velocity is 3', () => {
const velocity = 3;
- it("returns 0", () => {
+ it('returns 0', () => {
expect(
Iteration.calculateFillerSprintsQuantity(storyPoints, velocity)
).toEqual(0);
});
});
- describe("and velocity is 4", () => {
+ describe('and velocity is 4', () => {
const velocity = 4;
- it("returns 0", () => {
+ it('returns 0', () => {
expect(
Iteration.calculateFillerSprintsQuantity(storyPoints, velocity)
).toEqual(0);
});
});
- describe("and velocity is 5", () => {
+ describe('and velocity is 5', () => {
const velocity = 5;
- it("returns 0", () => {
+ it('returns 0', () => {
expect(
Iteration.calculateFillerSprintsQuantity(storyPoints, velocity)
).toEqual(0);
@@ -116,70 +116,73 @@ describe("iteration", function () {
});
});
- describe("time related functions", function () {
+ describe('time related functions', function () {
let clock;
+ const daysInWeek = 7;
beforeEach(function () {
- clock = sinon.useFakeTimers(new Date("2018-05-01T17:00:00").getTime());
+ clock = vi.useFakeTimers(new Date('2018-05-01T17:00:00').getTime());
});
- afterEach(function () {
- clock.restore();
- });
-
- describe("when 1 out of 1 week has passed", function () {
- it("returns 2", function () {
+ describe('when 1 out of 1 week has passed', function () {
+ const startDate = new Date();
+ startDate.setDate(startDate.getDate() - daysInWeek);
+ it('returns 2', function () {
const sprintNumber = Iteration.getCurrentIteration({
iterationLength: 1,
- startDate: "2018-04-24T16:00:00",
+ startDate,
});
expect(sprintNumber).toEqual(2);
});
});
- describe("when 3 out of 3 weeks has passed", function () {
- it("returns 2", function () {
+ describe('when 3 out of 3 weeks has passed', function () {
+ const startDate = new Date();
+ startDate.setDate(startDate.getDate() - daysInWeek * 3);
+ it('returns 2', function () {
const sprintNumber = Iteration.getCurrentIteration({
iterationLength: 3,
- startDate: "2018-04-10T16:00:00",
+ startDate,
});
expect(sprintNumber).toEqual(2);
});
});
- describe("when 1 out of 2 weeks has passed", function () {
- it("returns 1", function () {
+ describe('when 1 out of 2 weeks has passed', function () {
+ it('returns 1', function () {
+ const startDate = new Date();
+ startDate.setDate(startDate.getDate() - daysInWeek);
const sprintNumber = Iteration.getCurrentIteration({
iterationLength: 2,
- startDate: "2018-04-24T16:00:00",
+ startDate,
});
expect(sprintNumber).toEqual(1);
});
});
- describe("when a story was acceped a week ago", function () {
- it("returns 2", function () {
+ describe('when a story was acceped a week ago', function () {
+ it('returns 2', function () {
const sprintNumber = Iteration.getIterationForStory(
- { state: "accepted", acceptedAt: "2018-04-24T16:00:00" },
- { startDate: "2018-04-10T16:00:00", iterationLength: 2 }
+ { state: 'accepted', acceptedAt: '2018-04-24T16:00:00' },
+ { startDate: '2018-04-10T16:00:00', iterationLength: 2 }
);
expect(sprintNumber).toEqual(2);
});
});
});
- describe("when calculating sprint velocity", function () {
+ describe('when calculating sprint velocity', function () {
let project;
beforeEach(() => {
project = {
- startDate: "2018-09-03T16:00:00",
+ startDate: '2018-09-03T16:00:00',
iterationLength: 1,
defaultVelocity: 2,
};
});
- describe("when there are less than 3 past iterations", function () {
- it("return the same value as default velocity", () => {
+ describe('when there are less than 3 past iterations', function () {
+ it('return the same value as default velocity', () => {
const sprintVelocity = Iteration.sprintVelocity(project, [
{ points: 3 },
]);
@@ -187,8 +190,8 @@ describe("iteration", function () {
});
});
- describe("when there more than 3 past iterations", function () {
- it("return the medium of the last 3", () => {
+ describe('when there more than 3 past iterations', function () {
+ it('return the medium of the last 3', () => {
const sprintVelocity = Iteration.sprintVelocity(project, [
{ points: 3 },
{ points: 3 },
@@ -200,20 +203,20 @@ describe("iteration", function () {
});
});
- describe("when reducing stories to sprints", function () {
- describe("when default velocity is 2", () => {
+ describe('when reducing stories to sprints', function () {
+ describe('when default velocity is 2', () => {
let project;
beforeEach(() => {
project = {
- startDate: "2018-09-03T16:00:00",
+ startDate: '2018-09-03T16:00:00',
iterationLength: 1,
currentSprintVelocity: 2,
};
});
- describe("with empty array of stories", function () {
- it("return an empty array of sprints", () => {
+ describe('with empty array of stories', function () {
+ it('return an empty array of sprints', () => {
const stories = [];
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
@@ -225,29 +228,29 @@ describe("iteration", function () {
});
});
- describe("with 2 unstarted features with 1 point", function () {
+ describe('with 2 unstarted features with 1 point', function () {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("return an array with 1 item ", function () {
+ it('return an array with 1 item ', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -257,7 +260,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(1);
});
- it("return an array with 2 stoies in first position", () => {
+ it('return an array with 2 stoies in first position', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -268,55 +271,55 @@ describe("iteration", function () {
});
});
- describe("with started, finished and delivered stories", function () {
+ describe('with started, finished and delivered stories', function () {
const stories = [
{
id: 1,
- position: "1.5",
- state: "accepted",
- acceptedAt: "2018-09-03T16:36:20.811Z",
+ position: '1.5',
+ state: 'accepted',
+ acceptedAt: '2018-09-03T16:36:20.811Z',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 4,
- position: "7.5",
- state: "started",
- startedAt: "2018-09-03T16:36:20.811Z",
+ position: '7.5',
+ state: 'started',
+ startedAt: '2018-09-03T16:36:20.811Z',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 5,
- position: "3.7",
- state: "finished",
+ position: '3.7',
+ state: 'finished',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 6,
- position: "4.9",
- state: "delivered",
- deliveredAt: "2018-09-03T16:36:20.811Z",
+ position: '4.9',
+ state: 'delivered',
+ deliveredAt: '2018-09-03T16:36:20.811Z',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 7,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
];
- it("return an array with 3 items", function () {
+ it('return an array with 3 items', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -327,22 +330,22 @@ describe("iteration", function () {
});
});
- describe("with 1 unstarted features with 2 points", () => {
+ describe('with 1 unstarted features with 2 points', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "1",
- state: "unstarted",
+ position: '1',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("return an array with 1 item", function () {
+ it('return an array with 1 item', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -352,102 +355,102 @@ describe("iteration", function () {
expect(sprints.length).toEqual(1);
});
- it("return an array with just one story in first position", () => {
+ it('return an array with just one story in first position', () => {
+ const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
project,
initialSprintNumber
);
- const initialSprintNumber = Iteration.getCurrentIteration(project);
expect(sprints[0].stories.length).toEqual(1);
});
});
- describe("sprints number", () => {
- describe("when the initialSprintNumber is 15", () => {
+ describe('sprints number', () => {
+ describe('when the initialSprintNumber is 15', () => {
let project;
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "11",
- state: "unstarted",
+ position: '11',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
];
project = {
- startDate: "2018-09-03T16:00:00",
+ startDate: '2018-09-03T16:00:00',
iterationLength: 1,
currentSprintVelocity: 2,
};
});
- it("the first sprint returns 15", () => {
+ it('the first sprint returns 15', () => {
const sprints = Iteration.groupBySprints(stories, project, 15);
expect(sprints[0].number).toBe(15);
});
- it("the second sprint returns 16", () => {
+ it('the second sprint returns 16', () => {
const sprints = Iteration.groupBySprints(stories, project, 15);
expect(sprints[1].number).toBe(16);
});
- it("the third sprint returns 17", () => {
+ it('the third sprint returns 17', () => {
const sprints = Iteration.groupBySprints(stories, project, 15);
expect(sprints[2].number).toBe(17);
});
});
- describe("when there is no initialSprintNumber", () => {
+ describe('when there is no initialSprintNumber', () => {
let stories;
let project;
beforeEach(() => {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
];
project = {
- startDate: "2018-09-03T16:00:00",
+ startDate: '2018-09-03T16:00:00',
iterationLength: 1,
currentSprintVelocity: 2,
};
});
- it("the first sprint returns 1", () => {
+ it('the first sprint returns 1', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
@@ -459,77 +462,77 @@ describe("iteration", function () {
});
});
- describe("sprints startDate", () => {
- describe("when the project starts today and iterationLenght is 1 week", () => {
+ describe('sprints startDate', () => {
+ describe('when the project starts today and iterationLenght is 1 week', () => {
let stories;
let project;
beforeEach(() => {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "11",
- state: "unstarted",
+ position: '11',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
];
project = {
- startDate: moment().format("YYYY/MM/DD"),
+ startDate: moment().format('YYYY/MM/DD'),
iterationLength: 1,
currentSprintVelocity: 2,
};
});
- it("first sprint starts today", () => {
+ it('first sprint starts today', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
undefined
);
- const startDate = moment().format("YYYY/MM/DD");
+ const startDate = moment().format('YYYY/MM/DD');
expect(sprints[0].startDate).toBe(startDate);
});
- it("second sprint starts 1 week after today", () => {
+ it('second sprint starts 1 week after today', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
undefined
);
- const startDate = moment().add(1, "weeks").format("YYYY/MM/DD");
+ const startDate = moment().add(1, 'weeks').format('YYYY/MM/DD');
expect(sprints[1].startDate).toBe(startDate);
});
- it("third sprint starts 2 weeks after today", () => {
+ it('third sprint starts 2 weeks after today', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
undefined
);
- const startDate = moment().add(2, "weeks").format("YYYY/MM/DD");
+ const startDate = moment().add(2, 'weeks').format('YYYY/MM/DD');
expect(sprints[2].startDate).toBe(startDate);
});
});
- describe("when the project started 2 weeks ago and iterationLenght is 1 week", () => {
+ describe('when the project started 2 weeks ago and iterationLenght is 1 week', () => {
let projectStartDate;
let project;
let stories;
@@ -537,83 +540,83 @@ describe("iteration", function () {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 3,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "11",
- state: "unstarted",
+ position: '11',
+ state: 'unstarted',
estimate: 3,
- storyType: "feature",
+ storyType: 'feature',
},
];
- projectStartDate = moment().subtract(2, "weeks");
+ projectStartDate = moment().subtract(2, 'weeks');
project = {
- startDate: projectStartDate.format("YYYY/MM/DD"),
+ startDate: projectStartDate.format('YYYY/MM/DD'),
iterationLength: 1,
currentSprintVelocity: 2,
};
});
- it("first sprint starts 2 weeks after projectStartDate", () => {
+ it('first sprint starts 2 weeks after projectStartDate', () => {
const sprints = Iteration.groupBySprints(stories, project, 3);
const startDate = projectStartDate
- .add(2, "weeks")
- .format("YYYY/MM/DD");
+ .add(2, 'weeks')
+ .format('YYYY/MM/DD');
expect(sprints[0].startDate).toBe(startDate);
});
- it("second sprint starts 3 weeks after startDate", () => {
+ it('second sprint starts 3 weeks after startDate', () => {
const sprints = Iteration.groupBySprints(stories, project, 3);
const startDate = projectStartDate
- .add(3, "weeks")
- .format("YYYY/MM/DD");
+ .add(3, 'weeks')
+ .format('YYYY/MM/DD');
expect(sprints[1].startDate).toBe(startDate);
});
});
});
- describe("when current sprint velocity is 3", () => {
+ describe('when current sprint velocity is 3', () => {
const project = {
- startDate: "2018-09-03T16:00:00",
+ startDate: '2018-09-03T16:00:00',
iterationLength: 1,
currentSprintVelocity: 3,
};
- describe("with unstarted features", function () {
+ describe('with unstarted features', function () {
const stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
];
- it("return an array with 1 item", function () {
+ it('return an array with 1 item', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -624,7 +627,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(1);
});
- it("return an array with one sprint with 2 points", () => {
+ it('return an array with one sprint with 2 points', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -636,7 +639,7 @@ describe("iteration", function () {
expect(sprints[0].points).toEqual(2);
});
- it("return an array with one sprint with 1 remaining point", () => {
+ it('return an array with one sprint with 1 remaining point', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -648,32 +651,32 @@ describe("iteration", function () {
});
});
- describe("with 3 unstarted features with 1, 3 and 1 points", function () {
+ describe('with 3 unstarted features with 1, 3 and 1 points', function () {
const stories = [
{
id: 1,
- position: "1",
- state: "unstarted",
+ position: '1',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "2",
- state: "unstarted",
+ position: '2',
+ state: 'unstarted',
estimate: 3,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "3",
- state: "unstarted",
+ position: '3',
+ state: 'unstarted',
estimate: 1,
- storyType: "feature",
+ storyType: 'feature',
},
];
- it("return an array with 3 items", () => {
+ it('return an array with 3 items', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -684,7 +687,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(3);
});
- it("return an array with first position with 1 point", () => {
+ it('return an array with first position with 1 point', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -695,7 +698,7 @@ describe("iteration", function () {
expect(sprints[0].points).toEqual(1);
});
- it("return an array with second position with 3 points", () => {
+ it('return an array with second position with 3 points', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -706,7 +709,7 @@ describe("iteration", function () {
expect(sprints[1].points).toEqual(3);
});
- it("return an array with third position with 1 point", () => {
+ it('return an array with third position with 1 point', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -717,7 +720,7 @@ describe("iteration", function () {
expect(sprints[2].points).toEqual(1);
});
- it("return an array with third position with 2 remaining points", () => {
+ it('return an array with third position with 2 remaining points', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -729,35 +732,35 @@ describe("iteration", function () {
});
});
- describe("when have 3 stories, 1 unstarted feature and 2 started features", function () {
+ describe('when have 3 stories, 1 unstarted feature and 2 started features', function () {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "1",
- state: "started",
+ position: '1',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "2",
- state: "started",
+ position: '2',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "3",
- state: "unstarted",
+ position: '3',
+ state: 'unstarted',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("return an array with 3 items", function () {
+ it('return an array with 3 items', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -768,7 +771,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(3);
});
- it("return an array with last sprint beeing filler", function () {
+ it('return an array with last sprint beeing filler', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -779,7 +782,7 @@ describe("iteration", function () {
expect(sprints[2].isFiller).toBeTruthy();
});
- it("return an array with first sprint with 8 points", function () {
+ it('return an array with first sprint with 8 points', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -790,7 +793,7 @@ describe("iteration", function () {
expect(sprints[0].points).toEqual(8);
});
- it("return an array with last sprint with 4 points", function () {
+ it('return an array with last sprint with 4 points', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -801,7 +804,7 @@ describe("iteration", function () {
expect(sprints[2].points).toEqual(4);
});
- it("return an array with sprint of middle with 0 points", function () {
+ it('return an array with sprint of middle with 0 points', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -813,64 +816,64 @@ describe("iteration", function () {
});
});
- describe("when have 10 stories no feature", () => {
+ describe('when have 10 stories no feature', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "1",
- storyType: "bug",
+ position: '1',
+ storyType: 'bug',
},
{
id: 2,
- position: "2",
- storyType: "bug",
+ position: '2',
+ storyType: 'bug',
},
{
id: 3,
- position: "3",
- storyType: "bug",
+ position: '3',
+ storyType: 'bug',
},
{
id: 4,
- position: "4",
- storyType: "bug",
+ position: '4',
+ storyType: 'bug',
},
{
id: 5,
- position: "5",
- storyType: "bug",
+ position: '5',
+ storyType: 'bug',
},
{
id: 6,
- position: "6",
- storyType: "bug",
+ position: '6',
+ storyType: 'bug',
},
{
id: 7,
- position: "7",
- storyType: "bug",
+ position: '7',
+ storyType: 'bug',
},
{
id: 8,
- position: "8",
- storyType: "bug",
+ position: '8',
+ storyType: 'bug',
},
{
id: 9,
- position: "9",
- storyType: "bug",
+ position: '9',
+ storyType: 'bug',
},
{
id: 10,
- position: "10",
- storyType: "bug",
+ position: '10',
+ storyType: 'bug',
},
];
});
- it("return an array with 1 item", function () {
+ it('return an array with 1 item', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -881,7 +884,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(1);
});
- it("return one sprint with 0 points", function () {
+ it('return one sprint with 0 points', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -893,40 +896,40 @@ describe("iteration", function () {
});
});
- describe("when 4 stories no feature and 1 story feature", () => {
+ describe('when 4 stories no feature and 1 story feature', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "1",
- storyType: "bug",
+ position: '1',
+ storyType: 'bug',
},
{
id: 2,
- position: "2",
- storyType: "bug",
+ position: '2',
+ storyType: 'bug',
},
{
id: 3,
- position: "3",
- storyType: "bug",
+ position: '3',
+ storyType: 'bug',
},
{
id: 4,
- position: "4",
- storyType: "bug",
+ position: '4',
+ storyType: 'bug',
},
{
id: 5,
- position: "5",
- storyType: "feature",
- estimate: "3",
+ position: '5',
+ storyType: 'feature',
+ estimate: '3',
},
];
});
- it("return an array with 1 item", function () {
+ it('return an array with 1 item', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -937,7 +940,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(1);
});
- it("return one sprint with 3 points", function () {
+ it('return one sprint with 3 points', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -949,84 +952,84 @@ describe("iteration", function () {
});
});
- describe("when have 10 started stories with 4 points each", () => {
+ describe('when have 10 started stories with 4 points each', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "1",
- state: "started",
+ position: '1',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "2",
- state: "started",
+ position: '2',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "3",
- state: "started",
+ position: '3',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 4,
- position: "4",
- state: "started",
+ position: '4',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 5,
- position: "5",
- state: "started",
+ position: '5',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 6,
- position: "6",
- state: "started",
+ position: '6',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 7,
- position: "7",
- state: "started",
+ position: '7',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 8,
- position: "8",
- state: "started",
+ position: '8',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 9,
- position: "9",
- state: "started",
+ position: '9',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 10,
- position: "10",
- state: "started",
+ position: '10',
+ state: 'started',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("return an array with 1 item", function () {
+ it('return an array with 1 item', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1037,7 +1040,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(1);
});
- it("return one sprint with 40 points", function () {
+ it('return one sprint with 40 points', function () {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1049,35 +1052,35 @@ describe("iteration", function () {
});
});
- describe("when have 3 unstarted stories of 4 points", () => {
+ describe('when have 3 unstarted stories of 4 points', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "1",
- state: "unstarted",
+ position: '1',
+ state: 'unstarted',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "2",
- state: "unstarted",
+ position: '2',
+ state: 'unstarted',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 3,
- position: "3",
- state: "unstarted",
+ position: '3',
+ state: 'unstarted',
estimate: 4,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("return an array with 5 items", () => {
+ it('return an array with 5 items', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1088,7 +1091,7 @@ describe("iteration", function () {
expect(sprints.length).toEqual(5);
});
- it("checks if the first element have 4 points", () => {
+ it('checks if the first element have 4 points', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1099,7 +1102,7 @@ describe("iteration", function () {
expect(sprints[0].points).toEqual(4);
});
- it("checks if the second element have 0 points", () => {
+ it('checks if the second element have 0 points', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1110,7 +1113,7 @@ describe("iteration", function () {
expect(sprints[1].points).toEqual(0);
});
- it("checks if the second element have 2 points", () => {
+ it('checks if the second element have 2 points', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1121,7 +1124,7 @@ describe("iteration", function () {
expect(sprints[1].remainingPoints).toEqual(2);
});
- it("checks if the second element is filler", () => {
+ it('checks if the second element is filler', () => {
const initialSprintNumber = Iteration.getCurrentIteration(project);
const sprints = Iteration.groupBySprints(
stories,
@@ -1134,7 +1137,7 @@ describe("iteration", function () {
});
});
- describe("sprints point", () => {
+ describe('sprints point', () => {
let project;
beforeEach(() => {
project = {
@@ -1144,25 +1147,25 @@ describe("iteration", function () {
};
});
- describe("when there is two feature stories with 2 and 3 points", () => {
+ describe('when there is two feature stories with 2 and 3 points', () => {
const stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
+ position: '3.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
{
id: 2,
- position: "10",
- state: "unstarted",
+ position: '10',
+ state: 'unstarted',
estimate: 3,
- storyType: "feature",
+ storyType: 'feature',
},
];
- it("returns 5", () => {
+ it('returns 5', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
@@ -1172,18 +1175,18 @@ describe("iteration", function () {
});
});
- describe("when there is only one bug story", () => {
+ describe('when there is only one bug story', () => {
const stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
- estimate: "",
- storyType: "bug",
+ position: '3.2',
+ state: 'unstarted',
+ estimate: '',
+ storyType: 'bug',
},
];
- it("returns 0", () => {
+ it('returns 0', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
@@ -1193,28 +1196,28 @@ describe("iteration", function () {
});
});
- describe("when there is one bug and one feature with 2 points", () => {
+ describe('when there is one bug and one feature with 2 points', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
- estimate: "",
- storyType: "bug",
+ position: '3.2',
+ state: 'unstarted',
+ estimate: '',
+ storyType: 'bug',
},
{
id: 2,
- position: "4.2",
- state: "unstarted",
+ position: '4.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("returns 2", () => {
+ it('returns 2', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
@@ -1223,38 +1226,38 @@ describe("iteration", function () {
expect(sprints[0].points).toBe(2);
});
- it("returns a number", () => {
+ it('returns a number', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
undefined
);
- expect(typeof sprints[0].points).toBe("number");
+ expect(typeof sprints[0].points).toBe('number');
});
});
- describe("when there is two features one with 2 points and other with no estimate", () => {
+ describe('when there is two features one with 2 points and other with no estimate', () => {
let stories;
beforeEach(() => {
stories = [
{
id: 1,
- position: "3.2",
- state: "unstarted",
- estimate: "",
- storyType: "feature",
+ position: '3.2',
+ state: 'unstarted',
+ estimate: '',
+ storyType: 'feature',
},
{
id: 2,
- position: "4.2",
- state: "unstarted",
+ position: '4.2',
+ state: 'unstarted',
estimate: 2,
- storyType: "feature",
+ storyType: 'feature',
},
];
});
- it("returns 2", () => {
+ it('returns 2', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
@@ -1263,50 +1266,50 @@ describe("iteration", function () {
expect(sprints[0].points).toBe(2);
});
- it("returns a number", () => {
+ it('returns a number', () => {
const sprints = Iteration.groupBySprints(
stories,
project,
undefined
);
- expect(typeof sprints[0].points).toBe("number");
+ expect(typeof sprints[0].points).toBe('number');
});
});
});
});
});
- describe("causesOverflow", () => {
- describe("when story is feature", () => {
- describe("and have 2 points", () => {
+ describe('causesOverflow', () => {
+ describe('when story is feature', () => {
+ describe('and have 2 points', () => {
let story;
beforeEach(() => {
story = {
- storyType: "feature",
+ storyType: 'feature',
estimate: 2,
};
});
- describe("and velocity is 3", () => {
- it("returns truthy", () => {
+ describe('and velocity is 3', () => {
+ it('returns truthy', () => {
expect(Iteration.causesOverflow(story, 3)).toBeFalsy();
});
});
- describe("and velocity is 1", () => {
- it("returns falsy", () => {
+ describe('and velocity is 1', () => {
+ it('returns falsy', () => {
expect(Iteration.causesOverflow(story, 1)).toBeTruthy();
});
});
});
});
- describe("when story is not a feature", () => {
+ describe('when story is not a feature', () => {
const story = {
- storyType: "bug",
+ storyType: 'bug',
};
- it("returns falsy", () => {
+ it('returns falsy', () => {
expect(Iteration.causesOverflow(story, 1)).toBeFalsy();
});
});
diff --git a/spec/javascripts/models/beta/project_board_spec.js b/spec/javascripts/models/beta/project_board_spec.js
index adc9f3869..cf3a64c0c 100644
--- a/spec/javascripts/models/beta/project_board_spec.js
+++ b/spec/javascripts/models/beta/project_board_spec.js
@@ -9,7 +9,7 @@ describe('ProjectBoard model', () => {
validKeyWords.forEach(keyWord => {
describe(`when keyword is ${keyWord}`, () => {
const projectBoard = {
- search: { keyWord }
+ search: { keyWord },
};
it('returns truthy', () => {
@@ -21,7 +21,7 @@ describe('ProjectBoard model', () => {
invalidKeyWords.forEach(keyWord => {
describe(`when keyword is ${keyWord}`, () => {
const projectBoard = {
- search: { keyWord }
+ search: { keyWord },
};
it('returns falsy', () => {
@@ -33,7 +33,7 @@ describe('ProjectBoard model', () => {
describe('validSearch', () => {
const validKeyWords = ['foo', 'bar', 'lorem ipsum'];
- const invalidKeyWords = ['', ' ', '']
+ const invalidKeyWords = ['', ' ', ''];
validKeyWords.forEach(keyWord => {
describe(`when keyword is ${keyWord}`, () => {
@@ -108,8 +108,8 @@ describe('ProjectBoard model', () => {
let callback;
beforeEach(() => {
- onToggle = sinon.spy();
- callback = { onToggle }
+ onToggle = vi.fn();
+ callback = { onToggle };
});
describe('and have more of one column open', () => {
@@ -117,12 +117,12 @@ describe('ProjectBoard model', () => {
const projectBoard = {
visibleColumns: {
chillyBin: true,
- backlog: true
- }
+ backlog: true,
+ },
};
ProjectBoard.toggleColumn(projectBoard, column, callback);
- expect(onToggle.called).toBeTruthy();
+ expect(callback.onToggle).toHaveBeenCalled();
});
});
@@ -131,12 +131,12 @@ describe('ProjectBoard model', () => {
const projectBoard = {
visibleColumns: {
chillyBin: true,
- backlog: false
- }
+ backlog: false,
+ },
};
ProjectBoard.toggleColumn(projectBoard, column, callback);
- expect(onToggle.called).toBeFalsy();
+ expect(callback.onToggle).not.toHaveBeenCalled();
});
});
});
@@ -144,30 +144,36 @@ describe('ProjectBoard model', () => {
describe('when is opening an column', () => {
const projectBoard = {
visibleColumns: {
- chillyBin: false
- }
+ chillyBin: false,
+ },
};
const column = 'chillyBin';
let onToggle;
let callback;
beforeEach(() => {
- onToggle = sinon.spy();
+ onToggle = vi.fn();
callback = { onToggle };
});
it('always calls callback.onToggle', () => {
ProjectBoard.toggleColumn(projectBoard, column, callback);
- expect(onToggle.called).toBeTruthy();
+ expect(callback.onToggle).toHaveBeenCalled();
});
});
});
-
describe('Drag and Drop', () => {
describe('getPositions', () => {
- const array = [{ newPosition: 24, position: 24, state: 'finished' }, { newPosition: 20, position: 20, state: 'finished' }, { newPosition: 16, position: 16, state: 'unstarted' }, { newPosition: 12, position: 12, state: 'unstarted' }, { newPosition: 8, position: 8, state: 'started' }, { newPosition: 4, position: 4, state: 'started' }];
+ const array = [
+ { newPosition: 24, position: 24, state: 'finished' },
+ { newPosition: 20, position: 20, state: 'finished' },
+ { newPosition: 16, position: 16, state: 'unstarted' },
+ { newPosition: 12, position: 12, state: 'unstarted' },
+ { newPosition: 8, position: 8, state: 'started' },
+ { newPosition: 4, position: 4, state: 'started' },
+ ];
describe('same column', () => {
const isSameColumn = true;
@@ -181,9 +187,9 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'unstarted',
- ),
- ).toEqual([15,15]);
+ 'unstarted'
+ )
+ ).toEqual([15, 15]);
});
});
@@ -197,9 +203,9 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'finished',
- ),
- ).toEqual([21,21]);
+ 'finished'
+ )
+ ).toEqual([21, 21]);
});
});
@@ -213,9 +219,9 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'finished',
- ),
- ).toEqual([23,1]);
+ 'finished'
+ )
+ ).toEqual([23, 1]);
});
});
@@ -229,16 +235,16 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'started',
- ),
- ).toEqual([5,5]);
+ 'started'
+ )
+ ).toEqual([5, 5]);
});
});
});
- describe("Different columns", () => {
+ describe('Different columns', () => {
const isSameColumn = false;
- describe("Dragging to another column", () => {
+ describe('Dragging to another column', () => {
const sourceIndex = 3;
const destinationIndex = 2;
it('returns a new position', () => {
@@ -248,9 +254,9 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'unstarted',
- ),
- ).toEqual([15,15]);
+ 'unstarted'
+ )
+ ).toEqual([15, 15]);
});
});
@@ -264,9 +270,9 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'finished',
- ),
- ).toEqual([23,1]);
+ 'finished'
+ )
+ ).toEqual([23, 1]);
});
});
@@ -280,29 +286,42 @@ describe('ProjectBoard model', () => {
sourceIndex,
array,
isSameColumn,
- 'started',
- ),
- ).toEqual([5,5]);
+ 'started'
+ )
+ ).toEqual([5, 5]);
});
});
});
});
- describe("moveStory", () => {
+ describe('moveStory', () => {
let sourceArray;
let destinationArray;
let newDestArray;
beforeEach(() => {
newDestArray = [];
- sourceArray = [{ story: 'source1' }, { story: 'source2' }, { story: 'source3' }];
- destinationArray = [{ story: 'dest1' }, { story: 'dest2' }, { story: 'dest3' }];
+ sourceArray = [
+ { story: 'source1' },
+ { story: 'source2' },
+ { story: 'source3' },
+ ];
+ destinationArray = [
+ { story: 'dest1' },
+ { story: 'dest2' },
+ { story: 'dest3' },
+ ];
});
- describe("When moving in same column", () => {
+ describe('When moving in same column', () => {
const sourceIndex = 0;
const destinationIndex = 1;
it('returns a new array', () => {
- newDestArray = ProjectBoard.moveStory(sourceArray, sourceArray, sourceIndex, destinationIndex);
+ newDestArray = ProjectBoard.moveStory(
+ sourceArray,
+ sourceArray,
+ sourceIndex,
+ destinationIndex
+ );
expect(newDestArray[1].story).toEqual('source1');
});
});
@@ -311,7 +330,12 @@ describe('ProjectBoard model', () => {
const sourceIndex = 0;
const destinationIndex = 1;
it('returns a new array', () => {
- newDestArray = ProjectBoard.moveStory(sourceArray, destinationArray, sourceIndex, destinationIndex);
+ newDestArray = ProjectBoard.moveStory(
+ sourceArray,
+ destinationArray,
+ sourceIndex,
+ destinationIndex
+ );
expect(newDestArray[1].story).toEqual('source1');
});
});
diff --git a/spec/javascripts/models/iteration_spec.js b/spec/javascripts/models/iteration_spec.js
index 1a309ddb2..41b9b727b 100644
--- a/spec/javascripts/models/iteration_spec.js
+++ b/spec/javascripts/models/iteration_spec.js
@@ -1,280 +1,326 @@
import Iteration from 'models/iteration';
-describe("iteration", function() {
+describe('iteration', function () {
let iteration;
- beforeEach(function() {
+ beforeEach(function () {
iteration = new Iteration({});
});
- describe("initialize", function() {
-
- it("should assign stories if passed", function() {
- var stories = [1,2,3];
- var iteration = new Iteration({'stories': stories});
+ describe('initialize', function () {
+ it('should assign stories if passed', function () {
+ var stories = [1, 2, 3];
+ var iteration = new Iteration({ stories: stories });
expect(iteration.get('stories')).toEqual(stories);
});
-
});
- describe("defaults", function() {
-
- it("should have an empty array of stories", function() {
+ describe('defaults', function () {
+ it('should have an empty array of stories', function () {
expect(iteration.get('stories')).toEqual([]);
});
-
});
- describe("points", function() {
+ describe('points', function () {
let stories;
- beforeEach(function() {
- var Story = Backbone.Model.extend({name: 'story'});
+ beforeEach(function () {
+ var Story = Backbone.Model.extend({ name: 'story' });
stories = [
- new Story({estimate: 2, story_type: 'feature'}),
- new Story({estimate: 3, story_type: 'feature', state: 'accepted'}),
- new Story({estimate: 3, story_type: 'bug', state: 'accepted'}) // Only features count
- // towards velocity
+ new Story({ estimate: 2, story_type: 'feature' }),
+ new Story({ estimate: 3, story_type: 'feature', state: 'accepted' }),
+ new Story({ estimate: 3, story_type: 'bug', state: 'accepted' }), // Only features count
+ // towards velocity
];
- iteration.set({stories: stories});
+ iteration.set({ stories: stories });
});
- it("should calculate its points", function() {
+ it('should calculate its points', function () {
expect(iteration.points()).toEqual(5);
});
- it("should return 0 for points if it has no stories", function() {
+ it('should return 0 for points if it has no stories', function () {
iteration.unset('stories');
expect(iteration.points()).toEqual(0);
});
- it("should report how many points it overflows by", function() {
+ it('should report how many points it overflows by', function () {
// Should return 0
- iteration.set({'maximum_points':2});
- var pointsStub = sinon.stub(iteration, 'points');
+ iteration.set({ maximum_points: 2 });
+ var pointsStub = vi.spyOn(iteration, 'points');
// Should return 0 if the iteration points are less than maximum_points
- pointsStub.returns(1);
+ pointsStub.mockReturnValueOnce(1);
expect(iteration.overflowsBy()).toEqual(0);
// Should return 0 if the iteration points are equal to maximum_points
- pointsStub.returns(2);
+ pointsStub.mockReturnValueOnce(2);
expect(iteration.overflowsBy()).toEqual(0);
// Should return the difference if iteration points are greater than
// maximum_points
- pointsStub.returns(5);
+ pointsStub.mockReturnValueOnce(5);
expect(iteration.overflowsBy()).toEqual(3);
});
- it("should report how many accepted points it has", function() {
+ it('should report how many accepted points it has', function () {
expect(iteration.acceptedPoints()).toEqual(3);
});
-
});
- describe("filling backlog iterations", function() {
-
- it("should return how many points are available", function() {
- var pointsStub = sinon.stub(iteration, "points");
- pointsStub.returns(3);
+ describe('filling backlog iterations', function () {
+ it('should return how many points are available', function () {
+ var pointsStub = vi.spyOn(iteration, 'points');
+ pointsStub.mockReturnValueOnce(3);
- iteration.set({'maximum_points': 5});
+ iteration.set({ maximum_points: 5 });
expect(iteration.availablePoints()).toEqual(2);
});
- it("should always accept chores bugs and releases", function() {
- var stub = sinon.stub();
- var story = {get: stub};
+ it('should always accept chores bugs and releases', function () {
+ var stub = vi.fn();
+ var story = { get: stub };
- stub.withArgs('story_type').returns('chore');
+ stub.mockImplementation(arg => {
+ if (arg === 'story_type') return 'chore';
+ });
expect(iteration.canTakeStory(story)).toBeTruthy();
- stub.withArgs('story_type').returns('bug');
+ stub.mockImplementation(arg => {
+ if (arg === 'story_type') return 'bug';
+ });
expect(iteration.canTakeStory(story)).toBeTruthy();
- stub.withArgs('story_type').returns('release');
+ stub.mockImplementation(arg => {
+ if (arg === 'story_type') return 'release';
+ });
expect(iteration.canTakeStory(story)).toBeTruthy();
});
- it("should not accept anything when isFull is true", function() {
- var stub = sinon.stub();
- var story = {get: stub};
+ it('should not accept anything when isFull is true', function () {
+ var stub = vi.fn();
+ var story = { get: stub };
iteration.isFull = true;
- stub.withArgs('story_type').returns('chore');
+ stub.mockImplementation(arg => {
+ if (arg === 'story_type') return 'chore';
+ });
expect(iteration.canTakeStory(story)).toBeFalsy();
- stub.withArgs('story_type').returns('bug');
+ stub.mockImplementation(arg => {
+ if (arg === 'story_type') return 'bug';
+ });
expect(iteration.canTakeStory(story)).toBeFalsy();
- stub.withArgs('story_type').returns('release');
+ stub.mockImplementation(arg => {
+ if (arg === 'story_type') return 'release';
+ });
expect(iteration.canTakeStory(story)).toBeFalsy();
});
- it("should accept a feature if there are enough free points", function() {
- var availablePointsStub = sinon.stub(iteration, "availablePoints");
- availablePointsStub.returns(3);
- var pointsStub = sinon.stub(iteration, 'points');
- pointsStub.returns(1);
+ it('should accept a feature if there are enough free points', () => {
+ vi.spyOn(iteration, 'availablePoints').mockReturnValueOnce(3);
+ vi.spyOn(iteration, 'points').mockReturnValueOnce(1);
- var stub = sinon.stub();
- var story = {get: stub};
+ var story = { get: vi.fn() };
- stub.withArgs('story_type').returns('feature');
- stub.withArgs('estimate').returns(3);
+ story.get.mockImplementationOnce(arg => {
+ switch (arg) {
+ case 'story_type':
+ return 'feature';
+ case 'estimate':
+ return 3;
+ }
+ });
expect(iteration.canTakeStory(story)).toBeTruthy();
+ });
+
+ it('should not accept a feature if there are enough free points', function () {
+ vi.spyOn(iteration, 'availablePoints').mockReturnValueOnce(3);
+ vi.spyOn(iteration, 'points').mockReturnValueOnce(1);
+
+ var story = { get: vi.fn() };
// Story is too big to fit in iteration
- stub.withArgs('estimate').returns(4);
+ story.get.mockImplementation(arg => {
+ switch (arg) {
+ case 'story_type':
+ return 'feature';
+ case 'estimate':
+ return 4;
+ }
+ });
+
expect(iteration.canTakeStory(story)).toBeFalsy();
});
// Each iteration should take at least one feature
- it("should always take at least one feature no matter how big", function() {
- var availablePointsStub = sinon.stub(iteration, "availablePoints");
- availablePointsStub.returns(1);
-
- var stub = sinon.stub();
- var story = {get: stub};
- stub.withArgs('story_type').returns('feature');
- stub.withArgs('estimate').returns(2);
+ it('should always take at least one feature no matter how big', function () {
+ var availablePointsStub = vi.spyOn(iteration, 'availablePoints');
+ availablePointsStub.mockReturnValueOnce(1);
+
+ var stub = vi.fn();
+ var story = { get: stub };
+ stub.mockImplementation(arg => {
+ switch (arg) {
+ case 'story_type':
+ return 'feature';
+ case 'estimate':
+ return 2;
+ }
+ });
expect(iteration.points()).toEqual(0);
expect(iteration.canTakeStory(story)).toBeTruthy();
});
-
-
});
- describe("isFull flag", function() {
-
- it("should default to false", function() {
+ describe('isFull flag', function () {
+ it('should default to false', function () {
expect(iteration.isFull).toEqual(false);
});
- it("should be set to true once canTakeStory has returned false", function() {
- var stub = sinon.stub();
- var story = {get: stub};
+ it('should be set to true once canTakeStory has returned false', function () {
+ var story = { get: vi.fn() };
- iteration.availablePoints = sinon.stub();
- iteration.availablePoints.returns(0);
- iteration.points = sinon.stub();
- iteration.points.returns(1);
+ vi.spyOn(iteration, 'availablePoints').mockReturnValueOnce(0);
+ vi.spyOn(iteration, 'points').mockReturnValueOnce(1);
- stub.withArgs('story_type').returns('feature');
- stub.withArgs('estimate').returns(1);
+ story.get.mockImplementation(arg => {
+ switch (arg) {
+ case 'story_type':
+ return 'feature';
+ case 'estimate':
+ return 1;
+ }
+ });
expect(iteration.isFull).toEqual(false);
expect(iteration.canTakeStory(story)).toBeFalsy();
expect(iteration.isFull).toEqual(true);
});
-
});
- describe("createMissingIterations", function() {
+ describe('createMissingIterations', function () {
let start;
- beforeEach(function() {
- start = new Iteration({'number': 1});
+ beforeEach(function () {
+ start = new Iteration({ number: 1 });
});
- it("should create a range of iterations", function() {
- var end = new Iteration({'number': 5});
+ it('should create a range of iterations', function () {
+ var end = new Iteration({ number: 5 });
var iterations = Iteration.createMissingIterations('#done', start, end);
expect(iterations.length).toEqual(3);
});
- it("should return an empty array when there is no gap between start and end", function() {
- var end = new Iteration({'number': 2});
+ it('should return an empty array when there is no gap between start and end', function () {
+ var end = new Iteration({ number: 2 });
var iterations = Iteration.createMissingIterations('#done', start, end);
expect(iterations.length).toEqual(0);
});
- it("should raise an exception if end number is less than or equal to start", function() {
- var end = new Iteration({'number': 1});
+ it('should raise an exception if end number is less than or equal to start', function () {
+ var end = new Iteration({ number: 1 });
var that = start;
- expect(function() {
+ expect(function () {
Iteration.createMissingIterations('#done', that, end);
- }).toThrow("end iteration number:1 must be greater than start iteration number:2");
+ }).toThrow(
+ 'end iteration number:1 must be greater than start iteration number:2'
+ );
});
- it("should return an empty array when start is undefined and end is number 1", function() {
- var end = new Iteration({'number': 1});
- var iterations = Iteration.createMissingIterations('#done', undefined, end);
+ it('should return an empty array when start is undefined and end is number 1', function () {
+ var end = new Iteration({ number: 1 });
+ var iterations = Iteration.createMissingIterations(
+ '#done',
+ undefined,
+ end
+ );
expect(iterations.length).toEqual(0);
});
- it("should return a range of iterations when start is undefined", function() {
- var end = new Iteration({'number': 5});
- var iterations = Iteration.createMissingIterations('#done', undefined, end);
+ it('should return a range of iterations when start is undefined', function () {
+ var end = new Iteration({ number: 5 });
+ var iterations = Iteration.createMissingIterations(
+ '#done',
+ undefined,
+ end
+ );
expect(iterations.length).toEqual(4);
expect(_.first(iterations).get('number')).toEqual(1);
});
- it("should return an empty array when start is undefined and end is number 1", function() {
- var end = new Iteration({'number': 1});
- var iterations = Iteration.createMissingIterations('#done', undefined, end);
+ it('should return an empty array when start is undefined and end is number 1', function () {
+ var end = new Iteration({ number: 1 });
+ var iterations = Iteration.createMissingIterations(
+ '#done',
+ undefined,
+ end
+ );
expect(iterations.length).toEqual(0);
});
- it("should return a range of iterations when start is undefined", function() {
- var end = new Iteration({'number': 5});
- var iterations = Iteration.createMissingIterations('#done', undefined, end);
+ it('should return a range of iterations when start is undefined', function () {
+ var end = new Iteration({ number: 5 });
+ var iterations = Iteration.createMissingIterations(
+ '#done',
+ undefined,
+ end
+ );
expect(iterations.length).toEqual(4);
expect(_.first(iterations).get('number')).toEqual(1);
});
-
});
- describe("startDate", function() {
-
- it("should return the start date", function() {
+ describe('startDate', function () {
+ it('should return the start date', function () {
var startDate = new Date('2011/09/26');
- var stub = sinon.stub();
- stub.returns(startDate);
+ var stub = vi.fn();
+ stub.mockReturnValueOnce(startDate);
iteration.project = { getDateForIterationNumber: stub };
expect(iteration.startDate()).toEqual(startDate);
expect(stub).toHaveBeenCalledWith(iteration.get('number'));
});
-
});
- describe("stories", function() {
+ describe('stories', function () {
let acceptedStory;
let finishedStory;
let unstartedStory;
- beforeEach(function() {
- var Story = Backbone.Model.extend({name: 'story'});
- acceptedStory = new Story({state: 'accepted'});
- finishedStory = new Story({state: 'finished'});
- unstartedStory = new Story({state: 'unstarted'});
- var stories = [
- unstartedStory, acceptedStory, finishedStory
- ];
- iteration.set({stories: stories});
+ beforeEach(function () {
+ var Story = Backbone.Model.extend({ name: 'story' });
+ acceptedStory = new Story({ state: 'accepted' });
+ finishedStory = new Story({ state: 'finished' });
+ unstartedStory = new Story({ state: 'unstarted' });
+ var stories = [unstartedStory, acceptedStory, finishedStory];
+ iteration.set({ stories: stories });
});
- it("returns the stories in the order they were added by default", function() {
+ it('returns the stories in the order they were added by default', function () {
expect(iteration.stories()).toEqual([
- unstartedStory, acceptedStory, finishedStory
+ unstartedStory,
+ acceptedStory,
+ finishedStory,
]);
});
- it("returns the stories accepted first if in progress iteration", function() {
- iteration.set({column:'#in_progress'});
+ it('returns the stories accepted first if in progress iteration', function () {
+ iteration.set({ column: '#in_progress' });
var stories = iteration.stories();
expect(stories.length).toEqual(3);
expect(stories[0]).toEqual(acceptedStory);
});
- it("returns stories with a given state", function() {
+ it('returns stories with a given state', function () {
expect(iteration.storiesWithState('accepted')).toEqual([acceptedStory]);
});
- it("returns stories except a given state", function() {
- expect(iteration.storiesExceptState('accepted')).toEqual([unstartedStory, finishedStory]);
+ it('returns stories except a given state', function () {
+ expect(iteration.storiesExceptState('accepted')).toEqual([
+ unstartedStory,
+ finishedStory,
+ ]);
});
});
-
});
diff --git a/spec/javascripts/models/note_spec.js b/spec/javascripts/models/note_spec.js
index cc8593282..c7e5bab92 100644
--- a/spec/javascripts/models/note_spec.js
+++ b/spec/javascripts/models/note_spec.js
@@ -1,63 +1,63 @@
import Note from 'models/note';
-describe("Note", function() {
+describe('Note', function () {
let note;
- beforeEach(function() {
+ beforeEach(function () {
note = new Note({});
});
- describe("user", function() {
+ describe('user', function () {
let project;
let usersCollectionStub;
- beforeEach(function() {
- project = {users: {get: usersCollectionStub}};
- note.set({user_id: 999, user_name: 'John Doe'});
- note.collection = {story: {collection: {project: project}}};
+ beforeEach(function () {
+ project = { users: { get: usersCollectionStub } };
+ note.set({ user_id: 999, user_name: 'John Doe' });
+ note.collection = { story: { collection: { project: project } } };
});
- it("returns the name of the user", function() {
+ it('returns the name of the user', function () {
expect(note.get('user_name')).toEqual('John Doe');
});
-
});
- describe("errors", function() {
-
- it("should record errors", function() {
+ describe('errors', function () {
+ it('should record errors', function () {
expect(note.hasErrors()).toBeFalsy();
expect(note.errorsOn('note')).toBeFalsy();
- note.set({errors: {
- note: ["cannot be blank", "needs to be better"]
- }});
+ note.set({
+ errors: {
+ note: ['cannot be blank', 'needs to be better'],
+ },
+ });
expect(note.hasErrors()).toBeTruthy();
expect(note.errorsOn('note')).toBeTruthy();
- expect(note.errorMessages())
- .toEqual("note cannot be blank, note needs to be better");
+ expect(note.errorMessages()).toEqual(
+ 'note cannot be blank, note needs to be better'
+ );
});
-
});
- describe('humanAttributeName', function() {
-
- beforeEach(function() {
- sinon.stub(I18n, 't');
- I18n.t.withArgs('foo_bar').returns('Foo bar');
+ describe('humanAttributeName', function () {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't').mockImplementation(arg => {
+ if (arg === 'foo_bar') return 'Foo bar';
+ });
});
- afterEach(function() {
- I18n.t.restore();
+ afterEach(function () {
+ I18n.t.mockRestore();
});
- it("returns the translated attribute name", function() {
+ it('returns the translated attribute name', function () {
expect(note.humanAttributeName('foo_bar')).toEqual('Foo bar');
});
- it("strips of the id suffix", function() {
+ it('strips of the id suffix', function () {
expect(note.humanAttributeName('foo_bar_id')).toEqual('Foo bar');
});
});
diff --git a/spec/javascripts/models/past_iteration_spec.js b/spec/javascripts/models/past_iteration_spec.js
index cef13f7f6..637111766 100644
--- a/spec/javascripts/models/past_iteration_spec.js
+++ b/spec/javascripts/models/past_iteration_spec.js
@@ -1,100 +1,92 @@
import Cookies from 'js-cookie';
import Project from 'models/project';
import PastIteration from 'models/pastIteration';
+import { server } from '../mocks/server';
+import { http, HttpResponse } from 'msw';
-describe('PastIteration model', function() {
+describe('PastIteration model', function () {
let project;
let pastIterations;
- beforeEach(function() {
- Cookies.set('current_flow', 'progress_to_left', {expires: 365});
+ beforeEach(function () {
+ Cookies.set('current_flow', 'progress_to_left', { expires: 365 });
project = new Project({
- id: 1337, title: 'Test project', point_values: [0, 1, 2, 3],
- last_changeset_id: null, iteration_start_day: 1, iteration_length: 1,
+ id: 1337,
+ title: 'Test project',
+ point_values: [0, 1, 2, 3],
+ last_changeset_id: null,
+ iteration_start_day: 1,
+ iteration_length: 1,
default_flow: Cookies.get('current_flow'),
- current_flow: Cookies.get('current_flow')
+ current_flow: Cookies.get('current_flow'),
});
pastIterations = new PastIteration({
- project: project,
- startDate: Date.now(),
- endDate: Date.now() + 7,
- points: 3,
- iterationNumber: 2
+ project: project,
+ startDate: Date.now(),
+ endDate: Date.now() + 7,
+ points: 3,
+ iterationNumber: 2,
});
});
- describe('when instantiated', function() {
-
- it("should exhibit attributes", function() {
+ describe('when instantiated', function () {
+ it('should exhibit attributes', function () {
expect(pastIterations.get('number')).toEqual(2);
});
- it("should have a default load state", function() {
+ it('should have a default load state', function () {
expect(pastIterations.get('needsLoad')).toBe(true);
});
- it("should have a default column", function() {
+ it('should have a default column', function () {
expect(pastIterations.get('column')).toBe('#done');
});
});
- describe('stories', function() {
-
- it('should return the models stories', function() {
+ describe('stories', function () {
+ it('should return the models stories', function () {
expect(pastIterations.stories()).toEqual(pastIterations._stories);
});
-
});
- describe('startDate', function() {
-
- it('should return the models start date', function() {
+ describe('startDate', function () {
+ it('should return the models start date', function () {
expect(pastIterations.startDate()).toEqual(pastIterations._startDate);
});
-
});
- describe('endDate', function() {
-
- it('should return the models end date', function() {
+ describe('endDate', function () {
+ it('should return the models end date', function () {
expect(pastIterations.endDate()).toEqual(pastIterations._endDate);
});
-
});
- describe('points', function() {
-
- it('should return the model points', function() {
+ describe('points', function () {
+ it('should return the model points', function () {
expect(pastIterations.points()).toEqual(pastIterations._points);
});
-
});
- describe('fetch', function() {
-
- it('should update the stories from the iteration', function(done) {
- var story = [ { story:{id:42,title:"Test story"} } ];
- var stories = { stories:story }
- var server = sinon.fakeServer.create();
-
- server.respondImmediately = true;
- server.respondWith(
- "GET", /\/project_boards\/1337\/iterations(.*)/, [
- 200, {"Content-Type": "application/json"},
- JSON.stringify(stories)
- ]
+ describe('fetch', function () {
+ it('should update the stories from the iteration', function (done) {
+ var story = [{ story: { id: 42, title: 'Test story' } }];
+ var stories = { stories: story };
+ server.use(
+ http.get(/\/project_boards\/1337\/iterations(.*)/, () => {
+ return HttpResponse.json(stories), { status: 200 };
+ })
);
var initialStoriesLength = pastIterations._stories.length;
- pastIterations.fetch()
- .then(() => {
- expect(pastIterations._stories.length).toEqual(initialStoriesLength + 1);
- done();
- });
+ pastIterations.fetch().then(() => {
+ expect(pastIterations._stories.length).toEqual(
+ initialStoriesLength + 1
+ );
+ done();
+ });
});
});
-
});
diff --git a/spec/javascripts/models/project_board_spec.js b/spec/javascripts/models/project_board_spec.js
index b42c6f787..1db2a59bf 100644
--- a/spec/javascripts/models/project_board_spec.js
+++ b/spec/javascripts/models/project_board_spec.js
@@ -1,67 +1,79 @@
import Cookies from 'js-cookie';
import Project from 'models/project';
import ProjectBoard from 'models/projectBoard';
+import { server } from '../mocks/server';
+import { http, HttpResponse } from 'msw';
-describe('ProjectBoard model', function() {
+describe('ProjectBoard model', function () {
let project;
let projectBoard;
- beforeEach(function() {
- Cookies.set('current_flow', 'progress_to_left', {expires: 365});
+ beforeEach(function () {
+ Cookies.set('current_flow', 'progress_to_left', { expires: 365 });
project = new Project({
- id: 1337, title: 'Test project', point_values: [0, 1, 2, 3],
- last_changeset_id: null, iteration_start_day: 1, iteration_length: 1,
+ id: 1337,
+ title: 'Test project',
+ point_values: [0, 1, 2, 3],
+ last_changeset_id: null,
+ iteration_start_day: 1,
+ iteration_length: 1,
default_flow: Cookies.get('current_flow'),
- current_flow: Cookies.get('current_flow')
+ current_flow: Cookies.get('current_flow'),
});
- projectBoard = new ProjectBoard({project: project});
+ projectBoard = new ProjectBoard({ project: project });
});
- describe('when instantiated', function() {
-
- it('should set up a story collection', function() {
+ describe('when instantiated', function () {
+ it('should set up a story collection', function () {
expect(projectBoard.stories).toBeDefined();
});
- it('should have a project', function() {
+ it('should have a project', function () {
expect(projectBoard.project).toBe(project);
expect(projectBoard.stories.project).toBe(project);
});
- it("should have a default past iterations empty array", function() {
+ it('should have a default past iterations empty array', function () {
expect(projectBoard.pastIterations).toEqual([]);
});
-
});
- describe('fetch', function() {
-
- it('should update the past iterations and stories of the project board', function(done) {
- var activeStories = [{story:{id:42,title:"Active story"}}];
- var pastIterations = [{start_date:"2018/03/19",end_date:"2018/03/25",points:3,iteration_number:2}];
- var dataHash = {active_stories: activeStories, past_iterations: pastIterations}
- var server = sinon.fakeServer.create();
- server.respondImmediately = true;
- server.respondWith(
- "GET", "/project_boards/1337", [
- 200, {"Content-Type": "application/json"},
- JSON.stringify(dataHash)
- ]
+ describe('fetch', function () {
+ it('should update the past iterations and stories of the project board', function (done) {
+ var activeStories = [{ story: { id: 42, title: 'Active story' } }];
+ var pastIterations = [
+ {
+ start_date: '2018/03/19',
+ end_date: '2018/03/25',
+ points: 3,
+ iteration_number: 2,
+ },
+ ];
+ var dataHash = {
+ active_stories: activeStories,
+ past_iterations: pastIterations,
+ };
+ server.use(
+ http.get('/project_boards/1337', () => {
+ return HttpResponse.json(dataHash), { status: 200 };
+ })
);
var initialPastIterationsLength = projectBoard.pastIterations.length;
- var initialActiveStoriesLength = projectBoard.stories.length
+ var initialActiveStoriesLength = projectBoard.stories.length;
- projectBoard.fetch()
- .then(() => {
- expect(projectBoard.pastIterations.length).toEqual(initialPastIterationsLength + 1);
- expect(projectBoard.stories.length).toEqual(initialActiveStoriesLength + 1);
- done();
- });
+ projectBoard.fetch().then(() => {
+ expect(projectBoard.pastIterations.length).toEqual(
+ initialPastIterationsLength + 1
+ );
+ expect(projectBoard.stories.length).toEqual(
+ initialActiveStoriesLength + 1
+ );
+ done();
+ });
});
});
-
});
diff --git a/spec/javascripts/models/project_spec.js b/spec/javascripts/models/project_spec.js
index 9c22763c8..f960c3916 100644
--- a/spec/javascripts/models/project_spec.js
+++ b/spec/javascripts/models/project_spec.js
@@ -1,256 +1,283 @@
import Cookies from 'js-cookie';
import Project from 'models/project';
import Iteration from 'models/iteration';
+import { server } from '../mocks/server';
+import { http, HttpResponse } from 'msw';
+import { afterEach } from 'vitest';
-describe('Project model', function() {
+describe('Project model', function () {
let story;
let project;
- beforeEach(function() {
- Cookies.set('current_flow', 'progress_to_left', {expires: 365});
+ beforeAll(() => {
+ server.listen({
+ onUnhandledRequest: 'error',
+ });
+ });
+
+ afterAll(() => {
+ server.close();
+ });
+
+ beforeEach(function () {
+ Cookies.set('current_flow', 'progress_to_left', { expires: 365 });
var Story = Backbone.Model.extend({
name: 'story',
- fetch: function() {},
- position: function() {},
- labels: function() { return []; }
+ fetch: function () {},
+ position: function () {},
+ labels: function () {
+ return [];
+ },
});
- story = new Story({id: 456});
+ story = new Story({ id: 456 });
project = new Project({
- id: 999, title: 'Test project', point_values: [0, 1, 2, 3],
- last_changeset_id: null, iteration_start_day: 1, iteration_length: 1,
+ id: 999,
+ title: 'Test project',
+ point_values: [0, 1, 2, 3],
+ last_changeset_id: null,
+ iteration_start_day: 1,
+ iteration_length: 1,
default_flow: Cookies.get('current_flow'),
- current_flow: Cookies.get('current_flow')
+ current_flow: Cookies.get('current_flow'),
});
project.projectBoard.stories.add(story);
});
- describe('when instantiated', function() {
+ afterEach(() => {
+ server.resetHandlers();
+ });
- it('should exhibit attributes', function() {
- expect(project.get('point_values'))
- .toEqual([0, 1, 2, 3]);
+ describe('when instantiated', function () {
+ it('should exhibit attributes', function () {
+ expect(project.get('point_values')).toEqual([0, 1, 2, 3]);
});
- it('should set up a story collection', function() {
+ it('should set up a story collection', function () {
expect(project.projectBoard.stories).toBeDefined();
expect(project.projectBoard.stories.url).toEqual('/projects/999/stories');
// Sets up a reference on the collection to itself
expect(project.projectBoard.project).toBe(project);
});
- it('should set up a user collection', function() {
+ it('should set up a user collection', function () {
expect(project.users).toBeDefined();
expect(project.users.url).toEqual('/projects/999/users');
// Sets up a reference on the collection to itself
expect(project.users.project).toBe(project);
});
- it("should have a default velocity of 10", function() {
+ it('should have a default velocity of 10', function () {
expect(project.get('default_velocity')).toEqual(10);
});
- it("should have a default story flow", function() {
+ it('should have a default story flow', function () {
expect(project.get('default_flow')).toEqual('progress_to_left');
});
-
});
- describe('url', function() {
-
- it('should have a url', function() {
+ describe('url', function () {
+ it('should have a url', function () {
expect(project.url()).toEqual('/projects/999');
});
-
});
- describe('changesets', function() {
-
- it('should load changesets when last_changeset_id is changed', function() {
- var server = sinon.fakeServer.create();
- var spy = sinon.spy(project, 'handleChangesets');
- var changesets = [{"changeset":{"id":2,"story_id":456,"project_id":789}}];
- server.respondWith(
- "GET", "/projects/999/changesets?from=0&to=2", [
- 200, {"Content-Type": "application/json"},
- JSON.stringify(changesets)
- ]
- );
-
- expect(project.get('last_changeset_id')).toBeNull();
- project.set({last_changeset_id: 2});
-
- expect(server.requests.length).toEqual(1);
+ describe('changesets', function () {
+ it('should load changesets when last_changeset_id is changed', function () {
+ var changesets = [
+ { changeset: { id: 2, story_id: 456, project_id: 789 } },
+ ];
- server.respond();
+ vi.spyOn(project, 'handleChangesets').mockImplementation(arg => {
+ expect(arg).toStrictEqual(changesets);
+ });
- expect(spy).toHaveBeenCalledWith(changesets);
+ server.use(
+ http.get('/projects/999/changesets', () => {
+ return HttpResponse.json(changesets, { status: 200 });
+ })
+ );
- server.restore();
+ expect(project.get('last_changeset_id')).toBeNull();
+ project.set({ last_changeset_id: 2 });
});
- it("should reload changed stories from changesets", function() {
-
- var changesets = [{"changeset":{"id":123,"story_id":456,"project_id":789}}];
- var getSpy = sinon.spy(project.projectBoard.stories, 'get');
- var fetchSpy = sinon.spy(story, 'fetch');
+ it('should reload changed stories from changesets', function () {
+ var changesets = [
+ { changeset: { id: 123, story_id: 456, project_id: 789 } },
+ ];
+ var getSpy = vi.spyOn(project.projectBoard.stories, 'get');
+ var fetchSpy = vi.spyOn(story, 'fetch');
project.handleChangesets(changesets);
expect(getSpy).toHaveBeenCalledWith(456);
expect(fetchSpy).toHaveBeenCalled();
-
});
- it("should load new stories from changesets", function() {
-
- var story_json = {"story":{"id":987,"title":"New changeset story"}};
- var server = sinon.fakeServer.create();
- server.respondWith(
- "GET", "/projects/999/stories/987", [
- 200, {"Content-Type": "application/json"},
- JSON.stringify(story_json)
- ]
+ it('should load new stories from changesets', function () {
+ var story_json = { story: { id: 123 } };
+ server.use(
+ http.get('/projects/999/stories/123', () => {
+ return HttpResponse.json(story_json, { status: 200 });
+ })
);
- var changesets = [{"changeset":{"id":123,"story_id":987,"project_id":789}}];
- var getSpy = sinon.spy(project.projectBoard.stories, 'get');
- var addSpy = sinon.spy(project.projectBoard.stories, 'add');
+ var changesets = [
+ { changeset: { id: 123, story_id: 123, project_id: 987 } },
+ ];
+ var getSpy = vi.spyOn(project.projectBoard.stories, 'get');
+ var addSpy = vi.spyOn(project.projectBoard.stories, 'add');
var initial_collection_length = project.projectBoard.stories.length;
project.handleChangesets(changesets);
- expect(server.requests.length).toEqual(1);
- server.respond();
-
expect(getSpy).toHaveBeenCalled();
expect(addSpy).toHaveBeenCalled();
- expect(project.projectBoard.stories.length).toEqual(initial_collection_length + 1);
- expect(project.projectBoard.stories.get(987).get('title')).toEqual("New changeset story");
-
- server.restore();
+ expect(project.projectBoard.stories.length).toEqual(
+ initial_collection_length + 1
+ );
});
-
- it("should only reload a story once if present in multiple changesets", function() {
-
- var story_json = {"story":{"id":987,"title":"New changeset story"}};
- var server = sinon.fakeServer.create();
- server.respondWith(
- "GET", "/projects/999/stories/987", [
- 200, {"Content-Type": "application/json"},
- JSON.stringify(story_json)
- ]
+ it('should only reload a story once if present in multiple changesets', function () {
+ var story_json = { story: { id: 987, title: 'New changeset story' } };
+ server.use(
+ http.get('/projects/999/stories/987', () => {
+ return HttpResponse.json(story_json, { status: 200 });
+ })
);
+ const spy = vi.spyOn(project, 'handleChangesets');
+
// set of changes represents the same story modified twice. It
// should only be loaded once.
var changesets = [
- {"changeset":{"id":1,"story_id":987,"project_id":789}},
- {"changeset":{"id":2,"story_id":987,"project_id":789}}
+ { changeset: { id: 1, story_id: 987, project_id: 789 } },
+ { changeset: { id: 2, story_id: 987, project_id: 789 } },
];
project.handleChangesets(changesets);
- expect(server.requests.length).toEqual(1);
+ expect(spy).toHaveBeenCalledTimes(1);
});
});
-
- describe("iterations", function() {
-
- it("should get the right iteration number for a given date", function() {
+ describe('iterations', function () {
+ it('should get the right iteration number for a given date', function () {
// is a Monday
- project.set({start_date: "2011/07/25"});
+ project.set({ start_date: '2011/07/25' });
- var compare_date = new Date("2011/07/25");
+ var compare_date = new Date('2011/07/25');
expect(project.getIterationNumberForDate(compare_date)).toEqual(1);
- compare_date = new Date("2011/08/01");
+ compare_date = new Date('2011/08/01');
expect(project.getIterationNumberForDate(compare_date)).toEqual(2);
// With a 2 week iteration length, the date above will still be in
// iteration 1
- project.set({iteration_length: 2});
+ project.set({ iteration_length: 2 });
expect(project.getIterationNumberForDate(compare_date)).toEqual(1);
});
- it("should return the current iteration number", function() {
+ it('should return the current iteration number', function () {
expect(project.currentIterationNumber()).toEqual(1);
});
- it("should return the date for an iteration number", function() {
-
+ it('should return the date for an iteration number', function () {
// is a Monday
- project.set({start_date: "2011/07/25"});
+ project.set({ start_date: '2011/07/25' });
- expect(project.getDateForIterationNumber(1)).toEqual(new Date("2011/07/25"));
- expect(project.getDateForIterationNumber(5)).toEqual(new Date("2011/08/22"));
+ expect(project.getDateForIterationNumber(1)).toEqual(
+ new Date('2011/07/25')
+ );
+ expect(project.getDateForIterationNumber(5)).toEqual(
+ new Date('2011/08/22')
+ );
- project.set({iteration_length: 4});
- expect(project.getDateForIterationNumber(1)).toEqual(new Date("2011/07/25"));
- expect(project.getDateForIterationNumber(5)).toEqual(new Date("2011/11/14"));
+ project.set({ iteration_length: 4 });
+ expect(project.getDateForIterationNumber(1)).toEqual(
+ new Date('2011/07/25')
+ );
+ expect(project.getDateForIterationNumber(5)).toEqual(
+ new Date('2011/11/14')
+ );
// Sunday
- project.set({iteration_start_day: 0});
- expect(project.getDateForIterationNumber(1)).toEqual(new Date("2011/07/24"));
- expect(project.getDateForIterationNumber(5)).toEqual(new Date("2011/11/13"));
+ project.set({ iteration_start_day: 0 });
+ expect(project.getDateForIterationNumber(1)).toEqual(
+ new Date('2011/07/24')
+ );
+ expect(project.getDateForIterationNumber(5)).toEqual(
+ new Date('2011/11/13')
+ );
// Tuesday - should evaluate to the Tuesday before the explicitly
// set start date (Monday)
- project.set({iteration_start_day: 2});
- expect(project.getDateForIterationNumber(1)).toEqual(new Date("2011/07/19"));
- expect(project.getDateForIterationNumber(5)).toEqual(new Date("2011/11/08"));
+ project.set({ iteration_start_day: 2 });
+ expect(project.getDateForIterationNumber(1)).toEqual(
+ new Date('2011/07/19')
+ );
+ expect(project.getDateForIterationNumber(5)).toEqual(
+ new Date('2011/11/08')
+ );
});
- it("should initialize with an array of iterations", function() {
+ it('should initialize with an array of iterations', function () {
expect(project.iterations).toEqual([]);
});
- it("should get all the done iterations", function() {
+ it('should get all the done iterations', function () {
var doneIteration = {
- get: sinon.stub().withArgs('column').returns('#done')
+ get: vi.fn().mockImplementation(arg => {
+ if (arg === 'column') return '#done';
+ }),
};
var inProgressIteration = {
- get: sinon.stub().withArgs('column').returns('#in_progress')
+ get: vi.fn().mockImplementation(arg => {
+ if (arg === 'column') return '#in_progress';
+ }),
};
var backlogIteration = {
- get: sinon.stub().withArgs('column').returns('#backlog')
+ get: vi.fn().mockImplementation(arg => {
+ if (arg === 'column') return '#backlong';
+ }),
};
var chillyBinIteration = {
- get: sinon.stub().withArgs('column').returns('#chilly_bin')
+ get: vi.fn().mockImplementation(arg => {
+ if (arg === 'column') return '#chilly_bin';
+ }),
};
project.iterations = [
- doneIteration, inProgressIteration, backlogIteration, chillyBinIteration
+ doneIteration,
+ inProgressIteration,
+ backlogIteration,
+ chillyBinIteration,
];
expect(project.doneIterations()).toEqual([doneIteration]);
});
-
});
-
- describe("start date", function() {
-
- it("should return the start date", function() {
+ describe('start date', function () {
+ it('should return the start date', function () {
// Date is a Monday, and day 1 is Monday
- project.set({start_date: "2011/09/12",iteration_start_day: 1});
- expect(project.startDate()).toEqual(new Date("2011/09/12"));
+ project.set({ start_date: '2011/09/12', iteration_start_day: 1 });
+ expect(project.startDate()).toEqual(new Date('2011/09/12'));
// If the project start date has been explicitly set to a Thursday, but
// the iteration_start_day is Monday, the start date should be the Monday
// that immeadiatly preceeds the Thursday.
- project.set({start_date: "2011/07/28"});
- expect(project.startDate()).toEqual(new Date("2011/07/25"));
+ project.set({ start_date: '2011/07/28' });
+ expect(project.startDate()).toEqual(new Date('2011/07/25'));
// The same, but time the iteration start day is 'after' the start
// date day, in ordinal terms, e.g. iteration start date is a Saturday,
// project start date is a Thursday. The Saturday prior to the Thursday
// should be returned.
- project.set({iteration_start_day: 6});
- expect(project.startDate()).toEqual(new Date("2011/07/23"));
+ project.set({ iteration_start_day: 6 });
+ expect(project.startDate()).toEqual(new Date('2011/07/23'));
// If the project start date is not set, it should be considered as the
// first iteration start day prior to today.
@@ -259,259 +286,285 @@ describe('Project model', function() {
var fake_today = new Date('2011/07/29');
// Stop JSHINT complaining about overriding Date
/*global Date: true*/
- project.today = sinon.stub().returns(fake_today);
+ project.today = vi.fn().mockReturnValueOnce(fake_today);
project.unset('start_date');
expect(project.startDate()).toEqual(expected_date);
});
});
- describe("velocity", function() {
-
- it("returns the default velocity when done iterations are empty", function() {
- project.set({'default_velocity': 999});
+ describe('velocity', function () {
+ it('returns the default velocity when done iterations are empty', function () {
+ project.set({ default_velocity: 999 });
expect(project.velocity()).toEqual(999);
});
- it("should return velocity", function() {
- var doneIterations = _.map([1,2,3,4,5], function(i) {
- return {points: sinon.stub().returns(i)};
+ it('should return velocity', function () {
+ var doneIterations = _.map([1, 2, 3, 4, 5], function (i) {
+ return { points: vi.fn().mockReturnValueOnce(i) };
});
- var doneIterationsStub = sinon.stub(project, 'doneIterations');
- doneIterationsStub.returns(doneIterations);
+ vi.spyOn(project, 'doneIterations').mockImplementation(
+ () => doneIterations
+ );
// By default, should take the average of the last 3 iterations,
// (3 + 4 + 5) = 12 / 3 = 4
expect(project.velocity()).toEqual(4);
});
- it("should ignore zero points done iterations while calculating velocity", function() {
- var doneIterations = _.map([1,2,0,4,5], function(i) {
- return {points: sinon.stub().returns(i)};
+ it('should ignore zero points done iterations while calculating velocity', function () {
+ var doneIterations = _.map([1, 2, 0, 4, 5], function (i) {
+ return { points: vi.fn().mockReturnValueOnce(i) };
});
- var doneIterationsStub = sinon.stub(project, 'doneIterations');
- doneIterationsStub.returns(doneIterations);
+ vi.spyOn(project, 'doneIterations').mockImplementation(
+ () => doneIterations
+ );
// By default, should take the average of the last 3 iterations,
// (2 + 4 + 5) = 11 / 3 = 5
expect(project.velocity()).toEqual(3);
});
- it("should floor the velocity when it returns a fraction", function() {
- var doneIterations = _.map([3,2,2], function(i) {
- return {points: sinon.stub().returns(i)};
+ it('should floor the velocity when it returns a fraction', function () {
+ var doneIterations = _.map([3, 2, 2], function (i) {
+ return { points: vi.fn().mockReturnValueOnce(i) };
});
- var doneIterationsStub = sinon.stub(project, 'doneIterations');
- doneIterationsStub.returns(doneIterations);
+ vi.spyOn(project, 'doneIterations').mockImplementation(
+ () => doneIterations
+ );
// Should floor the result
// (3 + 2 + 2) = 7 / 3 = 2.333333
expect(project.velocity()).toEqual(2);
});
- it("should return the velocity when few iterations are complete", function() {
+ it('should return the velocity when few iterations are complete', function () {
// Still calculate the average correctly if fewer than the expected
// number of iterations have been completed.
- var doneIterations = _.map([3,1], function(i) {
- return {points: sinon.stub().returns(i)};
+ var doneIterations = _.map([3, 1], function (i) {
+ return { points: vi.fn().mockReturnValueOnce(i) };
});
- var doneIterationsStub = sinon.stub(project, 'doneIterations');
- doneIterationsStub.returns(doneIterations);
+
+ vi.spyOn(project, 'doneIterations').mockImplementation(
+ () => doneIterations
+ );
expect(project.velocity()).toEqual(2);
});
- it("should not return less than 1", function() {
- var doneIterations = _.map([0,0,0], function(i) {
- return {points: sinon.stub().returns(i)};
+ it('should not return less than 1', function () {
+ var doneIterations = _.map([0, 0, 0], function (i) {
+ return { points: vi.fn().mockReturnValueOnce(i) };
});
- var doneIterationsStub = sinon.stub(project, 'doneIterations');
- doneIterationsStub.returns(doneIterations);
+ vi.spyOn(project, 'doneIterations').mockImplementation(
+ () => doneIterations
+ );
expect(project.velocity()).toEqual(1);
});
- describe("when velocity is not set", function() {
- describe("velocityIsFake", function() {
- it("should be false", function() {
+ describe('when velocity is not set', function () {
+ describe('velocityIsFake', function () {
+ it('should be false', function () {
expect(project.velocityIsFake()).toBeFalsy();
});
});
- it("returns the default velocity", function() {
- project.set({'default_velocity': 99});
- expect(project.velocity()).toEqual(99);
+ it('returns the default velocity', function () {
+ project.set({ default_velocity: 99 });
+ expect(project.velocity()).toEqual(99);
});
});
- describe("when velocity is set to 20", function() {
-
- beforeEach(function() {
+ describe('when velocity is set to 20', function () {
+ beforeEach(function () {
project.velocity(20);
});
- describe("velocityIsFake", function() {
- it("should be true", function() {
+ describe('velocityIsFake', function () {
+ it('should be true', function () {
expect(project.velocityIsFake()).toBeTruthy();
});
});
- it("returns 20", function() {
- expect(project.velocity()).toEqual(20);
+ it('returns 20', function () {
+ expect(project.velocity()).toEqual(20);
});
});
- describe("when velocity is set to less than 1", function() {
-
- beforeEach(function() {
+ describe('when velocity is set to less than 1', function () {
+ beforeEach(function () {
project.velocity(0);
});
- it("sets the velocity to 1", function() {
+ it('sets the velocity to 1', function () {
expect(project.velocity()).toEqual(1);
});
-
});
- describe("when velocity is set to the same as the real value", function() {
-
- describe("velocity", function() {
- beforeEach(function() {
- project.set({'userVelocity': 20, velocityIsFake: true});
- project.calculateVelocity = function() { return 20; };
+ describe('when velocity is set to the same as the real value', function () {
+ describe('velocity', function () {
+ beforeEach(function () {
+ project.set({ userVelocity: 20, velocityIsFake: true });
+ project.calculateVelocity = function () {
+ return 20;
+ };
project.velocity(20);
});
- it("should unset userVelocity", function() {
+ it('should unset userVelocity', function () {
expect(project.get('userVelocity')).toBeUndefined();
});
- it("should be false", function() {
+ it('should be false', function () {
expect(project.velocityIsFake()).toBeFalsy();
});
});
});
- describe("revertVelocity", function() {
-
- beforeEach(function() {
- project.set({userVelocity: 999, velocityIsFake: true});
+ describe('revertVelocity', function () {
+ beforeEach(function () {
+ project.set({ userVelocity: 999, velocityIsFake: true });
});
- it("unsets userVelocity", function() {
+ it('unsets userVelocity', function () {
project.revertVelocity();
expect(project.get('userVelocity')).toBeUndefined();
});
- it("sets velocityIsFake to false", function() {
+ it('sets velocityIsFake to false', function () {
project.revertVelocity();
expect(project.velocityIsFake()).toBeFalsy();
});
});
-
});
-
- describe("appendIteration", function() {
+ describe('appendIteration', function () {
let iteration;
- beforeEach(function() {
+ beforeEach(function () {
iteration = {
- get: sinon.stub()
+ get: vi.fn(),
};
});
- it("should add the first iteration to the array", function() {
- var stub = sinon.stub(Iteration, 'createMissingIterations');
- stub.returns([]);
+ it('should add the first iteration to the array', function () {
+ var stub = vi.spyOn(Iteration, 'createMissingIterations');
+ stub.mockReturnValueOnce([]);
project.appendIteration(iteration);
expect(_.last(project.iterations)).toEqual(iteration);
expect(project.iterations.length).toEqual(1);
- stub.restore();
+ stub.mockRestore();
});
- it("should create missing iterations if required", function() {
- var spy = sinon.spy(Iteration, 'createMissingIterations');
- iteration.get.withArgs('number').returns(1);
+ it('should create missing iterations if required', function () {
+ var spy = vi.spyOn(Iteration, 'createMissingIterations');
+ vi.spyOn(iteration, 'get').mockImplementation(arg => {
+ if (arg === 'number') return 1;
+ });
project.iterations.push(iteration);
var currentIteration = {
- get: sinon.stub().withArgs('number').returns(5)
+ get: vi.fn().mockImplementation(arg => {
+ if (arg === 'number') return 5;
+ }),
};
project.appendIteration(currentIteration, '#done');
expect(spy).toHaveBeenCalledWith('#done', iteration, currentIteration);
expect(project.iterations.length).toEqual(5);
- spy.restore();
});
-
});
- describe("columns", function() {
-
- it("should define the columns", function() {
+ describe('columns', function () {
+ it('should define the columns', function () {
expect(project.columnIds).toEqual([
- '#done', '#in_progress', '#backlog', '#chilly_bin', '#search_results', '#epic'
+ '#done',
+ '#in_progress',
+ '#backlog',
+ '#chilly_bin',
+ '#search_results',
+ '#epic',
]);
});
- it("should return the columns after a given column", function() {
+ it('should return the columns after a given column', function () {
expect(project.columnsAfter('#done')).toEqual([
- '#in_progress', '#backlog', '#chilly_bin', '#search_results', '#epic'
+ '#in_progress',
+ '#backlog',
+ '#chilly_bin',
+ '#search_results',
+ '#epic',
]);
expect(project.columnsAfter('#in_progress')).toEqual([
- '#backlog', '#chilly_bin', '#search_results', '#epic'
+ '#backlog',
+ '#chilly_bin',
+ '#search_results',
+ '#epic',
+ ]);
+ expect(project.columnsAfter('#backlog')).toEqual([
+ '#chilly_bin',
+ '#search_results',
+ '#epic',
+ ]);
+ expect(project.columnsAfter('#chilly_bin')).toEqual([
+ '#search_results',
+ '#epic',
]);
- expect(project.columnsAfter('#backlog')).toEqual(['#chilly_bin', '#search_results', '#epic']);
- expect(project.columnsAfter('#chilly_bin')).toEqual(['#search_results', '#epic']);
var currentProject = project;
- expect(function() {currentProject.columnsAfter('#foobar');}).toThrow(
- "#foobar is not a valid column"
- );
+ expect(function () {
+ currentProject.columnsAfter('#foobar');
+ }).toThrow('#foobar is not a valid column');
});
- it("should return the columns before a given column", function() {
+ it('should return the columns before a given column', function () {
expect(project.columnsBefore('#done')).toEqual([]);
expect(project.columnsBefore('#in_progress')).toEqual(['#done']);
expect(project.columnsBefore('#backlog')).toEqual([
- '#done', '#in_progress'
+ '#done',
+ '#in_progress',
]);
expect(project.columnsBefore('#chilly_bin')).toEqual([
- '#done', '#in_progress', '#backlog'
+ '#done',
+ '#in_progress',
+ '#backlog',
]);
expect(project.columnsBefore('#search_results')).toEqual([
- '#done', '#in_progress', '#backlog', '#chilly_bin'
+ '#done',
+ '#in_progress',
+ '#backlog',
+ '#chilly_bin',
]);
expect(project.columnsBefore('#epic')).toEqual([
- '#done', '#in_progress', '#backlog', '#chilly_bin', '#search_results'
+ '#done',
+ '#in_progress',
+ '#backlog',
+ '#chilly_bin',
+ '#search_results',
]);
let currentProject = project;
- expect(function() {currentProject.columnsBefore('#foobar');}).toThrow(
- "#foobar is not a valid column"
- );
+ expect(function () {
+ currentProject.columnsBefore('#foobar');
+ }).toThrow('#foobar is not a valid column');
});
-
});
- describe("rebuildIterations", function() {
-
- beforeEach(function() {
- project.projectBoard.stories.invoke = sinon.stub();
+ describe('rebuildIterations', function () {
+ beforeEach(function () {
+ project.projectBoard.stories.invoke = vi.fn();
});
- it("triggers a rebuilt-iterations event", function() {
- var stub = sinon.stub();
+ it('triggers a rebuilt-iterations event', function () {
+ var stub = vi.fn();
project.on('rebuilt-iterations', stub);
project.rebuildIterations();
expect(stub).toHaveBeenCalled();
});
-
});
- describe("toggleStoryFlow", function() {
-
- it("should be able to toggle current_flow value", function() {
+ describe('toggleStoryFlow', function () {
+ it('should be able to toggle current_flow value', function () {
project.toggleStoryFlow();
expect(project.get('current_flow')).toBe('progress_to_right');
@@ -519,11 +572,9 @@ describe('Project model', function() {
expect(project.get('current_flow')).toBe('progress_to_left');
});
- it("should be able to save the current story flow on cookies", function() {
+ it('should be able to save the current story flow on cookies', function () {
project.toggleStoryFlow();
expect(Cookies.get('current_flow')).toBe('progress_to_right');
});
-
});
-
});
diff --git a/spec/javascripts/models/story_spec.js b/spec/javascripts/models/story_spec.js
index 3b8cf7330..b5692d1e9 100644
--- a/spec/javascripts/models/story_spec.js
+++ b/spec/javascripts/models/story_spec.js
@@ -1,142 +1,139 @@
import Story from 'models/story';
import User from 'models/user';
-describe('Story', function() {
+describe('Story', function () {
let story;
let new_story;
let ro_story;
- let server;
- beforeEach(function() {
+ beforeEach(function () {
var Project = Backbone.Model.extend({
name: 'project',
- defaults: {point_values: [0, 1, 2, 3]},
- users: { get: function() {} },
+ defaults: { point_values: [0, 1, 2, 3] },
+ users: { get: function () {} },
current_user: new User({ id: 999, 'guest?': false }),
- currentIterationNumber: function() { return 1; },
- getIterationNumberForDate: function() { return 999; }
+ currentIterationNumber: function () {
+ return 1;
+ },
+ getIterationNumberForDate: function () {
+ return 999;
+ },
});
var collection = {
- project: new Project({}), url: '/foo', remove: function() {},
- get: function() {}
+ project: new Project({}),
+ url: '/foo',
+ remove: function () {},
+ get: function () {},
};
var view = new Backbone.View();
story = new Story({
- id: 999, title: 'Test story', position: '2.45'
+ id: 999,
+ title: 'Test story',
+ position: '2.45',
});
new_story = new Story({
- title: 'New story'
+ title: 'New story',
});
ro_story = new Story({
- id: 998, title: 'Readonly story', position: '2.55'
+ id: 998,
+ title: 'Readonly story',
+ position: '2.55',
});
story.collection = new_story.collection = ro_story.collection = collection;
- story.view = new_story.view = ro_story.view = view;
+ story.view = new_story.view = ro_story.view = view;
// the readonly flag is called in the initialize, but the state change depends on the collection, which in spec is set after the instance, so has to set manually here
- ro_story.set({state: 'accepted', accepted_at: new Date()});
+ ro_story.set({ state: 'accepted', accepted_at: new Date() });
ro_story.setReadonly();
-
- server = sinon.fakeServer.create();
});
- describe('when instantiated', function() {
-
- it('should exhibit attributes', function() {
- expect(story.get('title'))
- .toEqual('Test story');
+ describe('when instantiated', function () {
+ it('should exhibit attributes', function () {
+ expect(story.get('title')).toEqual('Test story');
});
- it('should have a default state of unscheduled', function() {
- expect(story.get('state'))
- .toEqual('unscheduled');
+ it('should have a default state of unscheduled', function () {
+ expect(story.get('state')).toEqual('unscheduled');
});
- it('should have a default story type of feature', function() {
- expect(story.get('story_type'))
- .toEqual('feature');
+ it('should have a default story type of feature', function () {
+ expect(story.get('story_type')).toEqual('feature');
});
- it('should have an empty array of events by default', function() {
- expect(story.get('events'))
- .toEqual([]);
+ it('should have an empty array of events by default', function () {
+ expect(story.get('events')).toEqual([]);
});
- it('does not have a default release date setted', function() {
- expect(story.get('release_date'))
- .toBeUndefined()
+ it('does not have a default release date setted', function () {
+ expect(story.get('release_date')).toBeUndefined();
});
-
});
- describe('state transitions', function() {
-
- it('should start', function() {
+ describe('state transitions', function () {
+ it('should start', function () {
story.start();
expect(story.get('state')).toEqual('started');
});
- it('should finish', function() {
+ it('should finish', function () {
story.finish();
expect(story.get('state')).toEqual('finished');
});
- it('should deliver', function() {
+ it('should deliver', function () {
story.deliver();
expect(story.get('state')).toEqual('delivered');
});
- it('should accept', function() {
+ it('should accept', function () {
story.accept();
expect(story.get('state')).toEqual('accepted');
});
- it('should reject', function() {
+ it('should reject', function () {
story.reject();
expect(story.get('state')).toEqual('rejected');
});
- it('should restart', function() {
+ it('should restart', function () {
story.restart();
expect(story.get('state')).toEqual('started');
});
-
});
- describe("events", function() {
- it("transitions from unscheduled", function() {
- story.set({state: "unscheduled"});
- expect(story.events()).toEqual(["start"]);
+ describe('events', function () {
+ it('transitions from unscheduled', function () {
+ story.set({ state: 'unscheduled' });
+ expect(story.events()).toEqual(['start']);
});
- it("transitions from unstarted", function() {
- story.set({state: "unstarted"});
- expect(story.events()).toEqual(["start"]);
+ it('transitions from unstarted', function () {
+ story.set({ state: 'unstarted' });
+ expect(story.events()).toEqual(['start']);
});
- it("transitions from started", function() {
- story.set({state: "started"});
- expect(story.events()).toEqual(["finish"]);
+ it('transitions from started', function () {
+ story.set({ state: 'started' });
+ expect(story.events()).toEqual(['finish']);
});
- it("transitions from finished", function() {
- story.set({state: "finished"});
- expect(story.events()).toEqual(["deliver"]);
+ it('transitions from finished', function () {
+ story.set({ state: 'finished' });
+ expect(story.events()).toEqual(['deliver']);
});
- it("transitions from delivered", function() {
- story.set({state: "delivered"});
- expect(story.events()).toEqual(["accept", "reject"]);
+ it('transitions from delivered', function () {
+ story.set({ state: 'delivered' });
+ expect(story.events()).toEqual(['accept', 'reject']);
});
- it("transitions from rejected", function() {
- story.set({state: "rejected"});
- expect(story.events()).toEqual(["restart"]);
+ it('transitions from rejected', function () {
+ story.set({ state: 'rejected' });
+ expect(story.events()).toEqual(['restart']);
});
- it("has no transitions from accepted", function() {
- story.set({state: "accepted"});
+ it('has no transitions from accepted', function () {
+ story.set({ state: 'accepted' });
expect(story.events()).toEqual([]);
});
});
- describe("setAcceptedAt", function() {
-
- it("should set accepted at to today's date when accepted", function() {
+ describe('setAcceptedAt', function () {
+ it("should set accepted at to today's date when accepted", function () {
var today = new Date();
today.setHours(0);
today.setMinutes(0);
@@ -147,352 +144,332 @@ describe('Story', function() {
expect(new Date(story.get('accepted_at'))).toEqual(today);
});
- it("should not set accepted at when accepted if already set", function() {
- story.set({accepted_at: "2001/01/01"});
+ it('should not set accepted at when accepted if already set', function () {
+ story.set({ accepted_at: '2001/01/01' });
story.accept();
- expect(story.get('accepted_at')).toEqual("2001/01/01");
+ expect(story.get('accepted_at')).toEqual('2001/01/01');
});
});
- describe('estimable', function() {
-
- describe("when story is a feature", function() {
- beforeEach(function() {
- story.set({story_type: 'feature'});
+ describe('estimable', function () {
+ describe('when story is a feature', function () {
+ beforeEach(function () {
+ story.set({ story_type: 'feature' });
});
- it('should be estimable when not estimated', function() {
- sinon.stub(story, 'estimated').returns(false);
+ it('should be estimable when not estimated', function () {
+ vi.spyOn(story, 'estimated').mockReturnValueOnce(false);
expect(story.estimable()).toBeTruthy();
});
- it('should not be estimable when estimated', function() {
- sinon.stub(story, 'estimated').returns(true);
+ it('should not be estimable when estimated', function () {
+ vi.spyOn(story, 'estimated').mockReturnValueOnce(true);
expect(story.estimable()).toBeFalsy();
});
});
- describe("when story is not a feature", function() {
- it('should not be estimable', function() {
- story.set({story_type: 'release'});
+ describe('when story is not a feature', function () {
+ it('should not be estimable', function () {
+ story.set({ story_type: 'release' });
expect(story.estimable()).toBeFalsy();
});
});
-
});
- describe('estimated', function() {
-
- it('should say if it is estimated or not', function() {
+ describe('estimated', function () {
+ it('should say if it is estimated or not', function () {
story.unset('estimate');
expect(story.estimated()).toBeFalsy();
- story.set({estimate: null});
+ story.set({ estimate: null });
expect(story.estimated()).toBeFalsy();
- story.set({estimate: 0});
+ story.set({ estimate: 0 });
expect(story.estimated()).toBeTruthy();
- story.set({estimate: 1});
+ story.set({ estimate: 1 });
expect(story.estimated()).toBeTruthy();
});
-
});
describe('notEstimable', function () {
it('should not be estimable when story type is bug', function () {
- story.set({story_type: 'bug'});
+ story.set({ story_type: 'bug' });
expect(story.notEstimable()).toBeTruthy();
});
it('should not be estimable when story type is chore', function () {
- story.set({story_type: 'chore'});
+ story.set({ story_type: 'chore' });
expect(story.notEstimable()).toBeTruthy();
});
it('should not be estimable when story type is release', function () {
- story.set({story_type: 'release'});
+ story.set({ story_type: 'release' });
expect(story.notEstimable()).toBeTruthy();
});
it('should be estimable when story type is feature', function () {
- story.set({story_type: 'feature'});
+ story.set({ story_type: 'feature' });
expect(story.notEstimable()).toBeFalsy();
});
-
});
- describe('point_values', function() {
-
- it('should known about its valid points values', function() {
+ describe('point_values', function () {
+ it('should known about its valid points values', function () {
expect(story.point_values()).toEqual([0, 1, 2, 3]);
});
-
});
- describe('class name', function() {
-
- it('should have a classes of story and story type', function() {
- story.set({estimate: 1});
+ describe('class name', function () {
+ it('should have a classes of story and story type', function () {
+ story.set({ estimate: 1 });
expect(story.className()).toEqual('story feature');
});
- it('should have an unestimated class if unestimated', function() {
+ it('should have an unestimated class if unestimated', function () {
expect(story.estimable()).toBeTruthy();
expect(story.estimated()).toBeFalsy();
expect(story.className()).toEqual('story feature unestimated');
});
-
});
- describe('position', function() {
-
- it('should get position as a float', function() {
+ describe('position', function () {
+ it('should get position as a float', function () {
expect(story.position()).toEqual(2.45);
});
-
});
- describe('column', function() {
- it('should return the right column', function() {
- story.set({state: 'unscheduled'});
+ describe('column', function () {
+ it('should return the right column', function () {
+ story.set({ state: 'unscheduled' });
expect(story.column).toEqual('#chilly_bin');
- story.set({state: 'unstarted'});
+ story.set({ state: 'unstarted' });
expect(story.column).toEqual('#backlog');
- story.set({state: 'started'});
+ story.set({ state: 'started' });
expect(story.column).toEqual('#in_progress');
- story.set({state: 'delivered'});
+ story.set({ state: 'delivered' });
expect(story.column).toEqual('#in_progress');
- story.set({state: 'rejected'});
+ story.set({ state: 'rejected' });
expect(story.column).toEqual('#in_progress');
// If the story is accepted, but it's accepted_at date is within the
// current iteration, it should be in the in_progress column, otherwise
// it should be in the #done column
- sinon.stub(story, 'iterationNumber').returns(1);
- story.collection.project.currentIterationNumber = sinon.stub().returns(2);
- story.set({state: 'accepted'});
+ story.set({ state: 'accepted' });
+ vi.spyOn(story, 'iterationNumber').mockReturnValueOnce(1);
+ story.collection.project.currentIterationNumber = vi
+ .fn()
+ .mockReturnValueOnce(2);
expect(story.column).toEqual('#done');
- story.collection.project.currentIterationNumber.returns(1);
+ story.collection.project.currentIterationNumber.mockReturnValueOnce(1);
+ story.collection.project.currentIterationNumber();
story.setColumn();
expect(story.column).toEqual('#in_progress');
});
});
- describe("clear", function() {
-
- it("should destroy itself and its view", function() {
- var modelStub = sinon.stub(story, "destroy");
+ describe('clear', function () {
+ it('should destroy itself and its view', function () {
+ var modelStub = vi.spyOn(story, 'destroy');
story.clear();
expect(modelStub).toHaveBeenCalled();
});
-
});
- describe("errors", function() {
-
- it("should record errors", function() {
+ describe('errors', function () {
+ it('should record errors', function () {
expect(story.hasErrors()).toBeFalsy();
expect(story.errorsOn('title')).toBeFalsy();
- story.set({errors: {
- title: ["cannot be blank", "needs to be better"],
- estimate: ["is helluh unrealistic"]
- }});
+ story.set({
+ errors: {
+ title: ['cannot be blank', 'needs to be better'],
+ estimate: ['is helluh unrealistic'],
+ },
+ });
expect(story.hasErrors()).toBeTruthy();
expect(story.errorsOn('title')).toBeTruthy();
expect(story.errorsOn('position')).toBeFalsy();
- expect(story.errorMessages())
- .toEqual("title cannot be blank, title needs to be better, estimate is helluh unrealistic");
+ expect(story.errorMessages()).toEqual(
+ 'title cannot be blank, title needs to be better, estimate is helluh unrealistic'
+ );
});
-
});
- describe("users", function() {
-
- it("should get it's owner", function() {
-
+ describe('users', function () {
+ it("should get it's owner", function () {
// Should return undefined if the story does not have an owner
- var spy = sinon.spy(story.collection.project.users, "get");
+ var spy = vi.spyOn(story.collection.project.users, 'get');
var owned_by = story.owned_by();
expect(spy).toHaveBeenCalledWith(undefined);
expect(owned_by).toBeUndefined();
- story.set({'owned_by_id': 999});
+ story.set({ owned_by_id: 999 });
owned_by = story.owned_by();
expect(spy).toHaveBeenCalledWith(999);
});
- it("should get it's requester", function() {
-
+ it('should get its requester', function () {
// Should return undefined if the story does not have an owner
- var stub = sinon.stub(story.collection.project.users, "get");
- var dummyUser = {};
- stub.withArgs(undefined).returns(undefined);
- stub.withArgs(999).returns(dummyUser);
-
- var requested_by = story.requested_by();
+ const stub = vi
+ .spyOn(story.collection.project.users, 'get')
+ .mockImplementation(arg => {
+ if (arg === undefined) {
+ return undefined;
+ }
+ if (arg === 999) {
+ return dummyUser;
+ }
+ });
+
+ const dummyUser = {};
+
+ let requested_by = story.requested_by();
expect(stub).toHaveBeenCalledWith(undefined);
expect(requested_by).toBeUndefined();
- story.set({'requested_by_id': 999});
+ story.set({ requested_by_id: 999 });
requested_by = story.requested_by();
expect(requested_by).toEqual(dummyUser);
expect(stub).toHaveBeenCalledWith(999);
});
- it("should return a readable created_at", function() {
-
- var timestamp = "2011/09/19 02:25:56 +0000";
- story.set({'created_at': timestamp});
+ it('should return a readable created_at', function () {
+ var timestamp = '2011/09/19 02:25:56 +0000';
+ story.set({ created_at: timestamp });
expect(story.created_at()).toBe(
new Date(timestamp).format(story.timestampFormat)
);
-
});
- it("should be assigned to the current user when started", function() {
-
+ it('should be assigned to the current user when started', function () {
expect(story.get('state')).toEqual('unscheduled');
expect(story.owned_by()).toBeUndefined();
- story.set({state: 'started'});
+ story.set({ state: 'started' });
expect(story.get('owned_by_id')).toEqual(999);
});
-
});
-
- describe("details", function() {
-
+ describe('details', function () {
// If the story has details other than the title, e.g. description
- it("should return true the story has a description", function() {
-
+ it('should return true the story has a description', function () {
expect(story.hasDetails()).toBeFalsy();
- story.set({description: "Test description"});
+ story.set({ description: 'Test description' });
expect(story.hasDetails()).toBeTruthy();
-
});
- it("should return true if the story has saved notes", function() {
-
+ it('should return true if the story has saved notes', function () {
expect(story.hasDetails()).toBeFalsy();
- story.hasNotes = sinon.stub().returns(true);
+ story.hasNotes = vi.fn().mockReturnValueOnce(true);
expect(story.hasDetails()).toBeTruthy();
-
});
});
-
- describe("iterations", function() {
-
- it("should return the iteration number for an accepted story", function() {
- story.collection.project.getIterationNumberForDate = sinon.stub().returns(999);
- story.set({accepted_at: "2011/07/25", state: "accepted"});
+ describe('iterations', function () {
+ it('should return the iteration number for an accepted story', function () {
+ story.collection.project.iterationNumber = vi
+ .fn()
+ .mockReturnValueOnce(999);
+ story.set({ accepted_at: '2011/07/25', state: 'accepted' });
expect(story.iterationNumber()).toEqual(999);
});
-
});
- describe("labels", function() {
-
- it("should return an empty array if labels undefined", function() {
+ describe('labels', function () {
+ it('should return an empty array if labels undefined', function () {
expect(story.get('labels')).toBeUndefined();
expect(story.labels()).toEqual([]);
});
- it("should return an array of labels", function() {
- story.set({labels: "foo,bar"});
- expect(story.labels()).toEqual(["foo","bar"]);
+ it('should return an array of labels', function () {
+ story.set({ labels: 'foo,bar' });
+ expect(story.labels()).toEqual(['foo', 'bar']);
});
- it("should remove trailing and leading whitespace when spliting labels", function() {
- story.set({labels: "foo , bar , baz"});
- expect(story.labels()).toEqual(["foo","bar","baz"]);
+ it('should remove trailing and leading whitespace when spliting labels', function () {
+ story.set({ labels: 'foo , bar , baz' });
+ expect(story.labels()).toEqual(['foo', 'bar', 'baz']);
});
-
});
- describe("notes", function() {
-
- it("should default with an empty notes collection", function() {
+ describe('notes', function () {
+ it('should default with an empty notes collection', function () {
expect(story.notes.length).toEqual(0);
});
- it("should set the right notes collection url", function() {
+ it('should set the right notes collection url', function () {
expect(story.notes.url()).toEqual('/foo/999/notes');
});
- it("should set a notes collection", function() {
+ it('should set a notes collection', function () {
var story = new Story({
- notes: [{"note":{"text": "Dummy note"}}]
+ notes: [{ note: { text: 'Dummy note' } }],
});
expect(story.notes.length).toEqual(1);
});
- describe("hasNotes", function() {
-
- it("returns true if it has saved notes", function() {
+ describe('hasNotes', function () {
+ it('returns true if it has saved notes', function () {
expect(story.hasNotes()).toBeFalsy();
- story.notes.add({id: 999, note: "Test note"});
+ story.notes.add({ id: 999, note: 'Test note' });
expect(story.hasNotes()).toBeTruthy();
});
- it("returns false if it has unsaved notes", function() {
- story.notes.add({note: "Unsaved note"});
+ it('returns false if it has unsaved notes', function () {
+ story.notes.add({ note: 'Unsaved note' });
expect(story.hasNotes()).toBeFalsy();
});
-
});
-
});
- describe('humanAttributeName', function() {
- beforeEach(function() {
- sinon.stub(I18n, 't');
- I18n.t.withArgs('foo_bar').returns('Foo bar');
+ describe('humanAttributeName', function () {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't').mockImplementation(arg => {
+ if (arg === 'foo_bar') return 'Foo bar';
+ });
});
afterEach(() => {
- I18n.t.restore();
+ I18n.t.mockRestore();
});
- it("returns the translated attribute name", function() {
+ it('returns the translated attribute name', function () {
expect(story.humanAttributeName('foo_bar')).toEqual('Foo bar');
});
- it("strips of the id suffix", function() {
+ it('strips of the id suffix', function () {
expect(story.humanAttributeName('foo_bar_id')).toEqual('Foo bar');
});
});
- describe('isReadonly', function() {
- it("should not be read only", function() {
+ describe('isReadonly', function () {
+ it('should not be read only', function () {
expect(story.isReadonly).toBeFalsy();
});
- it("should be read only", function() {
+ it('should be read only', function () {
expect(ro_story.isReadonly).toBeTruthy();
});
});
- describe('changeState', function() {
- describe('when story is started', function() {
- it('sets the owner to the current user', function() {
+ describe('changeState', function () {
+ describe('when story is started', function () {
+ it('sets the owner to the current user', function () {
story.set({ onwed_by_id: 123 });
story.changeState(story, 'started');
expect(story.get('owned_by_id')).toBe(999);
});
});
- describe('when story is not started', function() {
- it('does not change the owner', function() {
+ describe('when story is not started', function () {
+ it('does not change the owner', function () {
story.changeState(story, 'finished');
expect(story.get('owned_by_id')).toBe(undefined);
});
diff --git a/spec/javascripts/models/task_spec.js b/spec/javascripts/models/task_spec.js
index 7b9441707..03b4a6e30 100644
--- a/spec/javascripts/models/task_spec.js
+++ b/spec/javascripts/models/task_spec.js
@@ -1,63 +1,63 @@
import Task from 'models/task';
+import { afterEach } from 'vitest';
-describe("Task", function() {
+describe('Task', function () {
let task;
- beforeEach(function() {
+ beforeEach(function () {
task = new Task({});
});
- describe("story", function() {
-
- beforeEach(function() {
- task.set({story_id: 999, name: 'Foobar'});
+ describe('story', function () {
+ beforeEach(function () {
+ task.set({ story_id: 999, name: 'Foobar' });
});
- it("returns the name task", function() {
+ it('returns the name task', function () {
expect(task.get('name')).toEqual('Foobar');
});
- it("returns the story_id", function() {
+ it('returns the story_id', function () {
expect(task.get('story_id')).toEqual(999);
});
-
});
- describe("errors", function() {
-
- it("should record errors", function() {
+ describe('errors', function () {
+ it('should record errors', function () {
expect(task.hasErrors()).toBeFalsy();
expect(task.errorsOn('name')).toBeFalsy();
- task.set({errors: {
- name: ["cannot be blank", "needs to be better"]
- }});
+ task.set({
+ errors: {
+ name: ['cannot be blank', 'needs to be better'],
+ },
+ });
expect(task.hasErrors()).toBeTruthy();
expect(task.errorsOn('name')).toBeTruthy();
- expect(task.errorMessages())
- .toEqual("name cannot be blank, name needs to be better");
+ expect(task.errorMessages()).toEqual(
+ 'name cannot be blank, name needs to be better'
+ );
});
-
});
- describe('humanAttributeName', function() {
-
- beforeEach(function() {
- sinon.stub(I18n, 't');
- I18n.t.withArgs('foo_bar').returns('Foo bar');
+ describe('humanAttributeName', function () {
+ beforeEach(function () {
+ vi.spyOn(I18n, 't').mockImplementation(arg => {
+ if (arg === 'foo_bar') return 'Foo bar';
+ });
});
- afterEach(function() {
- I18n.t.restore();
+ afterEach(() => {
+ I18n.t.mockRestore();
});
- it("returns the translated attribute name", function() {
+ it('returns the translated attribute name', function () {
expect(task.humanAttributeName('foo_bar')).toEqual('Foo bar');
});
- it("strips of the id suffix", function() {
+ it('strips of the id suffix', function () {
expect(task.humanAttributeName('foo_bar_id')).toEqual('Foo bar');
});
});
diff --git a/spec/javascripts/models/user_spec.js b/spec/javascripts/models/user_spec.js
index 0d0b5da23..c373bc0ab 100644
--- a/spec/javascripts/models/user_spec.js
+++ b/spec/javascripts/models/user_spec.js
@@ -1,7 +1,7 @@
import User from 'models/user';
-describe("User", () => {
- beforeEach(function() {
+describe('User', () => {
+ beforeEach(function () {
const userData = {
email: 'foo@bar.com',
finished_tour: false,
@@ -9,20 +9,23 @@ describe("User", () => {
initials: 'FB',
name: 'Foo Bar',
username: 'foobar',
- tour_steps: '[]'
+ tour_steps: '[]',
};
- sinon.stub($, 'ajax').withArgs({
- type: 'GET',
- dataType: 'json',
- url: '/users/current'
- }).returns($.when(userData));
- });
+ vi.spyOn($, 'ajax').mockImplementation(arg => {
+ const object = {
+ type: 'GET',
+ dataType: 'json',
+ url: '/users/current',
+ };
- afterEach(() => $.ajax.restore());
+ if (JSON.stringify(arg) === JSON.stringify(object))
+ return $.when(userData);
+ });
+ });
- it('returns current user', function(done) {
- User.getCurrent().then((currentUser) => {
+ it('returns current user', function (done) {
+ User.getCurrent().then(currentUser => {
expect(currentUser.attributes).toEqual({
email: 'foo@bar.com',
finished_tour: false,
@@ -30,7 +33,7 @@ describe("User", () => {
initials: 'FB',
name: 'Foo Bar',
username: 'foobar',
- tour_steps: []
+ tour_steps: [],
});
expect(currentUser instanceof User).toEqual(true);
diff --git a/spec/javascripts/support/setup.js b/spec/javascripts/support/setup.js
index 6eb0c88f6..c901c036d 100644
--- a/spec/javascripts/support/setup.js
+++ b/spec/javascripts/support/setup.js
@@ -1,7 +1,5 @@
import 'libs/index';
import 'raf/polyfill';
-import './enzyme';
-import 'jest-enzyme';
import * as JestDom from '@testing-library/jest-dom';
@@ -9,7 +7,6 @@ const { toHaveStyle: toHaveDomStyle, ...jestDomRest } = JestDom;
expect.extend({ toHaveDomStyle, ...jestDomRest });
-window.sinon = require('sinon');
-window.md = { makeHtml: function() {} };
+window.md = { makeHtml: function () {} };
window.process.env.CLOUDINARY_URL = 'cloudinary://username:password@localhost';
window.process.env.CLOUDINARY_UPLOAD_PRESET = '';
diff --git a/spec/javascripts/views/column_view_spec.js b/spec/javascripts/views/column_view_spec.js
index 1bbdb2715..3c3993c5e 100644
--- a/spec/javascripts/views/column_view_spec.js
+++ b/spec/javascripts/views/column_view_spec.js
@@ -1,99 +1,100 @@
import ColumnView from 'views/column_view';
-describe("ColumnView", function() {
+describe('ColumnView', function () {
let el;
let view;
- beforeEach(function() {
- ColumnView.prototype.template = sinon.stub();
- el = $(' | ');
- view = new ColumnView({el: el});
+ beforeEach(function () {
+ ColumnView.prototype.template = vi.fn();
+ el = $(
+ ' | '
+ );
+ view = new ColumnView({ el: el });
});
- it("should be a ", function() {
+ it('should be a | ', function () {
expect(view.$el[0].nodeName).toEqual('TD');
});
- describe("toggle", function() {
-
- beforeEach(function() {
- view.$el.toggle = sinon.spy();
+ describe('toggle', function () {
+ beforeEach(function () {
+ view.$el.toggle = vi.fn();
});
- it("calls jQuery.hide() on its el", function() {
+ it('calls jQuery.hide() on its el', function () {
view.toggle();
expect(view.$el.toggle).toHaveBeenCalled();
});
- it("triggers the visibilityChanged event", function() {
- var stub = sinon.stub();
+ it('triggers the visibilityChanged event', function () {
+ var stub = vi.fn();
view.on('visibilityChanged', stub);
view.toggle();
expect(stub).toHaveBeenCalled();
});
-
});
- describe("storyColumn", function() {
+ describe('storyColumn', function () {
let storyColumn;
- beforeEach(function() {
+ beforeEach(function () {
storyColumn = {};
- sinon.stub(view, '$');
- view.$.withArgs('.story_column').returns(storyColumn);
+ vi.spyOn(view, '$').mockImplementation(arg => {
+ if (arg === '.story_column') return storyColumn;
+ });
});
- it("returns the story column", function() {
+ it('returns the story column', function () {
expect(view.storyColumn()).toBe(storyColumn);
});
});
- describe("appendView", function() {
+ describe('appendView', function () {
let storyColumn;
- beforeEach(function() {
- storyColumn = {append: sinon.stub()};
- view.storyColumn = sinon.stub().returns(storyColumn);
+ beforeEach(function () {
+ storyColumn = { append: vi.fn() };
+ view.storyColumn = vi.fn().mockReturnValueOnce(storyColumn);
});
- it("appends the view to the story column", function() {
- var currentView = {el: {}};
+ it('appends the view to the story column', function () {
+ var currentView = { el: {} };
view.appendView(currentView);
expect(storyColumn.append).toHaveBeenCalledWith(currentView.el);
});
-
});
- describe("setSortable", function() {
+ describe('setSortable', function () {
let storyColumn;
- beforeEach(function() {
- storyColumn = {sortable: sinon.stub()};
- view.storyColumn = sinon.stub().returns(storyColumn);
+ beforeEach(function () {
+ storyColumn = { sortable: vi.fn() };
+ view.storyColumn = vi.fn().mockReturnValueOnce(storyColumn);
});
- it("calls sortable on the story column", function() {
+ it('calls sortable on the story column', function () {
view.setSortable();
expect(storyColumn.sortable).toHaveBeenCalled();
});
-
});
- describe("hidden", function() {
-
- beforeEach(function() {
- view.$el.is = sinon.stub();
+ describe('hidden', function () {
+ beforeEach(function () {
+ view.$el.is = vi.fn();
});
- it("returns true if the column is hidden", function() {
- view.$el.is.withArgs(':hidden').returns(true);
+ it('returns true if the column is hidden', function () {
+ vi.spyOn(view.$el, 'is').mockImplementation(arg => {
+ if (arg === ':hidden') return true;
+ });
expect(view.hidden()).toEqual(true);
});
- it("returns false if the column is visible", function() {
- view.$el.is.withArgs(':hidden').returns(false);
+ it('returns false if the column is visible', function () {
+ vi.spyOn(view.$el, 'is').mockImplementation(arg => {
+ if (arg === ':hidden') return false;
+ });
expect(view.hidden()).toEqual(false);
});
});
-
});
diff --git a/spec/javascripts/views/column_visibility_button_view_spec.js b/spec/javascripts/views/column_visibility_button_view_spec.js
index 40888ddab..2e72a5016 100644
--- a/spec/javascripts/views/column_visibility_button_view_spec.js
+++ b/spec/javascripts/views/column_visibility_button_view_spec.js
@@ -1,61 +1,61 @@
import ColumnVisibilityButtonView from 'views/column_visibility_button_view';
import ColumnView from 'views/column_view';
-describe("ColumnVisibilityButtonView", function() {
+describe('ColumnVisibilityButtonView', function () {
let el;
let view;
let columnView;
- beforeEach(function() {
- el = $(' | | ');
- columnView = new ColumnView({el: el});
- ColumnVisibilityButtonView.prototype.template = sinon.stub();
- view = new ColumnVisibilityButtonView({columnView: columnView});
+ beforeEach(function () {
+ el = $(
+ ' | '
+ );
+ columnView = new ColumnView({ el: el });
+ ColumnVisibilityButtonView.prototype.template = vi.fn();
+ view = new ColumnVisibilityButtonView({ columnView: columnView });
});
- it("should have as the tagName",function() {
+ it('should have as the tagName', function () {
expect(view.el.nodeName).toEqual('A');
});
- it("should set its content from the ColumnView title", function() {
+ it('should set its content from the ColumnView title', function () {
expect(view.title).toEqual(columnView.title);
});
- it("should set its class from the ColumnView id", function() {
- expect(view.$el.attr('class')).toEqual('sidebar-link hide_' + columnView.id);
+ it('should set its class from the ColumnView id', function () {
+ expect(view.$el.attr('class')).toEqual(
+ 'sidebar-link hide_' + columnView.id
+ );
});
- describe('toggle', function() {
-
- beforeEach(function() {
- columnView.toggle = sinon.stub();
+ describe('toggle', function () {
+ beforeEach(function () {
+ columnView.toggle = vi.fn();
});
- it('delegates to the columnView', function() {
+ it('delegates to the columnView', function () {
view.toggle();
expect(columnView.toggle).toHaveBeenCalled();
});
-
});
- describe('setClassName', function() {
-
- it("sets the pressed class when the column is hidden", function() {
- columnView.hidden = sinon.stub().returns(true);
+ describe('setClassName', function () {
+ it('sets the pressed class when the column is hidden', function () {
+ columnView.hidden = vi.fn().mockReturnValueOnce(true);
view.setClassName();
expect(view.$el[0]).toHaveClass('pressed');
});
- it("removes the pressed class when the column is visible", function() {
- columnView.hidden = sinon.stub().returns(false);
+ it('removes the pressed class when the column is visible', function () {
+ columnView.hidden = vi.fn().mockReturnValueOnce(false);
view.setClassName();
expect(view.$el[0]).not.toHaveClass('pressed');
});
- it("is bound to the columnView visibilityChanged event", function() {
+ it('is bound to the columnView visibilityChanged event', function () {
columnView.toggle();
expect(columnView.hidden()).toBe(true);
});
-
});
});
diff --git a/spec/javascripts/views/form_view_spec.js b/spec/javascripts/views/form_view_spec.js
index 862213d18..698f11fb3 100644
--- a/spec/javascripts/views/form_view_spec.js
+++ b/spec/javascripts/views/form_view_spec.js
@@ -1,24 +1,26 @@
import FormView from 'views/form_view';
-describe('FormView', function() {
+describe('FormView', function () {
let view;
- beforeEach(function() {
- FormView.prototype.template = sinon.stub();
+ beforeEach(function () {
+ FormView.prototype.template = vi.fn();
view = new FormView();
});
- it("should have a form as its top level element", function() {
+ it('should have a form as its top level element', function () {
expect(view.el.nodeName).toEqual('FORM');
});
- describe("mergeAttrs", function() {
- it("merges an options hash with some defaults", function() {
- var opts = {foo: 'bar'};
- var defaults = {foo: 'baz', bar: 'baz'};
- expect(view.mergeAttrs(defaults, opts)).toEqual({foo: 'bar', bar: 'baz'});
- expect(defaults).toEqual({foo: 'bar', bar: 'baz'});
+ describe('mergeAttrs', function () {
+ it('merges an options hash with some defaults', function () {
+ var opts = { foo: 'bar' };
+ var defaults = { foo: 'baz', bar: 'baz' };
+ expect(view.mergeAttrs(defaults, opts)).toEqual({
+ foo: 'bar',
+ bar: 'baz',
+ });
+ expect(defaults).toEqual({ foo: 'bar', bar: 'baz' });
});
});
-
});
diff --git a/spec/javascripts/views/iteration_view_spec.js b/spec/javascripts/views/iteration_view_spec.js
index eab3f9e5d..30b9ccdc5 100644
--- a/spec/javascripts/views/iteration_view_spec.js
+++ b/spec/javascripts/views/iteration_view_spec.js
@@ -1,50 +1,51 @@
import IterationView from 'views/iteration_view';
-describe('IterationView', function() {
+describe('IterationView', function () {
let view;
let iteration;
- beforeEach(function() {
+ beforeEach(function () {
var Iteration = Backbone.Model.extend({
- name: 'iteration', points: function() { return 999; },
- acceptedPoints: function() { return 555; },
- startDate: function() { return new Date('2011/09/26'); }
+ name: 'iteration',
+ points: function () {
+ return 999;
+ },
+ acceptedPoints: function () {
+ return 555;
+ },
+ startDate: function () {
+ return new Date('2011/09/26');
+ },
});
- iteration = new Iteration({'number': 1});
- IterationView.prototype.template = sinon.stub();
- view = new IterationView({model: iteration});
+ iteration = new Iteration({ number: 1 });
+ IterationView.prototype.template = vi.fn();
+ view = new IterationView({ model: iteration });
});
- it("should have a div as its top level element", function() {
+ it('should have a div as its top level element', function () {
expect(view.el.nodeName).toEqual('DIV');
});
- it("should have a class of iteration", function() {
+ it('should have a class of iteration', function () {
expect(view.$el[0]).toHaveClass('iteration');
});
- describe("render", function() {
-
- it("renders the output of the template into the el", function() {
+ describe('render', function () {
+ it('renders the output of the template into the el', function () {
view.render();
- expect(view.$el.html()).toContain(
- '999'
- );
+ expect(view.$el.html()).toContain('999');
});
-
});
- describe("points", function() {
-
- it("displays points when column is not #in_progress", function() {
- iteration.set({'column': '#backlog'});
+ describe('points', function () {
+ it('displays points when column is not #in_progress', function () {
+ iteration.set({ column: '#backlog' });
expect(view.points()).toEqual(999);
});
- it("displays accepted / total when column is #in_progress", function() {
- iteration.set({'column': '#in_progress'});
+ it('displays accepted / total when column is #in_progress', function () {
+ iteration.set({ column: '#in_progress' });
expect(view.points()).toEqual('555/999');
});
-
});
});
diff --git a/spec/javascripts/views/note_view_spec.js b/spec/javascripts/views/note_view_spec.js
index 94ac749b6..dfc63e081 100644
--- a/spec/javascripts/views/note_view_spec.js
+++ b/spec/javascripts/views/note_view_spec.js
@@ -1,33 +1,33 @@
import NoteView from 'views/note_view';
-describe('NoteView', function() {
+describe('NoteView', function () {
let note;
let view;
- beforeEach(function() {
- var Note = Backbone.Model.extend({name: 'note', url: '/foo'});
+ beforeEach(function () {
+ var Note = Backbone.Model.extend({ name: 'note', url: '/foo' });
note = new Note({});
- NoteView.prototype.template = sinon.stub();
- view = new NoteView({model: note});
+ NoteView.prototype.template = vi.fn();
+ view = new NoteView({ model: note });
});
- it("has div as the tag name", function() {
+ it('has div as the tag name', function () {
expect(view.el.nodeName).toEqual('DIV');
});
- it("has the note class", function() {
+ it('has the note class', function () {
expect(view.$el[0]).toHaveClass('note');
});
- describe("deleteNote", function() {
- it("should call destroy on the model", function() {
- var deleteStub = sinon.stub(view.model, 'destroy');
+ describe('deleteNote', function () {
+ it('should call destroy on the model', function () {
+ var deleteStub = vi.spyOn(view.model, 'destroy');
view.deleteNote();
expect(deleteStub).toHaveBeenCalled();
});
- it("should remove element", function() {
- var removeSpy = sinon.spy(view.$el, 'remove');
+ it('should remove element', function () {
+ var removeSpy = vi.spyOn(view.$el, 'remove');
view.deleteNote();
expect(removeSpy).toHaveBeenCalled();
});
diff --git a/spec/javascripts/views/project_notification_spec.js b/spec/javascripts/views/project_notification_spec.js
index 32831f8d0..d75a32e4c 100644
--- a/spec/javascripts/views/project_notification_spec.js
+++ b/spec/javascripts/views/project_notification_spec.js
@@ -1,33 +1,37 @@
import TabNotification from 'mixins/tab_notification';
-describe('Project Notification', function() {
- var tabNotification = TabNotification;
+describe('Project Notification', function () {
+ let tabNotificationHandleChange;
beforeAll(function () {
- sinon.stub(TabNotification, 'handleChangeTitle');
+ tabNotificationHandleChange = vi.spyOn(
+ TabNotification,
+ 'handleChangeTitle'
+ );
$('body').data({
notificationIconUrl: 'notificationIconUrlValue',
- faviconIconUrl: 'faviconIconUrlValue'
+ faviconIconUrl: 'faviconIconUrlValue',
});
});
afterAll(function () {
- TabNotification.handleChangeTitle.restore();
+ TabNotification.handleChangeTitle.mockRestore();
$('body').removeData(['notificationIconUrl', 'faviconIconUrl']);
});
-
- it('change the favicon and title', function() {
- tabNotification.changeTitle('test title', true);
- expect(tabNotification.handleChangeTitle).toHaveBeenCalledWith(
- ' \u2733 test title', 'notificationIconUrlValue'
+ it('change the favicon and title', function () {
+ TabNotification.changeTitle('test title', true);
+ expect(tabNotificationHandleChange).toHaveBeenCalledWith(
+ ' \u2733 test title',
+ 'notificationIconUrlValue'
);
});
- it('restore the favicon and title', function() {
- tabNotification.changeTitle('test title', false);
- expect(tabNotification.handleChangeTitle).toHaveBeenCalledWith(
- 'test title', 'faviconIconUrlValue'
+ it('restore the favicon and title', function () {
+ TabNotification.changeTitle('test title', false);
+ expect(tabNotificationHandleChange).toHaveBeenCalledWith(
+ 'test title',
+ 'faviconIconUrlValue'
);
});
});
diff --git a/spec/javascripts/views/project_velocity_override_view_spec.js b/spec/javascripts/views/project_velocity_override_view_spec.js
index 2d5bc6a20..b415c0525 100644
--- a/spec/javascripts/views/project_velocity_override_view_spec.js
+++ b/spec/javascripts/views/project_velocity_override_view_spec.js
@@ -1,71 +1,65 @@
import ProjectVelocityOverrideView from 'views/project_velocity_override_view';
-describe('ProjectVelocityOverrideView', function() {
+describe('ProjectVelocityOverrideView', function () {
let project;
let subject;
- beforeEach(function() {
+ beforeEach(function () {
project = {};
- ProjectVelocityOverrideView.prototype.template = sinon.stub();
- subject = new ProjectVelocityOverrideView({model: project});
+ ProjectVelocityOverrideView.prototype.template = vi.fn();
+ subject = new ProjectVelocityOverrideView({ model: project });
});
- describe("changeVelocity", function() {
-
- beforeEach(function() {
- sinon.stub(subject, 'requestedVelocityValue').returns(42);
- project.velocity = sinon.stub();
- subject.$el.remove = sinon.stub();
+ describe('changeVelocity', function () {
+ beforeEach(function () {
+ vi.spyOn(subject, 'requestedVelocityValue').mockReturnValueOnce(42);
+ project.velocity = vi.fn();
+ subject.$el.remove = vi.fn();
});
- it("calls velocity() on the model", function() {
+ it('calls velocity() on the model', function () {
subject.changeVelocity();
expect(project.velocity).toHaveBeenCalledWith(42);
});
- it("removes the $el", function() {
+ it('removes the $el', function () {
subject.changeVelocity();
expect(subject.$el.remove).toHaveBeenCalled();
});
- it("returns false", function() {
+ it('returns false', function () {
expect(subject.changeVelocity()).toEqual(false);
});
-
});
- describe("revertVelocity", function() {
-
- beforeEach(function() {
- project.revertVelocity = sinon.stub();
- subject.$el.remove = sinon.stub();
+ describe('revertVelocity', function () {
+ beforeEach(function () {
+ project.revertVelocity = vi.fn();
+ subject.$el.remove = vi.fn();
});
- it("calls revertVelocity() on the model", function() {
+ it('calls revertVelocity() on the model', function () {
subject.revertVelocity();
expect(project.revertVelocity).toHaveBeenCalled();
});
- it("removes the $el", function() {
+ it('removes the $el', function () {
subject.revertVelocity();
expect(subject.$el.remove).toHaveBeenCalled();
});
- it("returns false", function() {
+ it('returns false', function () {
expect(subject.revertVelocity()).toEqual(false);
});
-
});
- describe("requestedVelocityValue", function() {
-
- beforeEach(function() {
+ describe('requestedVelocityValue', function () {
+ beforeEach(function () {
subject.$el.append('');
});
- it("returns the right value", function() {
+ it('returns the right value', function () {
expect(subject.requestedVelocityValue()).toEqual(42);
});
-
});
});
diff --git a/spec/javascripts/views/project_velocity_view_spec.js b/spec/javascripts/views/project_velocity_view_spec.js
index ae4701537..3431b0fde 100644
--- a/spec/javascripts/views/project_velocity_view_spec.js
+++ b/spec/javascripts/views/project_velocity_view_spec.js
@@ -1,131 +1,128 @@
import ProjectVelocityView from 'views/project_velocity_view';
import ProjectVelocityOverrideView from 'views/project_velocity_override_view';
-jest.mock('views/project_velocity_override_view');
+vi.mock('views/project_velocity_override_view');
-describe('ProjectVelocityView', function() {
+describe('ProjectVelocityView', function () {
let model;
let subject;
let overrideView;
let ProjectVelocityOverrideViewStub;
- beforeEach(function() {
+ beforeEach(function () {
model = {};
-
- overrideView = overrideView = {};
- ProjectVelocityOverrideViewStub = () => overrideView;
+ overrideView = {};
- ProjectVelocityOverrideViewStub.prototype.template = sinon.stub();
+ vi.spyOn(ProjectVelocityOverrideView.prototype, 'template').mockImplementation(() => {});
- ProjectVelocityOverrideView.mockImplementation(() => ProjectVelocityOverrideViewStub);
+ ProjectVelocityOverrideViewStub = () => overrideView;
- sinon.stub(ProjectVelocityView.prototype, 'listenTo');
+ ProjectVelocityOverrideView.mockImplementation(
+ () => ProjectVelocityOverrideViewStub
+ );
- subject = new ProjectVelocityView({model: model});
- });
+ vi.spyOn(ProjectVelocityView.prototype, 'listenTo').mockImplementation(() => {});
- afterEach(() => {
- ProjectVelocityView.prototype.listenTo.restore();
+ subject = new ProjectVelocityView({ model });
});
- it("should have a top level element", function() {
+ it('should have a top level element', function () {
expect(subject.el.nodeName).toEqual('DIV');
});
- describe("initialize", function() {
-
- it("creates the override view", function() {
+ describe('initialize', function () {
+ it('creates the override view', function () {
expect(subject.override_view).toEqual(ProjectVelocityOverrideViewStub);
});
- it("binds setFakeClass to change:userVelocity on the model", function() {
+ it('binds setFakeClass to change:userVelocity on the model', function () {
expect(subject.listenTo).toHaveBeenCalledWith(
- subject.model, "change:userVelocity", subject.setFakeClass
+ subject.model,
+ 'change:userVelocity',
+ subject.setFakeClass
);
});
- it("binds render to rebuilt-iterations on the model", function() {
+ it('binds render to rebuilt-iterations on the model', function () {
expect(subject.listenTo).toHaveBeenCalledWith(
- subject.model, "rebuilt-iterations", subject.render
+ subject.model,
+ 'rebuilt-iterations',
+ subject.render
);
});
-
});
- describe("render", function() {
+ describe('render', function () {
let template;
- beforeEach(function() {
- subject.$el.html = sinon.stub();
- subject.setFakeClass = sinon.stub();
+ beforeEach(function () {
+ subject.$el.html = vi.fn();
+ subject.setFakeClass = vi.fn();
template = {};
- subject.template = sinon.stub().withArgs({project: model}).returns(template);
+ subject.template = vi.fn().mockImplementation(arg => {
+ const object = { project: model };
+
+ if (JSON.stringify(arg) == JSON.stringify(object)) return template;
+ });
});
- it("renders the template", function() {
+ it('renders the template', function () {
subject.render();
expect(subject.$el.html).toHaveBeenCalledWith(template);
});
- it("calls setFakeClass()", function() {
+ it('calls setFakeClass()', function () {
subject.render();
expect(subject.setFakeClass).toHaveBeenCalledWith(model);
});
- it("returns itself", function() {
+ it('returns itself', function () {
expect(subject.render()).toBe(subject);
});
-
});
- describe("editVelocityOverride", function() {
+ describe('editVelocityOverride', function () {
let el;
- beforeEach(function() {
+ beforeEach(function () {
el = {};
- subject.override_view.render = sinon.stub();
- subject.override_view.render.returns({el: el});
- subject.$el.append = sinon.stub();
+ subject.override_view.render = vi.fn();
+ subject.override_view.render.mockReturnValueOnce({ el: el });
+ subject.$el.append = vi.fn();
});
- it("appends the override view to its $el", function() {
+ it('appends the override view to its $el', function () {
subject.editVelocityOverride();
expect(subject.$el.append).toHaveBeenCalled(el);
});
-
});
- describe("setFakeClass", function() {
-
- beforeEach(function() {
- model.velocityIsFake = sinon.stub();
+ describe('setFakeClass', function () {
+ beforeEach(function () {
+ model.velocityIsFake = vi.fn();
});
- describe("when velocity is fake", function() {
-
- beforeEach(function() {
- model.velocityIsFake.returns(true);
+ describe('when velocity is fake', function () {
+ beforeEach(function () {
+ model.velocityIsFake.mockReturnValueOnce(true);
});
- it("adds the fake class to $el", function() {
+ it('adds the fake class to $el', function () {
subject.setFakeClass(model);
expect(subject.$el[0]).toHaveClass('fake');
});
-
});
- describe("when velocity is not fake", function() {
-
- beforeEach(function() {
- model.velocityIsFake.returns(false);
+ describe('when velocity is not fake', function () {
+ beforeEach(function () {
+ model.velocityIsFake.mockReturnValueOnce(false);
});
- it("adds the fake class to $el", function() {
+ it('adds the fake class to $el', function () {
subject.setFakeClass(model);
expect(subject.$el[0]).not.toHaveClass('fake');
});
-
});
});
});
diff --git a/spec/javascripts/views/story_view_spec.js b/spec/javascripts/views/story_view_spec.js
index f0d266a35..10b90cc4d 100644
--- a/spec/javascripts/views/story_view_spec.js
+++ b/spec/javascripts/views/story_view_spec.js
@@ -1,35 +1,54 @@
-import StoryView from "views/story_view";
-import template from "templates/story.ejs";
-import OriginalStory from "models/story";
+import StoryView from 'views/story_view';
+import React from 'react';
+import template from 'templates/story.ejs';
+import OriginalStory from 'models/story';
+import { server } from '../mocks/server';
+import { afterAll, afterEach, beforeAll } from 'vitest';
+import { http, HttpResponse } from 'msw';
-describe("StoryView", function () {
+const url = '/path/to/story';
+
+vi.mock('react-clipboard.js', () => ({
+ default: ({ children, ...props }) => ,
+}));
+
+describe('StoryView', function () {
let story;
let new_story;
let view;
let new_story_view;
let set;
- let server;
+
+ beforeAll(() => {
+ server.listen({
+ onUnhandledRequest: 'error',
+ });
+ });
+
+ afterAll(() => {
+ server.close();
+ });
beforeEach(function () {
window.projectView = {
availableTags: [],
- notice: sinon.stub(),
- noticeSaveError: sinon.stub(),
+ notice: vi.fn(),
+ noticeSaveError: vi.fn(),
};
- sinon.stub(window.md, "makeHtml").returns("");
+ vi.spyOn(window.md, 'makeHtml').mockReturnValue('');
var Note = Backbone.Model.extend({
- name: "note",
- humanAttributeName: sinon.stub(),
+ name: 'note',
+ humanAttributeName: vi.fn(),
});
var Task = Backbone.Model.extend({
- name: "task",
- humanAttributeName: sinon.stub(),
+ name: 'task',
+ humanAttributeName: vi.fn(),
});
var NotesCollection = Backbone.Collection.extend({ model: Note });
var TasksCollection = Backbone.Collection.extend({ model: Task });
var Story = Backbone.Model.extend({
- name: "story",
- defaults: { story_type: "feature" },
+ name: 'story',
+ defaults: { story_type: 'feature' },
estimable: function () {
return true;
},
@@ -48,7 +67,7 @@ describe("StoryView", function () {
errorsOn: function () {
return false;
},
- url: "/path/to/story",
+ url: '/path/to/story',
collection: {
project: {
users: {
@@ -66,30 +85,30 @@ describe("StoryView", function () {
},
},
start: function () {
- this.set({ state: "started" });
+ this.set({ state: 'started' });
},
deliver: function () {
- this.set({ state: "delivered" });
+ this.set({ state: 'delivered' });
},
accept: function () {
- this.set({ state: "accepted" });
+ this.set({ state: 'accepted' });
},
reject: function () {
- this.set({ state: "rejected" });
+ this.set({ state: 'rejected' });
},
hasDetails: function () {
return true;
},
events: OriginalStory.prototype.events,
- humanAttributeName: sinon.stub(),
- setAcceptedAt: sinon.spy(),
- errorMessages: sinon.stub(),
+ humanAttributeName: vi.fn(),
+ setAcceptedAt: vi.fn(),
+ errorMessages: vi.fn(),
views: [],
clickFromSearchResult: false,
isSearchResult: false,
});
- story = new Story({ id: "999", title: "Story" });
- new_story = new Story({ title: "New Story" });
+ story = new Story({ id: '999', title: 'Story' });
+ new_story = new Story({ title: 'New Story' });
story.notes = new_story.notes = new NotesCollection();
story.tasks = new_story.tasks = new TasksCollection();
view = new StoryView({
@@ -99,64 +118,70 @@ describe("StoryView", function () {
model: new_story,
});
- window.projectView.usernames = sinon.stub();
+ window.projectView.usernames = vi.fn();
- server = sinon.fakeServer.create();
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json({}, { status: 200 });
+ })
+ );
});
- afterEach(function () {
- server.restore();
- window.md.makeHtml.restore();
+ afterEach(() => {
+ window.md.makeHtml.mockRestore();
+ server.resetHandlers();
});
- describe("class name", function () {
- it("should have the story class", function () {
- expect(view.$el[0]).toHaveClass("story");
+ describe('class name', function () {
+ it('should have the story class', function () {
+ expect(view.$el[0]).toHaveClass('story');
});
- it("should have the story type class", function () {
- expect(view.$el[0]).toHaveClass("feature");
+ it('should have the story type class', function () {
+ expect(view.$el[0]).toHaveClass('feature');
});
- it("should have the unestimated class", function () {
- expect(view.$el[0]).toHaveClass("unestimated");
+ it('should have the unestimated class', function () {
+ expect(view.$el[0]).toHaveClass('unestimated');
// Should not have the unestimated class if it's been estimated
- sinon.stub(view.model, "estimated").returns(true);
+ vi.spyOn(view.model, 'estimated').mockReturnValueOnce(true);
view.model.set({ estimate: 1 });
- expect(view.$el[0]).not.toHaveClass("unestimated");
+ expect(view.$el[0]).not.toHaveClass('unestimated');
});
- it("should have the story state class", function () {
- expect(view.$el[0]).toHaveClass("unestimated");
- view.model.set({ state: "accepted" });
- expect(view.$el[0]).toHaveClass("accepted");
+ it('should have the story state class', function () {
+ expect(view.$el[0]).toHaveClass('unestimated');
+ view.model.set({ state: 'accepted' });
+ expect(view.$el[0]).toHaveClass('accepted');
});
});
- describe("id", function () {
- it("should have an id", function () {
+ describe('id', function () {
+ it('should have an id', function () {
expect(view.id).toEqual(view.model.id);
- expect(view.$el.attr("id")).toBe("story-" + view.model.id);
+ expect(view.$el.attr('id')).toBe('story-' + view.model.id);
});
});
- describe("startEdit", function () {
+ describe('startEdit', function () {
let e;
beforeEach(function () {
e = {};
- view.model.set = sinon.stub();
- view.removeHoverbox = sinon.stub();
+ view.model.set = vi.fn();
+ view.removeHoverbox = vi.fn();
});
- describe("when event should expand story", function () {
+ describe('when event should expand story', function () {
beforeEach(function () {
- view.eventShouldExpandStory = sinon.stub();
- view.eventShouldExpandStory.withArgs(e).returns(true);
+ view.eventShouldExpandStory = vi.fn();
+ vi.spyOn(view, 'eventShouldExpandStory').mockImplementation(arg => {
+ return arg === e ? true : undefined;
+ });
});
- it("sets the model attributes correctly", function () {
+ it('sets the model attributes correctly', function () {
view.startEdit(e);
expect(view.model.set).toHaveBeenCalledWith({
editing: true,
@@ -165,294 +190,317 @@ describe("StoryView", function () {
});
});
- it("removes the hoverBox", function () {
+ it('removes the hoverBox', function () {
view.startEdit(e);
expect(view.removeHoverbox).toHaveBeenCalled();
});
});
});
- describe("eventShouldExpandStory", function () {
+ describe('eventShouldExpandStory', function () {
let e;
beforeEach(function () {
- e = { target: "" };
+ e = { target: '' };
});
- describe("when model is being edited", function () {
+ describe('when model is being edited', function () {
beforeEach(function () {
view.model.set({ editing: true });
});
- it("returns false", function () {
+ it('returns false', function () {
expect(view.eventShouldExpandStory(e)).toBeFalsy();
});
});
- describe("when model is not being edited", function () {
+ describe('when model is not being edited', function () {
beforeEach(function () {
view.model.set({ editing: false });
});
- describe("and e.target is an input", function () {
- it("returns false", function () {
+ describe('and e.target is an input', function () {
+ it('returns false', function () {
expect(view.eventShouldExpandStory(e)).toBeFalsy();
});
});
- describe("and e.target is not an input", function () {
- it("returns true", function () {
- e.target = "";
+ describe('and e.target is not an input', function () {
+ it('returns true', function () {
+ e.target = '';
expect(view.eventShouldExpandStory(e)).toBeTruthy();
});
});
});
});
- describe("cancel edit", function () {
- it("should remove itself when edit cancelled if its new", function () {
+ describe('cancel edit', function () {
+ it('should remove itself when edit cancelled if its new', function () {
var view = new StoryView({ model: new_story });
- var spy = sinon.spy(new_story, "clear");
+ var spy = vi.spyOn(new_story, 'clear');
view.cancelEdit();
expect(spy).toHaveBeenCalled();
});
- it("should reload after cancel if there were existing errors", function () {
+ it('should reload after cancel if there were existing errors', function () {
+ server.use(
+ http.get(url, () => {
+ return HttpResponse.json({}, { status: 422 });
+ })
+ );
story.set({ errors: true });
- expect(story.get("errors")).toEqual(true);
- sinon.stub(story, "hasErrors").returns(true);
- var stub = sinon.stub(story, "fetch");
+ expect(story.get('errors')).toEqual(true);
+ vi.spyOn(story, 'hasErrors').mockReturnValueOnce(true);
+ var stub = vi.spyOn(story, 'fetch');
view.cancelEdit();
expect(stub).toHaveBeenCalled();
- expect(story.get("errors")).toBeUndefined();
+ expect(story.get('errors')).toBeUndefined();
});
});
- describe("save edit", function () {
+ describe('save edit', function () {
let e;
beforeEach(function () {
- e = { currentTarget: "" };
+ e = { currentTarget: '' };
+ });
+
+ afterEach(() => {
+ server.resetHandlers();
});
- it("should call save", function () {
- server.respondWith("PUT", "/path/to/story", [
- 200,
- { "Content-Type": "application/json" },
- '{"story":{"title":"Story title"}}',
- ]);
+ it('should call save', async function () {
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json(
+ {
+ story: { title: 'Story title' },
+ },
+ { status: 200 }
+ );
+ })
+ );
+
story.set({ editing: true });
- view.clickSave(e);
- expect(story.get("editing")).toBeTruthy();
- expect(server.requests.length).toEqual(1);
+ expect(view.model.get('editing')).toBeTruthy();
- // editing should be set to false when save is successful
- server.respond();
+ await view.clickSave(e);
- expect(story.get("editing")).toBeFalsy();
+ expect(view.model.get('editing')).toBeFalsy();
});
- it("should set editing when errors occur", function () {
- server.respondWith("PUT", "/path/to/story", [
- 422,
- { "Content-Type": "application/json" },
- '{"story":{"errors":{"title":["cannot be blank"]}}}',
- ]);
+ it('should set editing when errors occur', async function () {
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json(
+ {
+ story: { errors: { title: ['cannot be blank'] } },
+ },
+ { status: 422 }
+ );
+ })
+ );
view.clickSave(e);
- expect(server.responses.length).toEqual(1);
- expect(server.responses[0].method).toEqual("PUT");
- expect("/path/to/story").toMatch(server.responses[0].url);
-
- server.respond();
+ await new Promise(resolve => view.model.once('change:editing', resolve));
- expect(story.get("editing")).toBeTruthy();
- expect(story.get("errors").title[0]).toEqual("cannot be blank");
+ expect(story.get('editing')).toBeTruthy();
+ expect(story.get('errors').title[0]).toEqual('cannot be blank');
});
- it("should disable all form controls on submit", function () {
- server.respondWith("PUT", "/path/to/story", [
- 200,
- { "Content-Type": "application/json" },
- '{"story":{"title":"Story title"}}',
- ]);
-
- var disable_spy = sinon.spy(view, "disableForm");
- var enable_spy = sinon.spy(view, "enableForm");
+ it('should disable all form controls on submit', async function () {
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json(
+ {
+ story: { title: 'Story title' },
+ },
+ { status: 200 }
+ );
+ })
+ );
+ var disable_spy = vi.spyOn(view, 'disableForm');
+ var enable_spy = vi.spyOn(view, 'enableForm');
story.set({ editing: true });
- view.clickSave(e);
- expect(disable_spy).toHaveBeenCalled();
expect(enable_spy).not.toHaveBeenCalled();
- server.respond();
+ await view.clickSave(e);
+
+ expect(disable_spy).toHaveBeenCalled();
expect(enable_spy).toHaveBeenCalled();
});
- it("should disable state transition buttons on click", function () {
- server.respondWith("PUT", "/path/to/story", [
- 200,
- { "Content-Type": "application/json" },
- '{"story":{"state":"started"}}',
- ]);
-
- var ev = { target: { value: "start" } };
- view.transition(ev);
-
- expect(view.saveInProgress).toBeTruthy();
-
- server.respond();
+ it('should disable state transition buttons on click', async function () {
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json(
+ {
+ story: { state: 'started' },
+ },
+ { status: 200 }
+ );
+ })
+ );
+ var ev = { target: { value: 'start' } };
+ await view.transition(ev);
expect(view.saveInProgress).toBeFalsy();
});
- it("should disable estimate buttons on click", function () {
- server.respondWith("PUT", "/path/to/story", [
- 200,
- { "Content-Type": "application/json" },
- '{"story":{"estimate":"1"}}',
- ]);
-
- var ev = { target: { attributes: { "data-value": { value: 1 } } } };
- view.estimate(ev);
-
- expect(view.saveInProgress).toBeTruthy();
-
- server.respond();
+ it('should disable estimate buttons on click', async function () {
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json(
+ {
+ story: { estimate: '1' },
+ },
+ { status: 200 }
+ );
+ })
+ );
+ var ev = { target: { attributes: { 'data-value': { value: 1 } } } };
+ await view.estimate(ev);
expect(view.saveInProgress).toBeFalsy();
});
- it("should call setAcceptedAt on the story", function () {
+ it('should call setAcceptedAt on the story', function () {
+ server.use(
+ http.put(url, () => {
+ return HttpResponse.json({}, { status: 200 });
+ })
+ );
+
view.saveEdit(e);
expect(story.setAcceptedAt).toHaveBeenCalledOnce();
});
});
- describe("expand collapse controls", function () {
- it("should not show the collapse control if its a new story", function () {
+ describe('expand collapse controls', function () {
+ it('should not show the collapse control if its a new story', function () {
new_story.set({ editing: true });
- expect($(new_story_view.el)).not.toContain("a.collapse");
+ expect($(new_story_view.el)).not.toContain('a.collapse');
});
});
- describe("sorting", function () {
+ describe('sorting', function () {
beforeEach(function () {
story.collection.length = 1;
story.collection.columns = function () {
return [];
};
- story.collection.project.columnsBefore = sinon.stub();
- story.collection.project.columnsAfter = sinon.stub();
+ story.collection.project.columnsBefore = vi.fn();
+ story.collection.project.columnsAfter = vi.fn();
});
- it("sets state to unstarted if dropped on the backlog column", function () {
- story.set({ state: "unscheduled" });
+ it('sets state to unstarted if dropped on the backlog column', function () {
+ story.set({ state: 'unscheduled' });
var html = $(' | ');
- var ev = { target: html.find("#story-1") };
+ var ev = { target: html.find('#story-1') };
view.sortUpdate(ev);
- expect(story.get("state")).toEqual("unstarted");
+ expect(story.get('state')).toEqual('unstarted');
});
- it("sets state to unstarted if dropped on the in_progress column", function () {
- story.set({ state: "unscheduled" });
+ it('sets state to unstarted if dropped on the in_progress column', function () {
+ story.set({ state: 'unscheduled' });
var html = $(' | ');
- var ev = { target: html.find("#story-1") };
+ var ev = { target: html.find('#story-1') };
view.sortUpdate(ev);
- expect(story.get("state")).toEqual("unstarted");
+ expect(story.get('state')).toEqual('unstarted');
});
it("doesn't change state if not unscheduled and dropped on the in_progress column", function () {
- story.set({ state: "finished" });
+ story.set({ state: 'finished' });
var html = $(' | ');
- var ev = { target: html.find("#story-1") };
+ var ev = { target: html.find('#story-1') };
view.sortUpdate(ev);
- expect(story.get("state")).toEqual("finished");
+ expect(story.get('state')).toEqual('finished');
});
- it("sets state to unscheduled if dropped on the chilly_bin column", function () {
- story.set({ state: "unstarted" });
+ it('sets state to unscheduled if dropped on the chilly_bin column', function () {
+ story.set({ state: 'unstarted' });
var html = $(' | ');
- var ev = { target: html.find("#story-1") };
+ var ev = { target: html.find('#story-1') };
view.sortUpdate(ev);
- expect(story.get("state")).toEqual("unscheduled");
+ expect(story.get('state')).toEqual('unscheduled');
});
- it("should move after the previous story in the column", function () {
+ it('should move after the previous story in the column', function () {
var html = $(
''
);
var ev = { target: html[1] };
- story.moveAfter = sinon.spy();
+ story.moveAfter = vi.fn();
view.sortUpdate(ev);
expect(story.moveAfter).toHaveBeenCalledWith(1);
});
- it("should move before the next story in the column", function () {
+ it('should move before the next story in the column', function () {
var html = $(
''
);
var ev = { target: html[0] };
- story.moveBefore = sinon.spy();
+ story.moveBefore = vi.fn();
view.sortUpdate(ev);
expect(story.moveBefore).toHaveBeenCalledWith(2);
});
- it("should move before the next story in the column", function () {
+ it('should move before the next story in the column', function () {
var html = $(
''
);
var ev = { target: html[1] };
- story.moveBefore = sinon.spy();
+ story.moveBefore = vi.fn();
view.sortUpdate(ev);
expect(story.moveBefore).toHaveBeenCalledWith(2);
});
- it("should move into an empty chilly bin", function () {
+ it('should move into an empty chilly bin', function () {
var html = $(
' | | '
);
- var ev = { target: html.find("#story-2") };
+ var ev = { target: html.find('#story-2') };
- story.moveAfter = sinon.spy();
+ story.moveAfter = vi.fn();
view.sortUpdate(ev);
- expect(story.get("state")).toEqual("unscheduled");
+ expect(story.get('state')).toEqual('unscheduled');
});
});
- describe("labels", function () {
- it("should initialize tagit on edit", function () {
- var spy = sinon.spy(jQuery.fn, "tagit");
+ describe('labels', function () {
+ it('should initialize tagit on edit', function () {
+ var spy = vi.spyOn(jQuery.fn, 'tagit');
new_story.set({ editing: true });
expect(spy).toHaveBeenCalled();
- spy.restore();
+ spy.mockRestore();
});
});
- describe("notes", function () {
- it("adds a blank note to the end of the notes collection", function () {
+ describe('notes', function () {
+ it('adds a blank note to the end of the notes collection', function () {
view.model.notes.reset();
expect(view.model.notes.length).toEqual(0);
view.addEmptyNote();
@@ -460,18 +508,18 @@ describe("StoryView", function () {
expect(view.model.notes.last().isNew()).toBeTruthy();
});
- describe("when the text area is empty", function () {
- it("disables the add button", function () {
- view.canEdit = sinon.stub().returns(true);
+ describe('when the text area is empty', function () {
+ it('disables the add button', function () {
+ view.canEdit = vi.fn().mockReturnValueOnce(true);
view.render();
- expect(view.$(".add-note").is(":disabled")).toEqual(true);
+ expect(view.$('.add-note').is(':disabled')).toEqual(true);
});
});
it("doesn't add a blank note if the story is new", function () {
- var stub = sinon.stub(view.model, "isNew");
- stub.returns(true);
+ var stub = vi.spyOn(view.model, 'isNew');
+ stub.mockReturnValueOnce(true);
view.model.notes.reset();
expect(view.model.notes.length).toEqual(0);
view.addEmptyNote();
@@ -479,30 +527,30 @@ describe("StoryView", function () {
});
it("doesn't add a blank note if there is already one", function () {
- view.model.notes.last = sinon.stub().returns({
- isNew: sinon.stub().returns(true),
- });
+ view.model.notes.last = vi.fn().mockImplementation(() => ({
+ isNew: vi.fn().mockReturnValue(true),
+ }));
expect(view.model.notes.last().isNew()).toBeTruthy();
var oldLength = view.model.notes.length;
view.addEmptyNote();
expect(view.model.notes.length).toEqual(oldLength);
});
- it("has a note deletion handler", function () {
- const note = { destroy: sinon.stub() };
+ it('has a note deletion handler', function () {
+ const note = { destroy: vi.fn() };
view.handleNoteDelete(note);
expect(note.destroy).toHaveBeenCalled();
});
- it("has a save handler", function () {
- const note = { set: sinon.stub(), save: sinon.stub() };
- view.handleNoteSubmit({ note, newValue: "TestNote" });
+ it('has a save handler', function () {
+ const note = { set: vi.fn(), save: vi.fn() };
+ view.handleNoteSubmit({ note, newValue: 'TestNote' });
expect(note.save).toHaveBeenCalled();
});
});
- describe("tasks", function () {
- it("adds a blank task to the end of the tasks collection", function () {
+ describe('tasks', function () {
+ it('adds a blank task to the end of the tasks collection', function () {
view.model.tasks.reset();
expect(view.model.tasks.length).toEqual(0);
view.addEmptyTask();
@@ -510,16 +558,16 @@ describe("StoryView", function () {
expect(view.model.tasks.last().isNew()).toBeTruthy();
});
- it("disables the add button if the input is empty", function () {
- view.canEdit = sinon.stub().returns(true);
+ it('disables the add button if the input is empty', function () {
+ view.canEdit = vi.fn().mockReturnValueOnce(true);
view.render();
- expect(view.$(".add-task").is(":disabled")).toEqual(true);
+ expect(view.$('.add-task').is(':disabled')).toEqual(true);
});
it("doesn't add a blank task if the story is new", function () {
- var stub = sinon.stub(view.model, "isNew");
- stub.returns(true);
+ var stub = vi.spyOn(view.model, 'isNew');
+ stub.mockReturnValueOnce(true);
view.model.tasks.reset();
expect(view.model.tasks.length).toEqual(0);
view.addEmptyTask();
@@ -527,8 +575,8 @@ describe("StoryView", function () {
});
it("doesn't add a blank task if there is already one", function () {
- view.model.tasks.last = sinon.stub().returns({
- isNew: sinon.stub().returns(true),
+ view.model.tasks.last = vi.fn().mockReturnValueOnce({
+ isNew: vi.fn().mockReturnValueOnce(true),
});
expect(view.model.tasks.last().isNew()).toBeTruthy();
var oldLength = view.model.tasks.length;
@@ -536,20 +584,20 @@ describe("StoryView", function () {
expect(view.model.tasks.length).toEqual(oldLength);
});
- it("has a task deletion handler", function () {
- const task = { destroy: sinon.stub() };
+ it('has a task deletion handler', function () {
+ const task = { destroy: vi.fn() };
view.handleTaskDelete(task);
expect(task.destroy).toHaveBeenCalled();
});
- it("has a submit handler", function () {
- const task = { set: sinon.stub(), save: sinon.stub() };
- view.handleTaskSubmit({ task, taskName: "TestTask" });
+ it('has a submit handler', function () {
+ const task = { set: vi.fn(), save: vi.fn() };
+ view.handleTaskSubmit({ task, taskName: 'TestTask' });
expect(task.save).toHaveBeenCalled();
});
});
- describe("description", function () {
+ describe('description', function () {
beforeEach(function () {
view.model.set({ editing: true });
});
@@ -558,54 +606,57 @@ describe("StoryView", function () {
view.model.set({ editing: false });
});
- it("is text area when story is new", function () {
- view.model.isNew = sinon.stub().returns(true);
- view.canEdit = sinon.stub().returns(true);
+ it('is text area when story is new', function () {
+ view.model.isNew = vi.fn().mockReturnValueOnce(true);
view.render();
expect(view.$('textarea[name="description"]').length).toEqual(1);
- expect(view.$(".description").length).toEqual(0);
+ expect(view.$('.description').length).toEqual(0);
});
it("is text when story isn't new and description isn't empty", function () {
- window.md.makeHtml.returns("foo
");
- view.model.isNew = sinon.stub().returns(false);
- const innerText = "foo";
+ view.model.once('change', () => {
+ expect(window.md.makeHtml).toHaveBeenCalledWith('foo');
+ expect(view.$('textarea[name="description"]').length).toEqual(0);
+ expect(view.$('.description').text()).toContain(innerText);
+ });
+ window.md.makeHtml.mockReturnValueOnce('foo
');
+ view.model.isNew = vi.fn().mockReturnValueOnce(false);
+ const innerText = 'foo';
view.model.set({ description: innerText });
view.render();
- expect(window.md.makeHtml).toHaveBeenCalledWith("foo");
- expect(view.$('textarea[name="description"]').length).toEqual(0);
- expect(view.$(".description").text()).toContain(innerText);
});
it("is a button when story isn't new and description is empty", function () {
- view.model.isNew = sinon.stub().returns(false);
- view.model.set({ description: "" });
+ view.model.once('change', () => {
+ expect(
+ view.$('input[name="edit-description"][type="button"]').length
+ ).toEqual(1);
+ });
+ view.model.isNew = vi.fn().mockReturnValueOnce(false);
+ view.model.set({ description: '' });
view.render();
- expect(
- view.$('input[name="edit-description"][type="button"]').length
- ).toEqual(1);
});
- it("is a text area after .edit-description is clicked", function () {
- const ev = { target: view.$("div.story-description")[0] };
- view.model.isNew = sinon.stub().returns(false);
+ it('is a text area after .edit-description is clicked', function () {
+ const ev = { target: view.$('div.story-description')[0] };
+ view.model.isNew = vi.fn().mockReturnValueOnce(false);
view.editDescription(ev);
- expect(view.model.get("editingDescription")).toBeTruthy();
+ expect(view.model.get('editingDescription')).toBeTruthy();
});
- it("When onChange is triggered should properly set description value", function () {
- const value = "foo";
- view.onChangeModel(value, "description");
- expect(view.model.get("description")).toEqual(value);
+ it('When onChange is triggered should properly set description value', function () {
+ const value = 'foo';
+ view.onChangeModel(value, 'description');
+ expect(view.model.get('description')).toEqual(value);
});
});
- describe("makeFormControl", function () {
+ describe('makeFormControl', function () {
let div;
beforeEach(function () {
div = {};
- view.make = sinon.stub().returns(div);
+ view.make = vi.fn().mockReturnValue(div);
});
it("calls make('div')", function () {
@@ -613,223 +664,223 @@ describe("StoryView", function () {
expect(view.make).toHaveBeenCalled();
});
- it("returns the div", function () {
+ it('returns the div', function () {
expect(view.makeFormControl()).toBe(div);
});
- it("invokes its callback", function () {
- var callback = sinon.stub();
+ it('invokes its callback', function () {
+ var callback = vi.fn();
view.makeFormControl(callback);
expect(callback).toHaveBeenCalledWith(div);
});
- describe("when passed an object", function () {
+ describe('when passed an object', function () {
let _jquery_append;
let content;
let appendSpy;
beforeEach(function () {
- content = { name: "foo", label: "Foo", control: "bar" };
+ content = { name: 'foo', label: 'Foo', control: 'bar' };
_jquery_append = jQuery.fn.append;
- appendSpy = jest.spyOn(jQuery.fn, "append");
+ appendSpy = vi.spyOn(jQuery.fn, 'append');
});
afterEach(function () {
jQuery.fn.append = _jquery_append;
});
- it("creates a label", function () {
+ it('creates a label', function () {
// var label = '';
// view.makeFormControl(content);
// expect(appendSpy).toHaveBeenCalledWith(label);
// expect(appendSpy).toHaveBeenCalledWith('
');
});
- it("appends the control", function () {
+ it('appends the control', function () {
// view.makeFormControl(content);
// expect(appendSpy).toHaveBeenCalledWith(content.control);
});
});
});
- describe("disableEstimate", function () {
- it("disables estimate field when story is not estimable", function () {
- view.model.notEstimable = sinon.stub().returns(true);
- view.canEdit = sinon.stub().returns(true);
+ describe('disableEstimate', function () {
+ it('disables estimate field when story is not estimable', function () {
+ view.model.notEstimable = vi.fn().mockReturnValueOnce(true);
+ view.canEdit = vi.fn().mockReturnValueOnce(true);
view.render();
- expect(view.$(".story_estimate").is(":disabled")).toEqual(true);
+ expect(view.$('.story_estimate').is(':disabled')).toEqual(true);
});
});
- describe("confirms before finish", function () {
+ describe('confirms before finish', function () {
let confirmStub;
beforeEach(function () {
- confirmStub = sinon.stub(window, "confirm");
+ confirmStub = vi.spyOn(window, 'confirm');
});
afterEach(function () {
- confirmStub.restore();
+ confirmStub.mockRestore();
});
- describe("when accepting a story", function () {
- it("should save story when confirmed", function () {
- confirmStub.returns(true);
+ describe('when accepting a story', function () {
+ it('should save story when confirmed', function () {
+ confirmStub.mockReturnValueOnce(true);
- story.set({ state: "delivered" });
+ story.set({ state: 'delivered' });
- var ev = { target: { value: "accept" } };
+ var ev = { target: { value: 'accept' } };
view.transition(ev);
- expect(story.get("state")).toEqual("accepted");
+ expect(story.get('state')).toEqual('accepted');
});
- it("should not save story when not confirmed", function () {
- confirmStub.returns(false);
+ it('should not save story when not confirmed', function () {
+ confirmStub.mockReturnValueOnce(false);
- story.set({ state: "delivered" });
+ story.set({ state: 'delivered' });
- var ev = { target: { value: "accept" } };
+ var ev = { target: { value: 'accept' } };
view.transition(ev);
- expect(story.get("state")).toEqual("delivered");
+ expect(story.get('state')).toEqual('delivered');
});
});
- describe("when rejecteing a story", function () {
- it("should save story when confirmed", function () {
- confirmStub.returns(true);
+ describe('when rejecteing a story', function () {
+ it('should save story when confirmed', function () {
+ confirmStub.mockReturnValueOnce(true);
- story.set({ state: "delivered" });
+ story.set({ state: 'delivered' });
- var ev = { target: { value: "reject" } };
+ var ev = { target: { value: 'reject' } };
view.transition(ev);
- expect(story.get("state")).toEqual("rejected");
+ expect(story.get('state')).toEqual('rejected');
});
- it("should not save story when not confirmed", function () {
- confirmStub.returns(false);
+ it('should not save story when not confirmed', function () {
+ confirmStub.mockReturnValueOnce(false);
- story.set({ state: "delivered" });
+ story.set({ state: 'delivered' });
- var ev = { target: { value: "reject" } };
+ var ev = { target: { value: 'reject' } };
view.transition(ev);
- expect(story.get("state")).toEqual("delivered");
+ expect(story.get('state')).toEqual('delivered');
});
});
});
- describe("toggleControlButtons", function () {
+ describe('toggleControlButtons', function () {
var $storyControls;
beforeEach(function () {
- view.canEdit = sinon.stub().returns(true);
+ view.canEdit = vi.fn().mockReturnValueOnce(true);
view.render();
});
- describe("it render a enabled", function () {
+ describe('it render a enabled', function () {
beforeEach(function () {
view.toggleControlButtons(false);
- $storyControls = view.$el.find(".story-controls");
+ $storyControls = view.$el.find('.story-controls');
});
- it("submit button", function () {
- var submit = $storyControls.find(".submit");
+ it('submit button', function () {
+ var submit = $storyControls.find('.submit');
expect(submit.disabled).toBeFalsy();
});
- it("cancel button", function () {
- var cancel = $storyControls.find(".cancel");
+ it('cancel button', function () {
+ var cancel = $storyControls.find('.cancel');
expect(cancel.disabled).toBeFalsy();
});
- it("destroy button", function () {
- var destroy = $storyControls.find(".destroy");
+ it('destroy button', function () {
+ var destroy = $storyControls.find('.destroy');
expect(destroy.disabled).toBeFalsy();
});
});
- describe("it render a disabled", function () {
+ describe('it render a disabled', function () {
beforeEach(function () {
view.toggleControlButtons(true);
- $storyControls = view.$el.find(".story-controls");
+ $storyControls = view.$el.find('.story-controls');
});
- it("submit button", function () {
- var submit = $storyControls.find(".submit");
+ it('submit button', function () {
+ var submit = $storyControls.find('.submit');
- expect(submit.prop("disabled")).toBeTruthy();
+ expect(submit.prop('disabled')).toBeTruthy();
});
- it("cancel button", function () {
- var cancel = $storyControls.find(".cancel");
+ it('cancel button', function () {
+ var cancel = $storyControls.find('.cancel');
- expect(cancel.prop("disabled")).toBeTruthy();
+ expect(cancel.prop('disabled')).toBeTruthy();
});
- it("destroy button", function () {
- var destroy = $storyControls.find(".submit");
+ it('destroy button', function () {
+ var destroy = $storyControls.find('.submit');
- expect(destroy.prop("disabled")).toBeTruthy();
+ expect(destroy.prop('disabled')).toBeTruthy();
});
});
});
- describe("handleSaveError", function () {
+ describe('handleSaveError', function () {
let model;
beforeEach(function () {
- model = { name: "note", set: sinon.stub() };
- const responseText = JSON.stringify({ note: { errors: "Error" } });
+ model = { name: 'note', set: vi.fn() };
+ const responseText = JSON.stringify({ note: { errors: 'Error' } });
const response = { responseText };
view.handleSaveError(model, response);
});
- it("shows the errors", function () {
+ it('shows the errors', function () {
expect(window.projectView.noticeSaveError).toHaveBeenCalledWith(model);
});
it("set the model's errors", function () {
- expect(model.set).toHaveBeenCalledWith({ errors: "Error" });
+ expect(model.set).toHaveBeenCalledWith({ errors: 'Error' });
});
});
- describe("transition buttons", function () {
- ["started", "finished", "delivered", "rejected"].forEach(function (state) {
+ describe('transition buttons', function () {
+ ['started', 'finished', 'delivered', 'rejected'].forEach(function (state) {
describe(`when state is "${state}"`, function () {
- it("shows transition buttons", function () {
+ it('shows transition buttons', function () {
story.set({ state });
- story.estimable = sinon.stub().returns(false);
+ story.estimable = vi.fn().mockReturnValueOnce(false);
view.render();
- expect(view.$el.html()).toContain("data-story-state-buttons");
+ expect(view.$el.html()).toContain('data-story-state-buttons');
});
});
});
describe('when state is "accepted"', function () {
- it("does not show transition buttons", function () {
- story.set({ state: "accepted" });
- story.estimable = sinon.stub().returns(false);
+ it('does not show transition buttons', function () {
+ story.set({ state: 'accepted' });
+ story.estimable = vi.fn().mockReturnValueOnce(false);
view.render();
- expect(view.$el.html()).not.toContain("data-story-state-buttons");
+ expect(view.$el.html()).not.toContain('data-story-state-buttons');
});
- it("does not show save or delete buttons", function () {
+ it('does not show save or delete buttons', function () {
var $storyControls;
- view.canEdit = sinon.stub().returns(true);
+ view.model.once('change', () => {
+ $storyControls = view.$el[0];
+ expect($storyControls.classList).not.toContain('submit');
+ });
view.render();
- story.set({ state: "accepted" });
- $storyControls = view.$el[0];
-
- expect($storyControls).not.toContain(".submit");
+ story.set({ state: 'accepted' });
});
});
});
diff --git a/vite.base.config.ts b/vite.base.config.ts
new file mode 100644
index 000000000..47625591e
--- /dev/null
+++ b/vite.base.config.ts
@@ -0,0 +1,43 @@
+import { defineConfig } from 'vite';
+import path from 'path';
+import PrecompileEjs from './app/assets/javascripts/libs/precompile_ejs';
+
+const aliasMap = {
+ vendor: path.join(__dirname, 'vendor/assets/javascripts'),
+ collections: path.join(__dirname, 'app/assets/javascripts/collections'),
+ mixins: path.join(__dirname, 'app/assets/javascripts/mixins'),
+ models: path.join(__dirname, 'app/assets/javascripts/models'),
+ templates: path.join(__dirname, 'app/assets/javascripts/templates'),
+ views: path.join(__dirname, 'app/assets/javascripts/views'),
+ libs: path.join(__dirname, 'app/assets/javascripts/libs'),
+ components: path.join(__dirname, 'app/assets/javascripts/components'),
+ controllers: path.join(__dirname, 'app/assets/javascripts/controllers'),
+ reducers: path.join(__dirname, 'app/assets/javascripts/reducers'),
+ actions: path.join(__dirname, 'app/assets/javascripts/actions'),
+ central: path.join(__dirname, 'app/assets/javascripts/central'),
+ store: path.join(__dirname, 'app/assets/javascripts/store'),
+ gritter: 'gritter/js/jquery.gritter.min.js',
+};
+
+const alias = Object.entries(aliasMap).map(([key, value]) => ({
+ find: key,
+ replacement: value,
+}));
+
+export default defineConfig({
+ plugins: [PrecompileEjs()],
+ esbuild: {
+ loader: 'jsx',
+ include: [
+ 'app/**/*.jsx',
+ 'spec/javascripts/**/*.jsx',
+ // Add these lines to allow all .js files to contain JSX
+ 'app/**/*.js',
+ 'spec/javascripts/**/*.js',
+ ],
+ exclude: [],
+ },
+ resolve: {
+ alias: [...alias],
+ },
+});
diff --git a/vite.config.ts b/vite.config.ts
index c8d6ea3e5..fe680e283 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,44 +1,11 @@
-import { defineConfig } from 'vite'
-import RubyPlugin from 'vite-plugin-ruby'
-import path from 'path'
-import PrecompileEjs from './app/assets/javascripts/libs/precompile_ejs'
+import { mergeConfig } from 'vitest/config';
+import { defineConfig } from 'vite';
+import RubyPlugin from 'vite-plugin-ruby';
+import viteBaseConfig from './vite.base.config';
-const aliasMap = {
- vendor: path.join(__dirname, 'vendor/assets/javascripts'),
- collections: path.join(__dirname, 'app/assets/javascripts/collections'),
- mixins: path.join(__dirname, 'app/assets/javascripts/mixins'),
- models: path.join(__dirname, 'app/assets/javascripts/models'),
- templates: path.join(__dirname, 'app/assets/javascripts/templates'),
- views: path.join(__dirname, 'app/assets/javascripts/views'),
- libs: path.join(__dirname, 'app/assets/javascripts/libs'),
- components: path.join(__dirname, 'app/assets/javascripts/components'),
- controllers: path.join(__dirname, 'app/assets/javascripts/controllers'),
- reducers: path.join(__dirname, 'app/assets/javascripts/reducers'),
- actions: path.join(__dirname, 'app/assets/javascripts/actions'),
- central: path.join(__dirname, 'app/assets/javascripts/central'),
- store: path.join(__dirname, 'app/assets/javascripts/store'),
- gritter: 'gritter/js/jquery.gritter.min.js',
-}
-
-const alias = Object.entries(aliasMap).map(([key, value]) => ({ find: key, replacement: value }))
-
-export default defineConfig({
- plugins: [
- RubyPlugin(),
- PrecompileEjs()
- ],
- esbuild: {
- loader: "jsx",
- include: [
- "app/**/*.jsx",
- // Add these lines to allow all .js files to contain JSX
- "app/**/*.js",
- ],
- exclude: [],
- },
- resolve: {
- alias: [
- ...alias,
- ]
- }
-})
+export default mergeConfig(
+ viteBaseConfig,
+ defineConfig({
+ plugins: [RubyPlugin()],
+ })
+);
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 000000000..555a16104
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig, mergeConfig } from 'vitest/config';
+import viteBaseConfig from './vite.base.config';
+import path from 'path';
+
+export default mergeConfig(
+ viteBaseConfig,
+ defineConfig({
+ test: {
+ include: [
+ 'spec/javascripts/**/*_spec.js',
+ 'spec/javascripts/**/*_spec.jsx',
+ ],
+ globals: true,
+ setupFiles: path.join(__dirname, 'spec/javascripts/support/setup.js'),
+ environment: 'jsdom',
+ },
+ })
+);
diff --git a/yarn.lock b/yarn.lock
index 994d8c8d0..97101daae 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10,7 +10,7 @@
"@jridgewell/gen-mapping" "^0.1.0"
"@jridgewell/trace-mapping" "^0.3.9"
-"@ampproject/remapping@^2.2.0":
+"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.3.0":
version "2.3.0"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==
@@ -18,7 +18,7 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
@@ -50,7 +50,7 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.2.tgz#e41928bd33475305c586f6acbbb7e3ade7a6f7f5"
integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==
-"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5":
+"@babel/core@^7.1.0":
version "7.18.5"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.5.tgz#c597fa680e58d571c28dda9827669c78cdd7f000"
integrity sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==
@@ -431,7 +431,7 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.18.5", "@babel/parser@^7.4.3":
+"@babel/parser@^7.1.0", "@babel/parser@^7.16.7", "@babel/parser@^7.18.5", "@babel/parser@^7.4.3":
version "7.18.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.5.tgz#337062363436a893a2d22faa60be5bb37091c83c"
integrity sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==
@@ -594,14 +594,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
-"@babel/plugin-syntax-bigint@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea"
- integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.8.0"
-
-"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3":
+"@babel/plugin-syntax-class-properties@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
@@ -636,13 +629,6 @@
dependencies:
"@babel/helper-plugin-utils" "^7.17.12"
-"@babel/plugin-syntax-import-meta@^7.8.3":
- version "7.10.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
- integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
- dependencies:
- "@babel/helper-plugin-utils" "^7.10.4"
-
"@babel/plugin-syntax-json-strings@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
@@ -657,7 +643,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.17.12"
-"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
+"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==
@@ -671,7 +657,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
-"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3":
+"@babel/plugin-syntax-numeric-separator@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97"
integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==
@@ -706,7 +692,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3":
+"@babel/plugin-syntax-top-level-await@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c"
integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==
@@ -1198,7 +1184,7 @@
dependencies:
regenerator-runtime "^0.13.11"
-"@babel/template@^7.16.7", "@babel/template@^7.3.3", "@babel/template@^7.4.0":
+"@babel/template@^7.16.7", "@babel/template@^7.4.0":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
@@ -1216,7 +1202,7 @@
"@babel/parser" "^7.25.0"
"@babel/types" "^7.25.0"
-"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2", "@babel/traverse@^7.18.5", "@babel/traverse@^7.4.3":
+"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2", "@babel/traverse@^7.18.5", "@babel/traverse@^7.4.3":
version "7.18.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.5.tgz#94a8195ad9642801837988ab77f36e992d9a20cd"
integrity sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==
@@ -1245,7 +1231,7 @@
debug "^4.3.1"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.17.12", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0", "@babel/types@^7.4.4":
+"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.17.12", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4":
version "7.18.4"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354"
integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==
@@ -1262,10 +1248,27 @@
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"
-"@bcoe/v8-coverage@^0.2.3":
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
- integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+"@bundled-es-modules/cookie@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz#c3b82703969a61cf6a46e959a012b2c257f6b164"
+ integrity sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==
+ dependencies:
+ cookie "^0.5.0"
+
+"@bundled-es-modules/statuses@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz#761d10f44e51a94902c4da48675b71a76cc98872"
+ integrity sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==
+ dependencies:
+ statuses "^2.0.1"
+
+"@bundled-es-modules/tough-cookie@^0.1.6":
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz#fa9cd3cedfeecd6783e8b0d378b4a99e52bde5d3"
+ integrity sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==
+ dependencies:
+ "@types/tough-cookie" "^4.0.5"
+ tough-cookie "^4.1.4"
"@cnakazawa/watch@^1.0.3":
version "1.0.4"
@@ -1322,116 +1325,231 @@
debug "^3.1.0"
lodash.once "^4.1.1"
+"@esbuild/aix-ppc64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
+ integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==
+
"@esbuild/android-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
+"@esbuild/android-arm64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052"
+ integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==
+
"@esbuild/android-arm@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
+"@esbuild/android-arm@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28"
+ integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==
+
"@esbuild/android-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
+"@esbuild/android-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e"
+ integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==
+
"@esbuild/darwin-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
+"@esbuild/darwin-arm64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a"
+ integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==
+
"@esbuild/darwin-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
+"@esbuild/darwin-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22"
+ integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==
+
"@esbuild/freebsd-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
+"@esbuild/freebsd-arm64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e"
+ integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==
+
"@esbuild/freebsd-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
+"@esbuild/freebsd-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261"
+ integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==
+
"@esbuild/linux-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
+"@esbuild/linux-arm64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b"
+ integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==
+
"@esbuild/linux-arm@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
+"@esbuild/linux-arm@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9"
+ integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==
+
"@esbuild/linux-ia32@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
+"@esbuild/linux-ia32@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2"
+ integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==
+
"@esbuild/linux-loong64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
+"@esbuild/linux-loong64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df"
+ integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==
+
"@esbuild/linux-mips64el@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
+"@esbuild/linux-mips64el@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe"
+ integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==
+
"@esbuild/linux-ppc64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
+"@esbuild/linux-ppc64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4"
+ integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==
+
"@esbuild/linux-riscv64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
+"@esbuild/linux-riscv64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc"
+ integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==
+
"@esbuild/linux-s390x@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
+"@esbuild/linux-s390x@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de"
+ integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==
+
"@esbuild/linux-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
+"@esbuild/linux-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0"
+ integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==
+
"@esbuild/netbsd-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
+"@esbuild/netbsd-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047"
+ integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
+
"@esbuild/openbsd-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
+"@esbuild/openbsd-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70"
+ integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
+
"@esbuild/sunos-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
+"@esbuild/sunos-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b"
+ integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==
+
"@esbuild/win32-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
+"@esbuild/win32-arm64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d"
+ integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==
+
"@esbuild/win32-ia32@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
+"@esbuild/win32-ia32@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b"
+ integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==
+
"@esbuild/win32-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
+"@esbuild/win32-x64@0.21.5":
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c"
+ integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
+
"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -1525,21 +1643,44 @@
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==
-"@istanbuljs/load-nyc-config@^1.0.0":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
- integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==
+"@inquirer/confirm@^3.0.0":
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.2.0.tgz#6af1284670ea7c7d95e3f1253684cfbd7228ad6a"
+ integrity sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==
dependencies:
- camelcase "^5.3.1"
- find-up "^4.1.0"
- get-package-type "^0.1.0"
- js-yaml "^3.13.1"
- resolve-from "^5.0.0"
+ "@inquirer/core" "^9.1.0"
+ "@inquirer/type" "^1.5.3"
-"@istanbuljs/schema@^0.1.2":
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
- integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
+"@inquirer/core@^9.1.0":
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-9.1.0.tgz#158b82dc44564a1abd0ce14723d50c3efa0634a2"
+ integrity sha512-RZVfH//2ytTjmaBIzeKT1zefcQZzuruwkpTwwbe/i2jTl4o9M+iML5ChULzz6iw1Ok8iUBBsRCjY2IEbD8Ft4w==
+ dependencies:
+ "@inquirer/figures" "^1.0.5"
+ "@inquirer/type" "^1.5.3"
+ "@types/mute-stream" "^0.0.4"
+ "@types/node" "^22.5.2"
+ "@types/wrap-ansi" "^3.0.0"
+ ansi-escapes "^4.3.2"
+ cli-spinners "^2.9.2"
+ cli-width "^4.1.0"
+ mute-stream "^1.0.0"
+ signal-exit "^4.1.0"
+ strip-ansi "^6.0.1"
+ wrap-ansi "^6.2.0"
+ yoctocolors-cjs "^2.1.2"
+
+"@inquirer/figures@^1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.5.tgz#57f9a996d64d3e3345d2a3ca04d36912e94f8790"
+ integrity sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==
+
+"@inquirer/type@^1.5.3":
+ version "1.5.3"
+ resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.5.3.tgz#220ae9f3d5ae17dd3b2ce5ffd6b48c4a30c73181"
+ integrity sha512-xUQ14WQGR/HK5ei+2CvgcwoH9fQ4PgPGmVFSN0pc1+fVyDL3MREhyAY7nxEErSu6CkllBM3D7e3e+kOvtu+eIg==
+ dependencies:
+ mute-stream "^1.0.0"
"@jest/console@^24.9.0":
version "24.9.0"
@@ -1550,79 +1691,6 @@
chalk "^2.0.1"
slash "^2.0.0"
-"@jest/console@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2"
- integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- chalk "^4.0.0"
- jest-message-util "^26.6.2"
- jest-util "^26.6.2"
- slash "^3.0.0"
-
-"@jest/core@^26.6.3":
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad"
- integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/reporters" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- ansi-escapes "^4.2.1"
- chalk "^4.0.0"
- exit "^0.1.2"
- graceful-fs "^4.2.4"
- jest-changed-files "^26.6.2"
- jest-config "^26.6.3"
- jest-haste-map "^26.6.2"
- jest-message-util "^26.6.2"
- jest-regex-util "^26.0.0"
- jest-resolve "^26.6.2"
- jest-resolve-dependencies "^26.6.3"
- jest-runner "^26.6.3"
- jest-runtime "^26.6.3"
- jest-snapshot "^26.6.2"
- jest-util "^26.6.2"
- jest-validate "^26.6.2"
- jest-watcher "^26.6.2"
- micromatch "^4.0.2"
- p-each-series "^2.1.0"
- rimraf "^3.0.0"
- slash "^3.0.0"
- strip-ansi "^6.0.0"
-
-"@jest/environment@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18"
- integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==
- dependencies:
- "@jest/fake-timers" "^24.9.0"
- "@jest/transform" "^24.9.0"
- "@jest/types" "^24.9.0"
- jest-mock "^24.9.0"
-
-"@jest/environment@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c"
- integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==
- dependencies:
- "@jest/fake-timers" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- jest-mock "^26.6.2"
-
-"@jest/expect-utils@^28.1.1":
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.1.tgz#d84c346025b9f6f3886d02c48a6177e2b0360587"
- integrity sha512-n/ghlvdhCdMI/hTcnn4qV57kQuV9OTsZzH1TTCVARANKhl6hXJqLKUkwX69ftMGpsbpt96SsDD8n8LD2d9+FRw==
- dependencies:
- jest-get-type "^28.0.2"
-
"@jest/fake-timers@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93"
@@ -1632,66 +1700,6 @@
jest-message-util "^24.9.0"
jest-mock "^24.9.0"
-"@jest/fake-timers@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad"
- integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==
- dependencies:
- "@jest/types" "^26.6.2"
- "@sinonjs/fake-timers" "^6.0.1"
- "@types/node" "*"
- jest-message-util "^26.6.2"
- jest-mock "^26.6.2"
- jest-util "^26.6.2"
-
-"@jest/globals@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a"
- integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==
- dependencies:
- "@jest/environment" "^26.6.2"
- "@jest/types" "^26.6.2"
- expect "^26.6.2"
-
-"@jest/reporters@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6"
- integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==
- dependencies:
- "@bcoe/v8-coverage" "^0.2.3"
- "@jest/console" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- chalk "^4.0.0"
- collect-v8-coverage "^1.0.0"
- exit "^0.1.2"
- glob "^7.1.2"
- graceful-fs "^4.2.4"
- istanbul-lib-coverage "^3.0.0"
- istanbul-lib-instrument "^4.0.3"
- istanbul-lib-report "^3.0.0"
- istanbul-lib-source-maps "^4.0.0"
- istanbul-reports "^3.0.2"
- jest-haste-map "^26.6.2"
- jest-resolve "^26.6.2"
- jest-util "^26.6.2"
- jest-worker "^26.6.2"
- slash "^3.0.0"
- source-map "^0.6.0"
- string-length "^4.0.1"
- terminal-link "^2.0.0"
- v8-to-istanbul "^7.0.0"
- optionalDependencies:
- node-notifier "^8.0.0"
-
-"@jest/schemas@^28.0.2":
- version "28.0.2"
- resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.0.2.tgz#08c30df6a8d07eafea0aef9fb222c5e26d72e613"
- integrity sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==
- dependencies:
- "@sinclair/typebox" "^0.23.3"
-
"@jest/source-map@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714"
@@ -1701,15 +1709,6 @@
graceful-fs "^4.1.15"
source-map "^0.6.0"
-"@jest/source-map@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535"
- integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==
- dependencies:
- callsites "^3.0.0"
- graceful-fs "^4.2.4"
- source-map "^0.6.0"
-
"@jest/test-result@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca"
@@ -1719,27 +1718,6 @@
"@jest/types" "^24.9.0"
"@types/istanbul-lib-coverage" "^2.0.0"
-"@jest/test-result@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18"
- integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/istanbul-lib-coverage" "^2.0.0"
- collect-v8-coverage "^1.0.0"
-
-"@jest/test-sequencer@^26.6.3":
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17"
- integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==
- dependencies:
- "@jest/test-result" "^26.6.2"
- graceful-fs "^4.2.4"
- jest-haste-map "^26.6.2"
- jest-runner "^26.6.3"
- jest-runtime "^26.6.3"
-
"@jest/transform@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56"
@@ -1762,27 +1740,6 @@
source-map "^0.6.1"
write-file-atomic "2.4.1"
-"@jest/transform@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b"
- integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==
- dependencies:
- "@babel/core" "^7.1.0"
- "@jest/types" "^26.6.2"
- babel-plugin-istanbul "^6.0.0"
- chalk "^4.0.0"
- convert-source-map "^1.4.0"
- fast-json-stable-stringify "^2.0.0"
- graceful-fs "^4.2.4"
- jest-haste-map "^26.6.2"
- jest-regex-util "^26.0.0"
- jest-util "^26.6.2"
- micromatch "^4.0.2"
- pirates "^4.0.1"
- slash "^3.0.0"
- source-map "^0.6.1"
- write-file-atomic "^3.0.0"
-
"@jest/types@^24.9.0":
version "24.9.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
@@ -1792,29 +1749,6 @@
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^13.0.0"
-"@jest/types@^26.6.2":
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
- integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^3.0.0"
- "@types/node" "*"
- "@types/yargs" "^15.0.0"
- chalk "^4.0.0"
-
-"@jest/types@^28.1.1":
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.1.tgz#d059bbc80e6da6eda9f081f293299348bd78ee0b"
- integrity sha512-vRXVqSg1VhDnB8bWcmvLzmg0Bt9CRKVgHPXqYwvWMX3TvAjeO+nRuK6+VdTKCtWOvYlmkF/HqNAL/z+N3B53Kw==
- dependencies:
- "@jest/schemas" "^28.0.2"
- "@types/istanbul-lib-coverage" "^2.0.0"
- "@types/istanbul-reports" "^3.0.0"
- "@types/node" "*"
- "@types/yargs" "^17.0.8"
- chalk "^4.0.0"
-
"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
@@ -1866,7 +1800,7 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c"
integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==
-"@jridgewell/sourcemap-codec@^1.4.14":
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
@@ -1892,6 +1826,18 @@
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
+"@mswjs/interceptors@^0.35.0":
+ version "0.35.0"
+ resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.35.0.tgz#ccdabb668833b97d3c5f26e761f5ea665629dd5f"
+ integrity sha512-f5cHyIvm4m4g1I5x9EH1etGx0puaU0OaX2szqGRVBVgUC6aMASlOI5hbpe7tJ9l4/VWjCUu5OMraCazLZGI24A==
+ dependencies:
+ "@open-draft/deferred-promise" "^2.2.0"
+ "@open-draft/logger" "^0.3.0"
+ "@open-draft/until" "^2.0.0"
+ is-node-process "^1.2.0"
+ outvariant "^1.4.3"
+ strict-event-emitter "^0.5.1"
+
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
@@ -1936,51 +1882,108 @@
mkdirp "^1.0.4"
rimraf "^3.0.2"
-"@pkgr/core@^0.1.0":
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
- integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
-
-"@sinclair/typebox@^0.23.3":
- version "0.23.5"
- resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d"
- integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==
-
-"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0":
- version "1.8.3"
- resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
- integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==
- dependencies:
- type-detect "4.0.8"
+"@open-draft/deferred-promise@^2.2.0":
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd"
+ integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==
-"@sinonjs/fake-timers@^6.0.1":
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40"
- integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==
+"@open-draft/logger@^0.3.0":
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954"
+ integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==
dependencies:
- "@sinonjs/commons" "^1.7.0"
+ is-node-process "^1.2.0"
+ outvariant "^1.4.0"
-"@sinonjs/formatio@^3.2.1":
- version "3.2.2"
- resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c"
- integrity sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==
- dependencies:
- "@sinonjs/commons" "^1"
- "@sinonjs/samsam" "^3.1.0"
+"@open-draft/until@^2.0.0", "@open-draft/until@^2.1.0":
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda"
+ integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==
-"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.3":
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.3.tgz#46682efd9967b259b81136b9f120fd54585feb4a"
- integrity sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==
- dependencies:
- "@sinonjs/commons" "^1.3.0"
- array-from "^2.1.1"
- lodash "^4.17.15"
+"@pkgr/core@^0.1.0":
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
+ integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
-"@sinonjs/text-encoding@^0.7.1":
- version "0.7.1"
- resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
- integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
+"@rollup/rollup-android-arm-eabi@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz#0412834dc423d1ff7be4cb1fc13a86a0cd262c11"
+ integrity sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==
+
+"@rollup/rollup-android-arm64@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz#baf1a014b13654f3b9e835388df9caf8c35389cb"
+ integrity sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==
+
+"@rollup/rollup-darwin-arm64@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz#0a2c364e775acdf1172fe3327662eec7c46e55b1"
+ integrity sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==
+
+"@rollup/rollup-darwin-x64@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz#a972db75890dfab8df0da228c28993220a468c42"
+ integrity sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz#1609d0630ef61109dd19a278353e5176d92e30a1"
+ integrity sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==
+
+"@rollup/rollup-linux-arm-musleabihf@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz#3c1dca5f160aa2e79e4b20ff6395eab21804f266"
+ integrity sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==
+
+"@rollup/rollup-linux-arm64-gnu@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz#c2fe376e8b04eafb52a286668a8df7c761470ac7"
+ integrity sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==
+
+"@rollup/rollup-linux-arm64-musl@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz#e62a4235f01e0f66dbba587c087ca6db8008ec80"
+ integrity sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==
+
+"@rollup/rollup-linux-powerpc64le-gnu@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz#24b3457e75ee9ae5b1c198bd39eea53222a74e54"
+ integrity sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==
+
+"@rollup/rollup-linux-riscv64-gnu@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz#38edfba9620fe2ca8116c97e02bd9f2d606bde09"
+ integrity sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==
+
+"@rollup/rollup-linux-s390x-gnu@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz#a3bfb8bc5f1e802f8c76cff4a4be2e9f9ac36a18"
+ integrity sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==
+
+"@rollup/rollup-linux-x64-gnu@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz#0dadf34be9199fcdda44b5985a086326344f30ad"
+ integrity sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==
+
+"@rollup/rollup-linux-x64-musl@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz#7b7deddce240400eb87f2406a445061b4fed99a8"
+ integrity sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==
+
+"@rollup/rollup-win32-arm64-msvc@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz#a0ca0c5149c2cfb26fab32e6ba3f16996fbdb504"
+ integrity sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==
+
+"@rollup/rollup-win32-ia32-msvc@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz#aae2886beec3024203dbb5569db3a137bc385f8e"
+ integrity sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==
+
+"@rollup/rollup-win32-x64-msvc@4.21.2":
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz#e4291e3c1bc637083f87936c333cdbcad22af63b"
+ integrity sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==
"@testing-library/dom@^8.0.0":
version "8.19.0"
@@ -2035,7 +2038,7 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==
-"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.7":
+"@types/babel__core@^7.1.0":
version "7.1.19"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460"
integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==
@@ -2061,20 +2064,13 @@
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
-"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6":
+"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6":
version "7.17.1"
resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.1.tgz#1a0e73e8c28c7e832656db372b779bfd2ef37314"
integrity sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==
dependencies:
"@babel/types" "^7.3.0"
-"@types/cheerio@^0.22.22":
- version "0.22.31"
- resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.31.tgz#b8538100653d6bb1b08a1e46dec75b4f2a5d5eb6"
- integrity sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==
- dependencies:
- "@types/node" "*"
-
"@types/clipboard@^2.0.1":
version "2.0.7"
resolved "https://registry.yarnpkg.com/@types/clipboard/-/clipboard-2.0.7.tgz#db578ceec578947be2d603b003667ebdd5f274e1"
@@ -2082,17 +2078,20 @@
dependencies:
clipboard "*"
+"@types/cookie@^0.6.0":
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5"
+ integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
+
"@types/domhandler@2.4.1":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@types/domhandler/-/domhandler-2.4.1.tgz#7b3b347f7762180fbcb1ece1ce3dd0ebbb8c64cf"
integrity sha512-cfBw6q6tT5sa1gSPFSRKzF/xxYrrmeiut7E0TxNBObiLSBTuFEHibcfEe3waQPEDbqBsq+ql/TOniw65EyDFMA==
-"@types/graceful-fs@^4.1.2":
- version "4.1.5"
- resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
- integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
- dependencies:
- "@types/node" "*"
+"@types/estree@1.0.5", "@types/estree@^1.0.0":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
+ integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/hoist-non-react-statics@^3.3.0":
version "3.3.1"
@@ -2102,7 +2101,7 @@
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
-"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44"
integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==
@@ -2122,13 +2121,6 @@
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
-"@types/istanbul-reports@^3.0.0":
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff"
- integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==
- dependencies:
- "@types/istanbul-lib-report" "*"
-
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -2139,6 +2131,13 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
+"@types/mute-stream@^0.0.4":
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478"
+ integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==
+ dependencies:
+ "@types/node" "*"
+
"@types/node@*":
version "18.0.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
@@ -2149,16 +2148,18 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.21.tgz#0155ee46f6be28b2ff0342ca1a9b9fd4468bef41"
integrity sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q==
+"@types/node@^22.5.2":
+ version "22.5.4"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.4.tgz#83f7d1f65bc2ed223bdbf57c7884f1d5a4fa84e8"
+ integrity sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==
+ dependencies:
+ undici-types "~6.19.2"
+
"@types/normalize-package-data@^2.4.0":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==
-"@types/prettier@^2.0.0":
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.3.tgz#68ada76827b0010d0db071f739314fa429943d0a"
- integrity sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==
-
"@types/prop-types@*":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
@@ -2219,10 +2220,20 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
-"@types/stack-utils@^2.0.0":
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
- integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
+"@types/statuses@^2.0.4":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.5.tgz#f61ab46d5352fd73c863a1ea4e1cef3b0b51ae63"
+ integrity sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==
+
+"@types/tough-cookie@^4.0.5":
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304"
+ integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==
+
+"@types/wrap-ansi@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd"
+ integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==
"@types/yargs-parser@*":
version "21.0.0"
@@ -2236,20 +2247,6 @@
dependencies:
"@types/yargs-parser" "*"
-"@types/yargs@^15.0.0":
- version "15.0.14"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06"
- integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==
- dependencies:
- "@types/yargs-parser" "*"
-
-"@types/yargs@^17.0.8":
- version "17.0.10"
- resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a"
- integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==
- dependencies:
- "@types/yargs-parser" "*"
-
"@types/yauzl@^2.9.1":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599"
@@ -2262,67 +2259,67 @@
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406"
integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
-abab@^2.0.0, abab@^2.0.3, abab@^2.0.5:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
- integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
+"@vitest/expect@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86"
+ integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==
+ dependencies:
+ "@vitest/spy" "2.0.5"
+ "@vitest/utils" "2.0.5"
+ chai "^5.1.1"
+ tinyrainbow "^1.2.0"
-abbrev@1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
- integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
+"@vitest/pretty-format@2.0.5", "@vitest/pretty-format@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e"
+ integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==
+ dependencies:
+ tinyrainbow "^1.2.0"
-acorn-globals@^4.1.0:
- version "4.3.4"
- resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
- integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==
+"@vitest/runner@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.0.5.tgz#89197e712bb93513537d6876995a4843392b2a84"
+ integrity sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==
dependencies:
- acorn "^6.0.1"
- acorn-walk "^6.0.1"
+ "@vitest/utils" "2.0.5"
+ pathe "^1.1.2"
-acorn-globals@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
- integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==
+"@vitest/snapshot@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.0.5.tgz#a2346bc5013b73c44670c277c430e0334690a162"
+ integrity sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==
+ dependencies:
+ "@vitest/pretty-format" "2.0.5"
+ magic-string "^0.30.10"
+ pathe "^1.1.2"
+
+"@vitest/spy@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f"
+ integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==
+ dependencies:
+ tinyspy "^3.0.0"
+
+"@vitest/utils@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926"
+ integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==
dependencies:
- acorn "^7.1.1"
- acorn-walk "^7.1.1"
+ "@vitest/pretty-format" "2.0.5"
+ estree-walker "^3.0.3"
+ loupe "^3.1.1"
+ tinyrainbow "^1.2.0"
+
+abbrev@1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
+ integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-acorn-walk@^6.0.1:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
- integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
-
-acorn-walk@^7.1.1:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
- integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
-
-acorn@^5.5.3:
- version "5.7.4"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
- integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
-
-acorn@^6.0.1:
- version "6.4.2"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
- integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
-
-acorn@^7.1.1:
- version "7.4.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
- integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
-
-acorn@^8.2.4:
- version "8.7.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
- integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
-
acorn@^8.9.0:
version "8.12.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248"
@@ -2335,6 +2332,13 @@ agent-base@6, agent-base@^6.0.2:
dependencies:
debug "4"
+agent-base@^7.0.2, agent-base@^7.1.0:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317"
+ integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==
+ dependencies:
+ debug "^4.3.4"
+
agentkeepalive@^4.1.3:
version "4.2.1"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717"
@@ -2352,21 +2356,6 @@ aggregate-error@^3.0.0:
clean-stack "^2.0.0"
indent-string "^4.0.0"
-airbnb-prop-types@^2.16.0:
- version "2.16.0"
- resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz#b96274cefa1abb14f623f804173ee97c13971dc2"
- integrity sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==
- dependencies:
- array.prototype.find "^2.1.1"
- function.prototype.name "^1.1.2"
- is-regex "^1.1.0"
- object-is "^1.1.2"
- object.assign "^4.1.0"
- object.entries "^1.1.2"
- prop-types "^15.7.2"
- prop-types-exact "^1.2.0"
- react-is "^16.13.1"
-
ajv@^6.12.3, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
@@ -2382,7 +2371,7 @@ ansi-colors@^4.1.1:
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
-ansi-escapes@^4.2.1, ansi-escapes@^4.3.0:
+ansi-escapes@^4.3.0, ansi-escapes@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
@@ -2406,7 +2395,7 @@ ansi-regex@^4.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
-ansi-regex@^5.0.0, ansi-regex@^5.0.1:
+ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
@@ -2458,14 +2447,6 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
-anymatch@^3.0.3:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
- integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
- dependencies:
- normalize-path "^3.0.0"
- picomatch "^2.0.4"
-
"aproba@^1.0.3 || ^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
@@ -2534,16 +2515,6 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==
-array-equal@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
- integrity sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA==
-
-array-from@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195"
- integrity sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==
-
array-includes@^3.1.4, array-includes@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
@@ -2560,28 +2531,7 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==
-array.prototype.filter@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.1.tgz#20688792acdb97a09488eaaee9eebbf3966aae21"
- integrity sha512-Dk3Ty7N42Odk7PjU/Ci3zT4pLj20YvuVnneG/58ICM6bt4Ij5kZaJTVQ9TSaWaIECX2sFyz4KItkVZqHNnciqw==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.0"
- es-array-method-boxes-properly "^1.0.0"
- is-string "^1.0.7"
-
-array.prototype.find@^2.1.1:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.2.0.tgz#153b8a28ad8965cd86d3117b07e6596af6f2880d"
- integrity sha512-sn40qmUiLYAcRb/1HsIQjTTZ1kCy8II8VtZJpMn2Aoen9twULhbWXisfh3HimGqMlHGUul0/TfKCnXg42LuPpQ==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.4"
- es-shim-unscopables "^1.0.0"
-
-array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5:
+array.prototype.flat@^1.2.5:
version "1.3.0"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b"
integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==
@@ -2629,6 +2579,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
+assertion-error@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7"
+ integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==
+
assign-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
@@ -2649,11 +2604,6 @@ async-foreach@^0.1.3:
resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
integrity sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==
-async-limiter@~1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
- integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
-
async@^3.2.0, async@^3.2.3:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
@@ -2737,20 +2687,6 @@ babel-jest@^24.9.0:
chalk "^2.4.2"
slash "^2.0.0"
-babel-jest@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056"
- integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==
- dependencies:
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/babel__core" "^7.1.7"
- babel-plugin-istanbul "^6.0.0"
- babel-preset-jest "^26.6.2"
- chalk "^4.0.0"
- graceful-fs "^4.2.4"
- slash "^3.0.0"
-
babel-plugin-dynamic-import-node@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3"
@@ -2768,17 +2704,6 @@ babel-plugin-istanbul@^5.1.0:
istanbul-lib-instrument "^3.3.0"
test-exclude "^5.2.3"
-babel-plugin-istanbul@^6.0.0:
- version "6.1.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73"
- integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@istanbuljs/load-nyc-config" "^1.0.0"
- "@istanbuljs/schema" "^0.1.2"
- istanbul-lib-instrument "^5.0.4"
- test-exclude "^6.0.0"
-
babel-plugin-jest-hoist@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756"
@@ -2786,16 +2711,6 @@ babel-plugin-jest-hoist@^24.9.0:
dependencies:
"@types/babel__traverse" "^7.0.6"
-babel-plugin-jest-hoist@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d"
- integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==
- dependencies:
- "@babel/template" "^7.3.3"
- "@babel/types" "^7.3.3"
- "@types/babel__core" "^7.0.0"
- "@types/babel__traverse" "^7.0.6"
-
babel-plugin-polyfill-corejs2@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5"
@@ -2848,24 +2763,6 @@ babel-preset-airbnb@^4.4.0:
"@babel/preset-react" "^7.9.4"
babel-plugin-transform-react-remove-prop-types "^0.4.24"
-babel-preset-current-node-syntax@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
- integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==
- dependencies:
- "@babel/plugin-syntax-async-generators" "^7.8.4"
- "@babel/plugin-syntax-bigint" "^7.8.3"
- "@babel/plugin-syntax-class-properties" "^7.8.3"
- "@babel/plugin-syntax-import-meta" "^7.8.3"
- "@babel/plugin-syntax-json-strings" "^7.8.3"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
- "@babel/plugin-syntax-numeric-separator" "^7.8.3"
- "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
- "@babel/plugin-syntax-optional-chaining" "^7.8.3"
- "@babel/plugin-syntax-top-level-await" "^7.8.3"
-
babel-preset-jest@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc"
@@ -2874,14 +2771,6 @@ babel-preset-jest@^24.9.0:
"@babel/plugin-syntax-object-rest-spread" "^7.0.0"
babel-plugin-jest-hoist "^24.9.0"
-babel-preset-jest@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee"
- integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==
- dependencies:
- babel-plugin-jest-hoist "^26.6.2"
- babel-preset-current-node-syntax "^1.0.0"
-
babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
@@ -2968,11 +2857,6 @@ blueimp-tmpl@3:
resolved "https://registry.yarnpkg.com/blueimp-tmpl/-/blueimp-tmpl-3.20.0.tgz#bed897db362c70d3740e0ad1020ce84bfa15ceaa"
integrity sha512-g6ln9L+VX8ZA4WA8mgKMethYH+5teroJ2uOkCvcthy9Y9d9LrQ42OAMn+r3ECKu9CB+xe9GOChlIUJBSxwkI6g==
-boolbase@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
- integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
-
bootstrap-sass@^3.4.1:
version "3.4.3"
resolved "https://registry.yarnpkg.com/bootstrap-sass/-/bootstrap-sass-3.4.3.tgz#742cc8f4286303ae9fe8e4c95237321eae73766c"
@@ -3023,11 +2907,6 @@ braces@^3.0.3:
dependencies:
fill-range "^7.1.1"
-browser-process-hrtime@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
- integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
-
browserslist@^4.12.0, browserslist@^4.20.2, browserslist@^4.20.4, browserslist@^4.6.4:
version "4.21.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.0.tgz#7ab19572361a140ecd1e023e2c1ed95edda0cefe"
@@ -3060,11 +2939,6 @@ buffer-crc32@~0.2.3:
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
-buffer-from@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
- integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
-
buffer@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@@ -3073,6 +2947,11 @@ buffer@^5.6.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
+cac@^6.7.14:
+ version "6.7.14"
+ resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959"
+ integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==
+
cacache@^15.2.0:
version "15.3.0"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb"
@@ -3147,16 +3026,11 @@ camelcase-keys@^6.2.2:
map-obj "^4.0.0"
quick-lru "^4.0.1"
-camelcase@^5.0.0, camelcase@^5.3.1:
+camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-camelcase@^6.0.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
- integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-
caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001358:
version "1.0.30001358"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001358.tgz#473d35dabf5e448b463095cab7924e96ccfb8c00"
@@ -3179,6 +3053,17 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
+chai@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.1.tgz#f035d9792a22b481ead1c65908d14bb62ec1c82c"
+ integrity sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==
+ dependencies:
+ assertion-error "^2.0.1"
+ check-error "^2.1.1"
+ deep-eql "^5.0.1"
+ loupe "^3.1.0"
+ pathval "^2.0.0"
+
chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -3241,11 +3126,6 @@ change-object-case@^0.2.0:
dependencies:
change-case "^2.3.0"
-char-regex@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
- integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
-
chart.js@>=3.0.2:
version "4.3.0"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.3.0.tgz#ac363030ab3fec572850d2d872956f32a46326a1"
@@ -3277,37 +3157,16 @@ chartkick@^4.2.0:
chartjs-adapter-date-fns ">=2.0.0"
date-fns ">=2.0.0"
+check-error@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc"
+ integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==
+
check-more-types@^2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==
-cheerio-select@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4"
- integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==
- dependencies:
- boolbase "^1.0.0"
- css-select "^5.1.0"
- css-what "^6.1.0"
- domelementtype "^2.3.0"
- domhandler "^5.0.3"
- domutils "^3.0.1"
-
-cheerio@^1.0.0-rc.3:
- version "1.0.0-rc.11"
- resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.11.tgz#1be84be1a126958366bcc57a11648cd9b30a60c2"
- integrity sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag==
- dependencies:
- cheerio-select "^2.1.0"
- dom-serializer "^2.0.0"
- domhandler "^5.0.3"
- domutils "^3.0.1"
- htmlparser2 "^8.0.1"
- parse5 "^7.0.0"
- parse5-htmlparser2-tree-adapter "^7.0.0"
- tslib "^2.4.0"
-
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
@@ -3323,16 +3182,6 @@ ci-info@^3.2.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128"
integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==
-circular-json-es6@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/circular-json-es6/-/circular-json-es6-2.0.2.tgz#e4f4a093e49fb4b6aba1157365746112a78bd344"
- integrity sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==
-
-cjs-module-lexer@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f"
- integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==
-
class-utils@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
@@ -3367,6 +3216,11 @@ cli-cursor@^5.0.0:
dependencies:
restore-cursor "^5.0.0"
+cli-spinners@^2.9.2:
+ version "2.9.2"
+ resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41"
+ integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==
+
cli-table3@~0.6.1:
version "0.6.2"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a"
@@ -3392,6 +3246,11 @@ cli-truncate@^4.0.0:
slice-ansi "^5.0.0"
string-width "^7.0.0"
+cli-width@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5"
+ integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==
+
clipboard@*, clipboard@^2.0.0, clipboard@^2.0.4:
version "2.0.11"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5"
@@ -3401,15 +3260,6 @@ clipboard@*, clipboard@^2.0.0, clipboard@^2.0.4:
select "^1.1.2"
tiny-emitter "^2.0.0"
-cliui@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
- integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
- dependencies:
- string-width "^4.2.0"
- strip-ansi "^6.0.0"
- wrap-ansi "^6.2.0"
-
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
@@ -3419,6 +3269,15 @@ cliui@^7.0.2:
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
+cliui@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
+ integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.1"
+ wrap-ansi "^7.0.0"
+
cloudinary-jquery-file-upload@^2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/cloudinary-jquery-file-upload/-/cloudinary-jquery-file-upload-2.13.0.tgz#17b9bc63daea46f02acdb2601356191e87ca52a9"
@@ -3429,16 +3288,6 @@ cloudinary-jquery@^2.13.0:
resolved "https://registry.yarnpkg.com/cloudinary-jquery/-/cloudinary-jquery-2.13.0.tgz#482586c48099666ae30b945633e9ea9d5c79c621"
integrity sha512-gkUEPIxIxIFJWQxfuq0Xvp9GQ0WN3cd7cGq/z7zkZe3QvLkfJxboqLd5HRlwgh2JIccUQV4z9ZnlB+lyCu9iGg==
-co@^4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
- integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
-
-collect-v8-coverage@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
- integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==
-
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -3493,11 +3342,6 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@^2.19.0:
- version "2.20.3"
- resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
- integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-
commander@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
@@ -3541,7 +3385,7 @@ constant-case@^1.1.0:
snake-case "^1.1.0"
upper-case "^1.1.1"
-convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
+convert-source-map@^1.4.0, convert-source-map@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
@@ -3553,6 +3397,11 @@ convert-source-map@^2.0.0:
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
+cookie@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
+ integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
+
copy-descriptor@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
@@ -3646,22 +3495,6 @@ css-prefers-color-scheme@^3.1.1:
dependencies:
postcss "^7.0.5"
-css-select@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
- integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
- dependencies:
- boolbase "^1.0.0"
- css-what "^6.1.0"
- domhandler "^5.0.2"
- domutils "^3.0.1"
- nth-check "^2.0.1"
-
-css-what@^6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
- integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
-
css.escape@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb"
@@ -3692,29 +3525,12 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
-cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6:
- version "0.3.8"
- resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
- integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
-
-cssom@^0.4.4:
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
- integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
-
-cssstyle@^1.0.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1"
- integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==
- dependencies:
- cssom "0.3.x"
-
-cssstyle@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852"
- integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==
+cssstyle@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-4.0.1.tgz#ef29c598a1e90125c870525490ea4f354db0660a"
+ integrity sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==
dependencies:
- cssom "~0.3.6"
+ rrweb-cssom "^0.6.0"
csstype@^3.0.2:
version "3.1.0"
@@ -3789,23 +3605,13 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
-data-urls@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe"
- integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
- dependencies:
- abab "^2.0.0"
- whatwg-mimetype "^2.2.0"
- whatwg-url "^7.0.0"
-
-data-urls@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
- integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
+data-urls@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-5.0.0.tgz#2f76906bce1824429ffecb6920f45a0b30f00dde"
+ integrity sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==
dependencies:
- abab "^2.0.3"
- whatwg-mimetype "^2.3.0"
- whatwg-url "^8.0.0"
+ whatwg-mimetype "^4.0.0"
+ whatwg-url "^14.0.0"
date-fns@>=2.0.0:
version "2.30.0"
@@ -3840,7 +3646,7 @@ debug@^3.1.0, debug@^3.2.7:
dependencies:
ms "^2.1.1"
-debug@^4.3.1, debug@~4.3.6:
+debug@^4.3.1, debug@^4.3.5, debug@~4.3.6:
version "4.3.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b"
integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==
@@ -3860,22 +3666,20 @@ decamelize@^1.1.0, decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
-decimal.js@^10.2.1:
- version "10.3.1"
- resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
- integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
+decimal.js@^10.4.3:
+ version "10.4.3"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
+ integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==
decode-uri-component@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
-deep-equal-ident@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz#06f4b89e53710cd6cea4a7781c7a956642de8dc9"
- integrity sha512-aWv7VhTl/Lju1zenOD3E1w8PpUVrTDbwXCHtbSNr+p/uadr49Y1P1ld0W3Pl6gbvIbiRjoCVsqw70UupCNGh6g==
- dependencies:
- lodash.isequal "^3.0"
+deep-eql@^5.0.1:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341"
+ integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==
deep-equal@^2.0.5:
version "2.0.5"
@@ -3898,16 +3702,11 @@ deep-equal@^2.0.5:
which-collection "^1.0.1"
which-typed-array "^1.1.2"
-deep-is@^0.1.3, deep-is@~0.1.3:
+deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
-deepmerge@^4.2.2:
- version "4.2.2"
- resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
- integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
-
define-properties@^1.1.3, define-properties@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
@@ -3958,36 +3757,11 @@ depd@^1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
-detect-newline@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
- integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
-
diff-sequences@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==
-diff-sequences@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1"
- integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==
-
-diff-sequences@^28.1.1:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6"
- integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==
-
-diff@^3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
- integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
-
-discontinuous-range@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
- integrity sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==
-
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@@ -4015,39 +3789,16 @@ dom-serializer@0:
domelementtype "^2.0.1"
entities "^2.0.0"
-dom-serializer@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
- integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
- dependencies:
- domelementtype "^2.3.0"
- domhandler "^5.0.2"
- entities "^4.2.0"
-
domelementtype@1, domelementtype@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
-domelementtype@^2.0.1, domelementtype@^2.3.0:
+domelementtype@^2.0.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
-domexception@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
- integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
- dependencies:
- webidl-conversions "^4.0.2"
-
-domexception@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
- integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
- dependencies:
- webidl-conversions "^5.0.0"
-
domhandler@2.4.2, domhandler@^2.3.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
@@ -4055,13 +3806,6 @@ domhandler@2.4.2, domhandler@^2.3.0:
dependencies:
domelementtype "1"
-domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
- integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
- dependencies:
- domelementtype "^2.3.0"
-
domutils@^1.5.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
@@ -4070,15 +3814,6 @@ domutils@^1.5.1:
dom-serializer "0"
domelementtype "1"
-domutils@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
- integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==
- dependencies:
- dom-serializer "^2.0.0"
- domelementtype "^2.3.0"
- domhandler "^5.0.1"
-
dot-case@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-1.1.2.tgz#1e73826900de28d6de5480bc1de31d0842b06bec"
@@ -4116,11 +3851,6 @@ electron-to-chromium@^1.5.4:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.9.tgz#3e92950e3a409d109371b7a153a9c5712e2509fd"
integrity sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==
-emittery@^0.7.1:
- version "0.7.2"
- resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82"
- integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==
-
emoji-regex@^10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23"
@@ -4167,10 +3897,10 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
-entities@^4.2.0, entities@^4.3.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.0.tgz#62915f08d67353bb4eb67e3d62641a4059aec656"
- integrity sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==
+entities@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+ integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
env-paths@^2.2.0:
version "2.2.1"
@@ -4182,87 +3912,6 @@ environment@^1.0.0:
resolved "https://registry.yarnpkg.com/environment/-/environment-1.1.0.tgz#8e86c66b180f363c7ab311787e0259665f45a9f1"
integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==
-enzyme-adapter-react-16@^1.15.1:
- version "1.15.6"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz#fd677a658d62661ac5afd7f7f541f141f8085901"
- integrity sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==
- dependencies:
- enzyme-adapter-utils "^1.14.0"
- enzyme-shallow-equal "^1.0.4"
- has "^1.0.3"
- object.assign "^4.1.2"
- object.values "^1.1.2"
- prop-types "^15.7.2"
- react-is "^16.13.1"
- react-test-renderer "^16.0.0-0"
- semver "^5.7.0"
-
-enzyme-adapter-utils@^1.14.0:
- version "1.14.0"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz#afbb0485e8033aa50c744efb5f5711e64fbf1ad0"
- integrity sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==
- dependencies:
- airbnb-prop-types "^2.16.0"
- function.prototype.name "^1.1.3"
- has "^1.0.3"
- object.assign "^4.1.2"
- object.fromentries "^2.0.3"
- prop-types "^15.7.2"
- semver "^5.7.1"
-
-enzyme-matchers@^7.1.2:
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz#d80530a61f22d28bb993dd7588abba38bd4de282"
- integrity sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==
- dependencies:
- circular-json-es6 "^2.0.1"
- deep-equal-ident "^1.1.1"
-
-enzyme-shallow-equal@^1.0.1, enzyme-shallow-equal@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz#b9256cb25a5f430f9bfe073a84808c1d74fced2e"
- integrity sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==
- dependencies:
- has "^1.0.3"
- object-is "^1.1.2"
-
-enzyme-to-json@^3.3.0:
- version "3.6.2"
- resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.6.2.tgz#94f85c413bcae8ab67be53b0a94b69a560e27823"
- integrity sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg==
- dependencies:
- "@types/cheerio" "^0.22.22"
- lodash "^4.17.21"
- react-is "^16.12.0"
-
-enzyme@^3.11.0:
- version "3.11.0"
- resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28"
- integrity sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==
- dependencies:
- array.prototype.flat "^1.2.3"
- cheerio "^1.0.0-rc.3"
- enzyme-shallow-equal "^1.0.1"
- function.prototype.name "^1.1.2"
- has "^1.0.3"
- html-element-map "^1.2.0"
- is-boolean-object "^1.0.1"
- is-callable "^1.1.5"
- is-number-object "^1.0.4"
- is-regex "^1.0.5"
- is-string "^1.0.5"
- is-subset "^0.1.1"
- lodash.escape "^4.0.1"
- lodash.isequal "^4.5.0"
- object-inspect "^1.7.0"
- object-is "^1.0.2"
- object.assign "^4.1.0"
- object.entries "^1.1.1"
- object.values "^1.1.1"
- raf "^3.4.1"
- rst-selector-parser "^2.2.3"
- string.prototype.trim "^1.2.1"
-
err-code@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
@@ -4275,7 +3924,7 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.4, es-abstract@^1.19.5, es-abstract@^1.20.1:
+es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.1:
version "1.20.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
@@ -4433,6 +4082,35 @@ esbuild@^0.18.10:
"@esbuild/win32-ia32" "0.18.20"
"@esbuild/win32-x64" "0.18.20"
+esbuild@^0.21.3:
+ version "0.21.5"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
+ integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
+ optionalDependencies:
+ "@esbuild/aix-ppc64" "0.21.5"
+ "@esbuild/android-arm" "0.21.5"
+ "@esbuild/android-arm64" "0.21.5"
+ "@esbuild/android-x64" "0.21.5"
+ "@esbuild/darwin-arm64" "0.21.5"
+ "@esbuild/darwin-x64" "0.21.5"
+ "@esbuild/freebsd-arm64" "0.21.5"
+ "@esbuild/freebsd-x64" "0.21.5"
+ "@esbuild/linux-arm" "0.21.5"
+ "@esbuild/linux-arm64" "0.21.5"
+ "@esbuild/linux-ia32" "0.21.5"
+ "@esbuild/linux-loong64" "0.21.5"
+ "@esbuild/linux-mips64el" "0.21.5"
+ "@esbuild/linux-ppc64" "0.21.5"
+ "@esbuild/linux-riscv64" "0.21.5"
+ "@esbuild/linux-s390x" "0.21.5"
+ "@esbuild/linux-x64" "0.21.5"
+ "@esbuild/netbsd-x64" "0.21.5"
+ "@esbuild/openbsd-x64" "0.21.5"
+ "@esbuild/sunos-x64" "0.21.5"
+ "@esbuild/win32-arm64" "0.21.5"
+ "@esbuild/win32-ia32" "0.21.5"
+ "@esbuild/win32-x64" "0.21.5"
+
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -4458,30 +4136,6 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-escodegen@^1.9.1:
- version "1.14.3"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
- integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==
- dependencies:
- esprima "^4.0.1"
- estraverse "^4.2.0"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.6.1"
-
-escodegen@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
- integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==
- dependencies:
- esprima "^4.0.1"
- estraverse "^5.2.0"
- esutils "^2.0.2"
- optionator "^0.8.1"
- optionalDependencies:
- source-map "~0.6.1"
-
eslint-config-prettier@^9.0.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f"
@@ -4666,7 +4320,7 @@ espree@^9.6.0, espree@^9.6.1:
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.4.1"
-esprima@^4.0.0, esprima@^4.0.1:
+esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -4685,7 +4339,7 @@ esrecurse@^4.3.0:
dependencies:
estraverse "^5.2.0"
-estraverse@^4.1.1, estraverse@^4.2.0:
+estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
@@ -4695,6 +4349,13 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+estree-walker@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
+ integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
+ dependencies:
+ "@types/estree" "^1.0.0"
+
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
@@ -4723,7 +4384,7 @@ exec-sh@^0.3.2:
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc"
integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==
-execa@4.1.0, execa@^4.0.0:
+execa@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
@@ -4751,7 +4412,7 @@ execa@^1.0.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
-execa@~8.0.1:
+execa@^8.0.1, execa@~8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c"
integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==
@@ -4773,11 +4434,6 @@ executable@^4.1.1:
dependencies:
pify "^2.2.0"
-exit@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
- integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==
-
expand-brackets@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
@@ -4791,29 +4447,6 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-expect@>=22.0.0:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.1.tgz#ca6fff65f6517cf7220c2e805a49c19aea30b420"
- integrity sha512-/AANEwGL0tWBwzLNOvO0yUdy2D52jVdNXppOqswC49sxMN2cPWsGCQdzuIf9tj6hHoBQzNvx75JUYuQAckPo3w==
- dependencies:
- "@jest/expect-utils" "^28.1.1"
- jest-get-type "^28.0.2"
- jest-matcher-utils "^28.1.1"
- jest-message-util "^28.1.1"
- jest-util "^28.1.1"
-
-expect@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417"
- integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==
- dependencies:
- "@jest/types" "^26.6.2"
- ansi-styles "^4.0.0"
- jest-get-type "^26.3.0"
- jest-matcher-utils "^26.6.2"
- jest-message-util "^26.6.2"
- jest-regex-util "^26.0.0"
-
ext@^1.1.2:
version "1.6.0"
resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52"
@@ -4902,7 +4535,7 @@ fast-json-stable-stringify@^2.0.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
-fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
+fast-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
@@ -4999,7 +4632,7 @@ find-up@^3.0.0:
dependencies:
locate-path "^3.0.0"
-find-up@^4.0.0, find-up@^4.1.0:
+find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
@@ -5056,10 +4689,10 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
-form-data@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
- integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
+form-data@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
+ integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
@@ -5111,17 +4744,22 @@ fsevents@^1.2.7:
bindings "^1.5.0"
nan "^2.12.1"
-fsevents@^2.1.2, fsevents@~2.3.2:
+fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+fsevents@~2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-function.prototype.name@^1.1.2, function.prototype.name@^1.1.3, function.prototype.name@^1.1.5:
+function.prototype.name@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
@@ -5177,7 +4815,7 @@ gensync@^1.0.0-beta.2:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
-get-caller-file@^2.0.1, get-caller-file@^2.0.5:
+get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
@@ -5187,6 +4825,11 @@ get-east-asian-width@^1.0.0:
resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e"
integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==
+get-func-name@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41"
+ integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
+
get-intrinsic@^1.0.1, get-intrinsic@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
@@ -5205,11 +4848,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.3"
-get-package-type@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
- integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
-
get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
@@ -5275,7 +4913,7 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
-glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
+glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@@ -5341,7 +4979,7 @@ good-listener@^1.2.2:
dependencies:
delegate "^3.1.2"
-graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@@ -5351,16 +4989,16 @@ graphemer@^1.4.0:
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
+graphql@^16.8.1:
+ version "16.9.0"
+ resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f"
+ integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==
+
gritter@^1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/gritter/-/gritter-1.7.4.tgz#cdb83982bd19e2ce93be73971e1320a3261133e1"
integrity sha512-yqCTsfCSqi2fsajkuTWomqt6sOr78sAbUWrdb0E6I2QmFJoVVHT/I0JyTBhVmCWBBF46cDZqKg/K9rP2NUNKng==
-growly@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
- integrity sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==
-
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@@ -5468,6 +5106,11 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+headers-polyfill@^4.0.2:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07"
+ integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==
+
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
@@ -5496,32 +5139,12 @@ html-dom-parser@0.2.3:
domhandler "2.4.2"
htmlparser2 "3.10.1"
-html-element-map@^1.2.0:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.3.1.tgz#44b2cbcfa7be7aa4ff59779e47e51012e1c73c08"
- integrity sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==
- dependencies:
- array.prototype.filter "^1.0.0"
- call-bind "^1.0.2"
-
-html-encoding-sniffer@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
- integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==
- dependencies:
- whatwg-encoding "^1.0.1"
-
-html-encoding-sniffer@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
- integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
+html-encoding-sniffer@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448"
+ integrity sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==
dependencies:
- whatwg-encoding "^1.0.5"
-
-html-escaper@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
- integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
+ whatwg-encoding "^3.1.1"
html-react-parser@^0.10.0:
version "0.10.5"
@@ -5545,16 +5168,6 @@ htmlparser2@3.10.1:
inherits "^2.0.1"
readable-stream "^3.1.1"
-htmlparser2@^8.0.1:
- version "8.0.1"
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010"
- integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==
- dependencies:
- domelementtype "^2.3.0"
- domhandler "^5.0.2"
- domutils "^3.0.1"
- entities "^4.3.0"
-
http-cache-semantics@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
@@ -5569,6 +5182,14 @@ http-proxy-agent@^4.0.1:
agent-base "6"
debug "4"
+http-proxy-agent@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e"
+ integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==
+ dependencies:
+ agent-base "^7.1.0"
+ debug "^4.3.4"
+
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
@@ -5600,6 +5221,14 @@ https-proxy-agent@^5.0.0:
agent-base "6"
debug "4"
+https-proxy-agent@^7.0.5:
+ version "7.0.5"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2"
+ integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==
+ dependencies:
+ agent-base "^7.0.2"
+ debug "4"
+
human-signals@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
@@ -5626,14 +5255,7 @@ husky@^8.0.0:
version "0.0.0"
resolved "https://github.com/fnando/i18n-js/archive/v3.0.0.tar.gz#15901af4a5d07527c804106a0971c01d2f181068"
-iconv-lite@0.4.24:
- version "0.4.24"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
- integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
- dependencies:
- safer-buffer ">= 2.1.2 < 3"
-
-iconv-lite@^0.6.2:
+iconv-lite@0.6.3, iconv-lite@^0.6.2:
version "0.6.3"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
@@ -5658,14 +5280,6 @@ import-fresh@^3.2.1:
parent-module "^1.0.0"
resolve-from "^4.0.0"
-import-local@^3.0.2:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"
- integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
- dependencies:
- pkg-dir "^4.2.0"
- resolve-cwd "^3.0.0"
-
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@@ -5764,7 +5378,7 @@ is-bigint@^1.0.1:
dependencies:
has-bigints "^1.0.1"
-is-boolean-object@^1.0.1, is-boolean-object@^1.1.0:
+is-boolean-object@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
@@ -5777,7 +5391,7 @@ is-buffer@^1.1.5:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.4:
+is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
@@ -5847,11 +5461,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2:
is-data-descriptor "^1.0.0"
kind-of "^6.0.2"
-is-docker@^2.0.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
- integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
-
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -5886,11 +5495,6 @@ is-fullwidth-code-point@^5.0.0:
dependencies:
get-east-asian-width "^1.0.0"
-is-generator-fn@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
- integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
-
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
@@ -5928,6 +5532,11 @@ is-negative-zero@^2.0.2:
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
+is-node-process@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134"
+ integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==
+
is-number-object@^1.0.4:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
@@ -5974,7 +5583,7 @@ is-promise@^2.2.2:
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
-is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.1, is-regex@^1.1.4:
+is-regex@^1.1.1, is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
@@ -6016,11 +5625,6 @@ is-string@^1.0.5, is-string@^1.0.7:
dependencies:
has-tostringtag "^1.0.0"
-is-subset@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
- integrity sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==
-
is-symbol@^1.0.2, is-symbol@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
@@ -6039,7 +5643,7 @@ is-typed-array@^1.1.9:
for-each "^0.3.3"
has-tostringtag "^1.0.0"
-is-typedarray@^1.0.0, is-typedarray@~1.0.0:
+is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
@@ -6081,18 +5685,6 @@ is-windows@^1.0.2:
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
-is-wsl@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
- integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
- dependencies:
- is-docker "^2.0.0"
-
-isarray@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
- integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
-
isarray@1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@@ -6130,11 +5722,6 @@ istanbul-lib-coverage@^2.0.5:
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==
-istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3"
- integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==
-
istanbul-lib-instrument@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630"
@@ -6148,53 +5735,6 @@ istanbul-lib-instrument@^3.3.0:
istanbul-lib-coverage "^2.0.5"
semver "^6.0.0"
-istanbul-lib-instrument@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
- integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==
- dependencies:
- "@babel/core" "^7.7.5"
- "@istanbuljs/schema" "^0.1.2"
- istanbul-lib-coverage "^3.0.0"
- semver "^6.3.0"
-
-istanbul-lib-instrument@^5.0.4:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f"
- integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==
- dependencies:
- "@babel/core" "^7.12.3"
- "@babel/parser" "^7.14.7"
- "@istanbuljs/schema" "^0.1.2"
- istanbul-lib-coverage "^3.2.0"
- semver "^6.3.0"
-
-istanbul-lib-report@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6"
- integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==
- dependencies:
- istanbul-lib-coverage "^3.0.0"
- make-dir "^3.0.0"
- supports-color "^7.1.0"
-
-istanbul-lib-source-maps@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551"
- integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==
- dependencies:
- debug "^4.1.1"
- istanbul-lib-coverage "^3.0.0"
- source-map "^0.6.1"
-
-istanbul-reports@^3.0.2:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c"
- integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==
- dependencies:
- html-escaper "^2.0.0"
- istanbul-lib-report "^3.0.0"
-
jake@^10.8.5:
version "10.8.6"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.6.tgz#227a96786a1e035214e0ba84b482d6223d41ef04"
@@ -6205,58 +5745,6 @@ jake@^10.8.5:
filelist "^1.0.4"
minimatch "^3.1.2"
-jest-changed-files@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0"
- integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==
- dependencies:
- "@jest/types" "^26.6.2"
- execa "^4.0.0"
- throat "^5.0.0"
-
-jest-cli@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a"
- integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==
- dependencies:
- "@jest/core" "^26.6.3"
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- chalk "^4.0.0"
- exit "^0.1.2"
- graceful-fs "^4.2.4"
- import-local "^3.0.2"
- is-ci "^2.0.0"
- jest-config "^26.6.3"
- jest-util "^26.6.2"
- jest-validate "^26.6.2"
- prompts "^2.0.1"
- yargs "^15.4.1"
-
-jest-config@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349"
- integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==
- dependencies:
- "@babel/core" "^7.1.0"
- "@jest/test-sequencer" "^26.6.3"
- "@jest/types" "^26.6.2"
- babel-jest "^26.6.3"
- chalk "^4.0.0"
- deepmerge "^4.2.2"
- glob "^7.1.1"
- graceful-fs "^4.2.4"
- jest-environment-jsdom "^26.6.2"
- jest-environment-node "^26.6.2"
- jest-get-type "^26.3.0"
- jest-jasmine2 "^26.6.3"
- jest-regex-util "^26.0.0"
- jest-resolve "^26.6.2"
- jest-util "^26.6.2"
- jest-validate "^26.6.2"
- micromatch "^4.0.2"
- pretty-format "^26.6.2"
-
jest-diff@^24.0.0, jest-diff@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da"
@@ -6267,112 +5755,11 @@ jest-diff@^24.0.0, jest-diff@^24.9.0:
jest-get-type "^24.9.0"
pretty-format "^24.9.0"
-jest-diff@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394"
- integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==
- dependencies:
- chalk "^4.0.0"
- diff-sequences "^26.6.2"
- jest-get-type "^26.3.0"
- pretty-format "^26.6.2"
-
-jest-diff@^28.1.1:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.1.tgz#1a3eedfd81ae79810931c63a1d0f201b9120106c"
- integrity sha512-/MUUxeR2fHbqHoMMiffe/Afm+U8U4olFRJ0hiVG2lZatPJcnGxx292ustVu7bULhjV65IYMxRdploAKLbcrsyg==
- dependencies:
- chalk "^4.0.0"
- diff-sequences "^28.1.1"
- jest-get-type "^28.0.2"
- pretty-format "^28.1.1"
-
-jest-docblock@^26.0.0:
- version "26.0.0"
- resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5"
- integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==
- dependencies:
- detect-newline "^3.0.0"
-
-jest-each@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb"
- integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==
- dependencies:
- "@jest/types" "^26.6.2"
- chalk "^4.0.0"
- jest-get-type "^26.3.0"
- jest-util "^26.6.2"
- pretty-format "^26.6.2"
-
-jest-environment-enzyme@^7.1.2:
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/jest-environment-enzyme/-/jest-environment-enzyme-7.1.2.tgz#4561f26a719e8e87ce8c9a6d3f540a92663ba8d5"
- integrity sha512-3tfaYAzO7qZSRrv+srQnfK16Vu5XwH/pHi8FpoqSHjKKngbHzXf7aBCBuWh8y3w0OtknHRfDMFrC60Khj+g1hA==
- dependencies:
- jest-environment-jsdom "^24.0.0"
-
-jest-environment-jsdom@^24.0.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b"
- integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==
- dependencies:
- "@jest/environment" "^24.9.0"
- "@jest/fake-timers" "^24.9.0"
- "@jest/types" "^24.9.0"
- jest-mock "^24.9.0"
- jest-util "^24.9.0"
- jsdom "^11.5.1"
-
-jest-environment-jsdom@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e"
- integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==
- dependencies:
- "@jest/environment" "^26.6.2"
- "@jest/fake-timers" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- jest-mock "^26.6.2"
- jest-util "^26.6.2"
- jsdom "^16.4.0"
-
-jest-environment-node@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c"
- integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==
- dependencies:
- "@jest/environment" "^26.6.2"
- "@jest/fake-timers" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- jest-mock "^26.6.2"
- jest-util "^26.6.2"
-
-jest-enzyme@^7.1.2:
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/jest-enzyme/-/jest-enzyme-7.1.2.tgz#91a10b2d3be1b56c0d65b34286e5bdc41ab4ba3d"
- integrity sha512-j+jkph3t5hGBS12eOldpfsnERYRCHi4c/0KWPMnqRPoJJXvCpLIc5th1MHl0xDznQDXVU0AHUXg3rqMrf8vGpA==
- dependencies:
- enzyme-matchers "^7.1.2"
- enzyme-to-json "^3.3.0"
- jest-environment-enzyme "^7.1.2"
-
jest-get-type@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e"
integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==
-jest-get-type@^26.3.0:
- version "26.3.0"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
- integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==
-
-jest-get-type@^28.0.2:
- version "28.0.2"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203"
- integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==
-
jest-haste-map@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d"
@@ -6392,69 +5779,6 @@ jest-haste-map@^24.9.0:
optionalDependencies:
fsevents "^1.2.7"
-jest-haste-map@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa"
- integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/graceful-fs" "^4.1.2"
- "@types/node" "*"
- anymatch "^3.0.3"
- fb-watchman "^2.0.0"
- graceful-fs "^4.2.4"
- jest-regex-util "^26.0.0"
- jest-serializer "^26.6.2"
- jest-util "^26.6.2"
- jest-worker "^26.6.2"
- micromatch "^4.0.2"
- sane "^4.0.3"
- walker "^1.0.7"
- optionalDependencies:
- fsevents "^2.1.2"
-
-jest-jasmine2@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd"
- integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==
- dependencies:
- "@babel/traverse" "^7.1.0"
- "@jest/environment" "^26.6.2"
- "@jest/source-map" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- chalk "^4.0.0"
- co "^4.6.0"
- expect "^26.6.2"
- is-generator-fn "^2.0.0"
- jest-each "^26.6.2"
- jest-matcher-utils "^26.6.2"
- jest-message-util "^26.6.2"
- jest-runtime "^26.6.3"
- jest-snapshot "^26.6.2"
- jest-util "^26.6.2"
- pretty-format "^26.6.2"
- throat "^5.0.0"
-
-jest-leak-detector@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af"
- integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==
- dependencies:
- jest-get-type "^26.3.0"
- pretty-format "^26.6.2"
-
-jest-matcher-utils@>=22.0.0, jest-matcher-utils@^28.1.1:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.1.tgz#a7c4653c2b782ec96796eb3088060720f1e29304"
- integrity sha512-NPJPRWrbmR2nAJ+1nmnfcKKzSwgfaciCCrYZzVnNoxVoyusYWIjkBMNvu0RHJe7dNj4hH3uZOPZsQA+xAYWqsw==
- dependencies:
- chalk "^4.0.0"
- jest-diff "^28.1.1"
- jest-get-type "^28.0.2"
- pretty-format "^28.1.1"
-
jest-matcher-utils@^24.0.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073"
@@ -6465,16 +5789,6 @@ jest-matcher-utils@^24.0.0:
jest-get-type "^24.9.0"
pretty-format "^24.9.0"
-jest-matcher-utils@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a"
- integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==
- dependencies:
- chalk "^4.0.0"
- jest-diff "^26.6.2"
- jest-get-type "^26.3.0"
- pretty-format "^26.6.2"
-
jest-message-util@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3"
@@ -6489,36 +5803,6 @@ jest-message-util@^24.9.0:
slash "^2.0.0"
stack-utils "^1.0.1"
-jest-message-util@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07"
- integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@jest/types" "^26.6.2"
- "@types/stack-utils" "^2.0.0"
- chalk "^4.0.0"
- graceful-fs "^4.2.4"
- micromatch "^4.0.2"
- pretty-format "^26.6.2"
- slash "^3.0.0"
- stack-utils "^2.0.2"
-
-jest-message-util@^28.1.1:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.1.tgz#60aa0b475cfc08c8a9363ed2fb9108514dd9ab89"
- integrity sha512-xoDOOT66fLfmTRiqkoLIU7v42mal/SqwDKvfmfiWAdJMSJiU+ozgluO7KbvoAgiwIrrGZsV7viETjc8GNrA/IQ==
- dependencies:
- "@babel/code-frame" "^7.12.13"
- "@jest/types" "^28.1.1"
- "@types/stack-utils" "^2.0.0"
- chalk "^4.0.0"
- graceful-fs "^4.2.9"
- micromatch "^4.0.4"
- pretty-format "^28.1.1"
- slash "^3.0.0"
- stack-utils "^2.0.3"
-
jest-mock@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6"
@@ -6526,154 +5810,16 @@ jest-mock@^24.9.0:
dependencies:
"@jest/types" "^24.9.0"
-jest-mock@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302"
- integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/node" "*"
-
-jest-pnp-resolver@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
- integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
-
jest-regex-util@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636"
integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==
-jest-regex-util@^26.0.0:
- version "26.0.0"
- resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28"
- integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==
-
-jest-resolve-dependencies@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6"
- integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==
- dependencies:
- "@jest/types" "^26.6.2"
- jest-regex-util "^26.0.0"
- jest-snapshot "^26.6.2"
-
-jest-resolve@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507"
- integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==
- dependencies:
- "@jest/types" "^26.6.2"
- chalk "^4.0.0"
- graceful-fs "^4.2.4"
- jest-pnp-resolver "^1.2.2"
- jest-util "^26.6.2"
- read-pkg-up "^7.0.1"
- resolve "^1.18.1"
- slash "^3.0.0"
-
-jest-runner@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159"
- integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/environment" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- chalk "^4.0.0"
- emittery "^0.7.1"
- exit "^0.1.2"
- graceful-fs "^4.2.4"
- jest-config "^26.6.3"
- jest-docblock "^26.0.0"
- jest-haste-map "^26.6.2"
- jest-leak-detector "^26.6.2"
- jest-message-util "^26.6.2"
- jest-resolve "^26.6.2"
- jest-runtime "^26.6.3"
- jest-util "^26.6.2"
- jest-worker "^26.6.2"
- source-map-support "^0.5.6"
- throat "^5.0.0"
-
-jest-runtime@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b"
- integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==
- dependencies:
- "@jest/console" "^26.6.2"
- "@jest/environment" "^26.6.2"
- "@jest/fake-timers" "^26.6.2"
- "@jest/globals" "^26.6.2"
- "@jest/source-map" "^26.6.2"
- "@jest/test-result" "^26.6.2"
- "@jest/transform" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/yargs" "^15.0.0"
- chalk "^4.0.0"
- cjs-module-lexer "^0.6.0"
- collect-v8-coverage "^1.0.0"
- exit "^0.1.2"
- glob "^7.1.3"
- graceful-fs "^4.2.4"
- jest-config "^26.6.3"
- jest-haste-map "^26.6.2"
- jest-message-util "^26.6.2"
- jest-mock "^26.6.2"
- jest-regex-util "^26.0.0"
- jest-resolve "^26.6.2"
- jest-snapshot "^26.6.2"
- jest-util "^26.6.2"
- jest-validate "^26.6.2"
- slash "^3.0.0"
- strip-bom "^4.0.0"
- yargs "^15.4.1"
-
jest-serializer@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73"
integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==
-jest-serializer@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1"
- integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==
- dependencies:
- "@types/node" "*"
- graceful-fs "^4.2.4"
-
-jest-sinon@^1.0.1:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/jest-sinon/-/jest-sinon-1.0.4.tgz#cfd1611efe6a662c3102126279d5cc09e8603a6e"
- integrity sha512-D7kWXyWWE1JvjQNg290HMzv7M5lbNDF5s2ntgzEaQzCV5uIgn9P5PJeuX1sb6LZe50o+8qWijl6xwVibXdZL4Q==
- dependencies:
- expect ">=22.0.0"
- jest-matcher-utils ">=22.0.0"
-
-jest-snapshot@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84"
- integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==
- dependencies:
- "@babel/types" "^7.0.0"
- "@jest/types" "^26.6.2"
- "@types/babel__traverse" "^7.0.4"
- "@types/prettier" "^2.0.0"
- chalk "^4.0.0"
- expect "^26.6.2"
- graceful-fs "^4.2.4"
- jest-diff "^26.6.2"
- jest-get-type "^26.3.0"
- jest-haste-map "^26.6.2"
- jest-matcher-utils "^26.6.2"
- jest-message-util "^26.6.2"
- jest-resolve "^26.6.2"
- natural-compare "^1.4.0"
- pretty-format "^26.6.2"
- semver "^7.3.2"
-
jest-util@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162"
@@ -6692,55 +5838,6 @@ jest-util@^24.9.0:
slash "^2.0.0"
source-map "^0.6.0"
-jest-util@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1"
- integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==
- dependencies:
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- chalk "^4.0.0"
- graceful-fs "^4.2.4"
- is-ci "^2.0.0"
- micromatch "^4.0.2"
-
-jest-util@^28.1.1:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.1.tgz#ff39e436a1aca397c0ab998db5a51ae2b7080d05"
- integrity sha512-FktOu7ca1DZSyhPAxgxB6hfh2+9zMoJ7aEQA759Z6p45NuO8mWcqujH+UdHlCm/V6JTWwDztM2ITCzU1ijJAfw==
- dependencies:
- "@jest/types" "^28.1.1"
- "@types/node" "*"
- chalk "^4.0.0"
- ci-info "^3.2.0"
- graceful-fs "^4.2.9"
- picomatch "^2.2.3"
-
-jest-validate@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec"
- integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==
- dependencies:
- "@jest/types" "^26.6.2"
- camelcase "^6.0.0"
- chalk "^4.0.0"
- jest-get-type "^26.3.0"
- leven "^3.1.0"
- pretty-format "^26.6.2"
-
-jest-watcher@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975"
- integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==
- dependencies:
- "@jest/test-result" "^26.6.2"
- "@jest/types" "^26.6.2"
- "@types/node" "*"
- ansi-escapes "^4.2.1"
- chalk "^4.0.0"
- jest-util "^26.6.2"
- string-length "^4.0.1"
-
jest-worker@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
@@ -6749,24 +5846,6 @@ jest-worker@^24.9.0:
merge-stream "^2.0.0"
supports-color "^6.1.0"
-jest-worker@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
- integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==
- dependencies:
- "@types/node" "*"
- merge-stream "^2.0.0"
- supports-color "^7.0.0"
-
-jest@^26.6.3:
- version "26.6.3"
- resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef"
- integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==
- dependencies:
- "@jest/core" "^26.6.3"
- import-local "^3.0.2"
- jest-cli "^26.6.3"
-
jquery-ui-bundle@^1.12.1:
version "1.12.1"
resolved "https://registry.yarnpkg.com/jquery-ui-bundle/-/jquery-ui-bundle-1.12.1.tgz#d6be2e4c377494e2378b1cae2920a91d1182d8c4"
@@ -6836,70 +5915,32 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
-jsdom@^11.5.1:
- version "11.12.0"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8"
- integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==
- dependencies:
- abab "^2.0.0"
- acorn "^5.5.3"
- acorn-globals "^4.1.0"
- array-equal "^1.0.0"
- cssom ">= 0.3.2 < 0.4.0"
- cssstyle "^1.0.0"
- data-urls "^1.0.0"
- domexception "^1.0.1"
- escodegen "^1.9.1"
- html-encoding-sniffer "^1.0.2"
- left-pad "^1.3.0"
- nwsapi "^2.0.7"
- parse5 "4.0.0"
- pn "^1.1.0"
- request "^2.87.0"
- request-promise-native "^1.0.5"
- sax "^1.2.4"
- symbol-tree "^3.2.2"
- tough-cookie "^2.3.4"
- w3c-hr-time "^1.0.1"
- webidl-conversions "^4.0.2"
- whatwg-encoding "^1.0.3"
- whatwg-mimetype "^2.1.0"
- whatwg-url "^6.4.1"
- ws "^5.2.0"
- xml-name-validator "^3.0.0"
-
-jsdom@^16.4.0:
- version "16.7.0"
- resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
- integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
- dependencies:
- abab "^2.0.5"
- acorn "^8.2.4"
- acorn-globals "^6.0.0"
- cssom "^0.4.4"
- cssstyle "^2.3.0"
- data-urls "^2.0.0"
- decimal.js "^10.2.1"
- domexception "^2.0.1"
- escodegen "^2.0.0"
- form-data "^3.0.0"
- html-encoding-sniffer "^2.0.1"
- http-proxy-agent "^4.0.1"
- https-proxy-agent "^5.0.0"
+jsdom@^25.0.0:
+ version "25.0.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-25.0.0.tgz#d1612b4ddab85af56821b2f731e15faae135f4e1"
+ integrity sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==
+ dependencies:
+ cssstyle "^4.0.1"
+ data-urls "^5.0.0"
+ decimal.js "^10.4.3"
+ form-data "^4.0.0"
+ html-encoding-sniffer "^4.0.0"
+ http-proxy-agent "^7.0.2"
+ https-proxy-agent "^7.0.5"
is-potential-custom-element-name "^1.0.1"
- nwsapi "^2.2.0"
- parse5 "6.0.1"
- saxes "^5.0.1"
+ nwsapi "^2.2.12"
+ parse5 "^7.1.2"
+ rrweb-cssom "^0.7.1"
+ saxes "^6.0.0"
symbol-tree "^3.2.4"
- tough-cookie "^4.0.0"
- w3c-hr-time "^1.0.2"
- w3c-xmlserializer "^2.0.0"
- webidl-conversions "^6.1.0"
- whatwg-encoding "^1.0.5"
- whatwg-mimetype "^2.3.0"
- whatwg-url "^8.5.0"
- ws "^7.4.6"
- xml-name-validator "^3.0.0"
+ tough-cookie "^4.1.4"
+ w3c-xmlserializer "^5.0.0"
+ webidl-conversions "^7.0.0"
+ whatwg-encoding "^3.1.1"
+ whatwg-mimetype "^4.0.0"
+ whatwg-url "^14.0.0"
+ ws "^8.18.0"
+ xml-name-validator "^5.0.0"
jsesc@^2.5.1:
version "2.5.2"
@@ -6995,11 +6036,6 @@ jsprim@^2.0.2:
array-includes "^3.1.4"
object.assign "^4.1.2"
-just-extend@^4.0.2:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744"
- integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==
-
keymirror@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/keymirror/-/keymirror-0.1.1.tgz#918889ea13f8d0a42e7c557250eee713adc95c35"
@@ -7036,11 +6072,6 @@ kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
-kleur@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
- integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
-
language-subtag-registry@~0.3.2:
version "0.3.21"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a"
@@ -7063,16 +6094,6 @@ lcov-parse@^1.0.0:
resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0"
integrity sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==
-left-pad@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
- integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
-
-leven@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
- integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
-
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@@ -7081,14 +6102,6 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
-levn@~0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
- integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==
- dependencies:
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
-
lilconfig@~3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb"
@@ -7186,77 +6199,11 @@ lodash-es@^4.17.15:
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
-lodash._baseisequal@^3.0.0:
- version "3.0.7"
- resolved "https://registry.yarnpkg.com/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz#d8025f76339d29342767dcc887ce5cb95a5b51f1"
- integrity sha512-U+3GsNEZj9ebI03ncLC2pLmYVjgtYZEwdkAPO7UGgtGvAz36JVFPAQUufpSaVL93Cz5arc6JGRKZRhaOhyVJYA==
- dependencies:
- lodash.isarray "^3.0.0"
- lodash.istypedarray "^3.0.0"
- lodash.keys "^3.0.0"
-
-lodash._bindcallback@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
- integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==
-
-lodash._getnative@^3.0.0:
- version "3.9.1"
- resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
- integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==
-
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
-lodash.escape@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
- integrity sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==
-
-lodash.flattendeep@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
- integrity sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==
-
-lodash.isarguments@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
- integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==
-
-lodash.isarray@^3.0.0:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
- integrity sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==
-
-lodash.isequal@^3.0:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-3.0.4.tgz#1c35eb3b6ef0cd1ff51743e3ea3cf7fdffdacb64"
- integrity sha512-Bsu5fP9Omd+HBk2Dz8qp4BHbC+83DBykZ87Lz1JmPKTVNy4Q0XQVtUrbfXVAK/udQrWNcGStcKSA9yj/Zkm3TQ==
- dependencies:
- lodash._baseisequal "^3.0.0"
- lodash._bindcallback "^3.0.0"
-
-lodash.isequal@^4.5.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
- integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
-
-lodash.istypedarray@^3.0.0:
- version "3.0.6"
- resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62"
- integrity sha512-lGWJ6N8AA3KSv+ZZxlTdn4f6A7kMfpJboeyvbFdE7IU9YAgweODqmOgdUHOA+c6lVWeVLysdaxciFXi+foVsWw==
-
-lodash.keys@^3.0.0:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
- integrity sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==
- dependencies:
- lodash._getnative "^3.0.0"
- lodash.isarguments "^3.0.0"
- lodash.isarray "^3.0.0"
-
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
@@ -7267,12 +6214,7 @@ lodash.once@^4.1.1:
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
-lodash.sortby@^4.7.0:
- version "4.7.0"
- resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
- integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==
-
-lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
+lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7311,18 +6253,6 @@ log-update@^6.1.0:
strip-ansi "^7.1.0"
wrap-ansi "^9.0.0"
-lolex@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.2.0.tgz#ddbd7f6213ca1ea5826901ab1222b65d714b3cd7"
- integrity sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==
-
-lolex@^5.0.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367"
- integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==
- dependencies:
- "@sinonjs/commons" "^1.7.0"
-
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -7330,6 +6260,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
+loupe@^3.1.0, loupe@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.1.tgz#71d038d59007d890e3247c5db97c1ec5a92edc54"
+ integrity sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==
+ dependencies:
+ get-func-name "^2.0.1"
+
lower-case-first@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1"
@@ -7368,12 +6305,12 @@ lz-string@^1.4.4:
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==
-make-dir@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
- integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
+magic-string@^0.30.10:
+ version "0.30.11"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954"
+ integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==
dependencies:
- semver "^6.0.0"
+ "@jridgewell/sourcemap-codec" "^1.5.0"
make-fetch-happen@^9.1.0:
version "9.1.0"
@@ -7497,7 +6434,7 @@ micromatch@^3.1.10, micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"
-micromatch@^4.0.2, micromatch@^4.0.4:
+micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
@@ -7664,11 +6601,6 @@ moment@^2.29.4:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
-moo@^0.5.0:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4"
- integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==
-
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -7684,6 +6616,34 @@ ms@^2.0.0, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+msw@^2.4.4:
+ version "2.4.4"
+ resolved "https://registry.yarnpkg.com/msw/-/msw-2.4.4.tgz#d40c12b2d99750e3b2cbd94ef269a23b06a9aa67"
+ integrity sha512-iuM0qGs4YmgYCLH+xqb07w2e/e4fYmsx3+WHVlIOUA34TW1sw+wRpNmOlXnLDkw/T7233Jnm6t+aNf4v2E3e2Q==
+ dependencies:
+ "@bundled-es-modules/cookie" "^2.0.0"
+ "@bundled-es-modules/statuses" "^1.0.1"
+ "@bundled-es-modules/tough-cookie" "^0.1.6"
+ "@inquirer/confirm" "^3.0.0"
+ "@mswjs/interceptors" "^0.35.0"
+ "@open-draft/until" "^2.1.0"
+ "@types/cookie" "^0.6.0"
+ "@types/statuses" "^2.0.4"
+ chalk "^4.1.2"
+ graphql "^16.8.1"
+ headers-polyfill "^4.0.2"
+ is-node-process "^1.2.0"
+ outvariant "^1.4.2"
+ path-to-regexp "^6.2.0"
+ strict-event-emitter "^0.5.1"
+ type-fest "^4.9.0"
+ yargs "^17.7.2"
+
+mute-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e"
+ integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==
+
nan@^2.12.1:
version "2.16.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916"
@@ -7721,16 +6681,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
-nearley@^2.7.10:
- version "2.20.1"
- resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474"
- integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==
- dependencies:
- commander "^2.19.0"
- moo "^0.5.0"
- railroad-diagrams "^1.0.0"
- randexp "0.4.6"
-
negotiator@^0.6.2:
version "0.6.3"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
@@ -7746,17 +6696,6 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-nise@^1.5.2:
- version "1.5.3"
- resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7"
- integrity sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==
- dependencies:
- "@sinonjs/formatio" "^3.2.1"
- "@sinonjs/text-encoding" "^0.7.1"
- just-extend "^4.0.2"
- lolex "^5.0.1"
- path-to-regexp "^1.7.0"
-
node-gyp@^8.4.1:
version "8.4.1"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937"
@@ -7778,18 +6717,6 @@ node-int64@^0.4.0:
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==
-node-notifier@^8.0.0:
- version "8.0.2"
- resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5"
- integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==
- dependencies:
- growly "^1.3.0"
- is-wsl "^2.2.0"
- semver "^7.3.2"
- shellwords "^0.1.1"
- uuid "^8.3.0"
- which "^2.0.2"
-
node-releases@^2.0.18:
version "2.0.18"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
@@ -7855,11 +6782,6 @@ normalize-path@^2.1.1:
dependencies:
remove-trailing-separator "^1.0.1"
-normalize-path@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
- integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-
normalize-range@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
@@ -7906,27 +6828,15 @@ npmlog@^6.0.0:
gauge "^4.0.3"
set-blocking "^2.0.0"
-nth-check@^2.0.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
- integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
- dependencies:
- boolbase "^1.0.0"
-
num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==
-nwsapi@^2.0.7:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0"
- integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==
-
-nwsapi@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
- integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
+nwsapi@^2.2.12:
+ version "2.2.12"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.12.tgz#fb6af5c0ec35b27b4581eb3bbad34ec9e5c696f8"
+ integrity sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==
oauth-sign@~0.9.0:
version "0.9.0"
@@ -7947,12 +6857,12 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-inspect@^1.12.0, object-inspect@^1.12.2, object-inspect@^1.7.0, object-inspect@^1.9.0:
+object-inspect@^1.12.0, object-inspect@^1.12.2, object-inspect@^1.9.0:
version "1.12.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
-object-is@^1.0.2, object-is@^1.1.2, object-is@^1.1.4:
+object-is@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==
@@ -7992,7 +6902,7 @@ object.assign@^4.1.4:
has-symbols "^1.0.3"
object-keys "^1.1.1"
-object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.5:
+object.entries@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
@@ -8001,7 +6911,7 @@ object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.5:
define-properties "^1.1.3"
es-abstract "^1.19.1"
-object.fromentries@^2.0.3, object.fromentries@^2.0.5:
+object.fromentries@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
@@ -8035,7 +6945,7 @@ object.pick@^1.3.0:
dependencies:
isobject "^3.0.1"
-object.values@^1.1.1, object.values@^1.1.2, object.values@^1.1.5:
+object.values@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
@@ -8072,18 +6982,6 @@ onetime@^7.0.0:
dependencies:
mimic-function "^5.0.0"
-optionator@^0.8.1:
- version "0.8.3"
- resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
- integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
- dependencies:
- deep-is "~0.1.3"
- fast-levenshtein "~2.0.6"
- levn "~0.3.0"
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
- word-wrap "~1.2.3"
-
optionator@^0.9.3:
version "0.9.4"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734"
@@ -8101,10 +6999,10 @@ ospath@^1.2.2:
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==
-p-each-series@^2.1.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a"
- integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==
+outvariant@^1.4.0, outvariant@^1.4.2, outvariant@^1.4.3:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873"
+ integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==
p-finally@^1.0.0:
version "1.0.0"
@@ -8209,30 +7107,12 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
-parse5-htmlparser2-tree-adapter@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1"
- integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==
- dependencies:
- domhandler "^5.0.2"
- parse5 "^7.0.0"
-
-parse5@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
- integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==
-
-parse5@6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
- integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
-
-parse5@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.0.0.tgz#51f74a5257f5fcc536389e8c2d0b3802e1bfa91a"
- integrity sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==
+parse5@^7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
+ integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==
dependencies:
- entities "^4.3.0"
+ entities "^4.4.0"
pascal-case@^1.1.0:
version "1.1.2"
@@ -8289,12 +7169,10 @@ path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
-path-to-regexp@^1.7.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
- integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
- dependencies:
- isarray "0.0.1"
+path-to-regexp@^6.2.0:
+ version "6.2.2"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36"
+ integrity sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==
path-type@^3.0.0:
version "3.0.0"
@@ -8303,6 +7181,16 @@ path-type@^3.0.0:
dependencies:
pify "^3.0.0"
+pathe@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec"
+ integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==
+
+pathval@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25"
+ integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==
+
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@@ -8328,7 +7216,7 @@ picocolors@^1.0.1:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
-picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1:
+picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -8353,18 +7241,6 @@ pirates@^4.0.1:
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b"
integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==
-pkg-dir@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
- integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
- dependencies:
- find-up "^4.0.0"
-
-pn@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
- integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
-
popper.js@^1.12.5:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
@@ -8792,6 +7668,15 @@ postcss@^8.4.27:
picocolors "^1.0.0"
source-map-js "^1.2.0"
+postcss@^8.4.43:
+ version "8.4.45"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.45.tgz#538d13d89a16ef71edbf75d895284ae06b79e603"
+ integrity sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==
+ dependencies:
+ nanoid "^3.3.7"
+ picocolors "^1.0.1"
+ source-map-js "^1.2.0"
+
precss@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/precss/-/precss-4.0.0.tgz#518ce5c4d31eac9bd268c538ae6fb462f3bf57b3"
@@ -8810,11 +7695,6 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
-prelude-ls@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
- integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
-
prettier-linter-helpers@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
@@ -8842,16 +7722,6 @@ pretty-format@^24.0.0, pretty-format@^24.9.0:
ansi-styles "^3.2.0"
react-is "^16.8.4"
-pretty-format@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
- integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==
- dependencies:
- "@jest/types" "^26.6.2"
- ansi-regex "^5.0.0"
- ansi-styles "^4.0.0"
- react-is "^17.0.1"
-
pretty-format@^27.0.2:
version "27.5.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
@@ -8861,16 +7731,6 @@ pretty-format@^27.0.2:
ansi-styles "^5.0.0"
react-is "^17.0.1"
-pretty-format@^28.1.1:
- version "28.1.1"
- resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.1.tgz#f731530394e0f7fcd95aba6b43c50e02d86b95cb"
- integrity sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==
- dependencies:
- "@jest/schemas" "^28.0.2"
- ansi-regex "^5.0.1"
- ansi-styles "^5.0.0"
- react-is "^18.0.0"
-
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -8896,23 +7756,6 @@ promise-retry@^2.0.1:
err-code "^2.0.2"
retry "^0.12.0"
-prompts@^2.0.1:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
- integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==
- dependencies:
- kleur "^3.0.3"
- sisteransi "^1.0.5"
-
-prop-types-exact@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869"
- integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==
- dependencies:
- has "^1.0.3"
- object.assign "^4.1.0"
- reflect.ownkeys "^0.2.0"
-
prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
@@ -8927,11 +7770,16 @@ proxy-from-env@1.0.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==
-psl@^1.1.28, psl@^1.1.33:
+psl@^1.1.28:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
+psl@^1.1.33:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
+ integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
+
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@@ -8945,6 +7793,11 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+punycode@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
+ integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
+
pusher-js@^5.0.3:
version "5.1.1"
resolved "https://registry.yarnpkg.com/pusher-js/-/pusher-js-5.1.1.tgz#267495d3a821d511bdb20cf3c624ba0556e0b7df"
@@ -8955,6 +7808,11 @@ qs@~6.5.2:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
+querystringify@^2.1.1:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
+ integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -8977,19 +7835,6 @@ raf@^3.4.1:
dependencies:
performance-now "^2.1.0"
-railroad-diagrams@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
- integrity sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==
-
-randexp@0.4.6:
- version "0.4.6"
- resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
- integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==
- dependencies:
- discontinuous-range "1.0.0"
- ret "~0.1.10"
-
react-addons-test-utils@^15.6.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.6.2.tgz#c12b6efdc2247c10da7b8770d185080a7b047156"
@@ -9059,7 +7904,7 @@ react-dropzone@^10.2.1:
file-selector "^0.1.12"
prop-types "^15.7.2"
-react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.4, react-is@^16.8.6:
+react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.4, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -9069,11 +7914,6 @@ react-is@^17.0.1, react-is@^17.0.2:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
-react-is@^18.0.0:
- version "18.2.0"
- resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
- integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
-
react-md-spinner@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/react-md-spinner/-/react-md-spinner-1.0.0.tgz#14159e21b167af64bc9fb70c2558b5d9a5003820"
@@ -9126,7 +7966,7 @@ react-tag-autocomplete@^5.11.2:
resolved "https://registry.yarnpkg.com/react-tag-autocomplete/-/react-tag-autocomplete-5.13.1.tgz#9d3376cbbf66ce8901a62355ca35fd68a58abfc8"
integrity sha512-ECcQnizAxw8VnEDUfCKuA2ZDQ0Fyxds3kVtE4NVAhJvBYOMMgkRNAM3UwyEXAQ0h7nnCwmIA+czJiwso07Mrqw==
-react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0:
+react-test-renderer@^16.12.0:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae"
integrity sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==
@@ -9249,11 +8089,6 @@ redux@^4.0.0, redux@^4.0.4:
dependencies:
"@babel/runtime" "^7.9.2"
-reflect.ownkeys@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
- integrity sha512-qOLsBKHCpSOFKK1NUOCGC5VyeufB6lEsFe92AL2bhIJsacZS1qdoOZSbPk3MYKuT2cFlRDnulKXuuElIrMjGUg==
-
regenerate-unicode-properties@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56"
@@ -9356,23 +8191,7 @@ request-progress@^3.0.0:
dependencies:
throttleit "^1.0.0"
-request-promise-core@1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f"
- integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==
- dependencies:
- lodash "^4.17.19"
-
-request-promise-native@^1.0.5:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28"
- integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==
- dependencies:
- request-promise-core "1.1.4"
- stealthy-require "^1.1.1"
- tough-cookie "^2.3.3"
-
-request@^2.87.0, request@^2.88.0, request@^2.88.2:
+request@^2.88.0, request@^2.88.2:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -9408,34 +8227,27 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
+requires-port@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
+ integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
+
reselect@^4.0.0:
version "4.1.8"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524"
integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==
-resolve-cwd@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
- integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==
- dependencies:
- resolve-from "^5.0.0"
-
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-resolve-from@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
- integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
-
resolve-url@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==
-resolve@^1.10.0, resolve@^1.14.2, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.5.0:
+resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.5.0:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -9508,13 +8320,40 @@ rollup@^3.27.1:
optionalDependencies:
fsevents "~2.3.2"
-rst-selector-parser@^2.2.3:
- version "2.2.3"
- resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
- integrity sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==
+rollup@^4.20.0:
+ version "4.21.2"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.21.2.tgz#f41f277a448d6264e923dd1ea179f0a926aaf9b7"
+ integrity sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==
dependencies:
- lodash.flattendeep "^4.4.0"
- nearley "^2.7.10"
+ "@types/estree" "1.0.5"
+ optionalDependencies:
+ "@rollup/rollup-android-arm-eabi" "4.21.2"
+ "@rollup/rollup-android-arm64" "4.21.2"
+ "@rollup/rollup-darwin-arm64" "4.21.2"
+ "@rollup/rollup-darwin-x64" "4.21.2"
+ "@rollup/rollup-linux-arm-gnueabihf" "4.21.2"
+ "@rollup/rollup-linux-arm-musleabihf" "4.21.2"
+ "@rollup/rollup-linux-arm64-gnu" "4.21.2"
+ "@rollup/rollup-linux-arm64-musl" "4.21.2"
+ "@rollup/rollup-linux-powerpc64le-gnu" "4.21.2"
+ "@rollup/rollup-linux-riscv64-gnu" "4.21.2"
+ "@rollup/rollup-linux-s390x-gnu" "4.21.2"
+ "@rollup/rollup-linux-x64-gnu" "4.21.2"
+ "@rollup/rollup-linux-x64-musl" "4.21.2"
+ "@rollup/rollup-win32-arm64-msvc" "4.21.2"
+ "@rollup/rollup-win32-ia32-msvc" "4.21.2"
+ "@rollup/rollup-win32-x64-msvc" "4.21.2"
+ fsevents "~2.3.2"
+
+rrweb-cssom@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1"
+ integrity sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==
+
+rrweb-cssom@^0.7.1:
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz#c73451a484b86dd7cfb1e0b2898df4b703183e4b"
+ integrity sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==
rsvp@^4.8.4:
version "4.8.5"
@@ -9566,7 +8405,7 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
-"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+"safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -9596,15 +8435,10 @@ sass-graph@^4.0.1:
scss-tokenizer "^0.4.3"
yargs "^17.2.1"
-sax@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
- integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
-
-saxes@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
- integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==
+saxes@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5"
+ integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==
dependencies:
xmlchars "^2.2.0"
@@ -9629,7 +8463,7 @@ select@^1.1.2:
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==
-"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.7.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.5.0:
version "5.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
@@ -9697,11 +8531,6 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-shellwords@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
- integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
-
side-channel@^1.0.3, side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -9711,6 +8540,11 @@ side-channel@^1.0.3, side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
+siginfo@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
+ integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==
+
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
@@ -9721,34 +8555,11 @@ signal-exit@^4.1.0:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
-sinon@^7.5.0:
- version "7.5.0"
- resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.5.0.tgz#e9488ea466070ea908fd44a3d6478fd4923c67ec"
- integrity sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==
- dependencies:
- "@sinonjs/commons" "^1.4.0"
- "@sinonjs/formatio" "^3.2.1"
- "@sinonjs/samsam" "^3.3.3"
- diff "^3.5.0"
- lolex "^4.2.0"
- nise "^1.5.2"
- supports-color "^5.5.0"
-
-sisteransi@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
- integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
-
slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
-slash@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
- integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-
slice-ansi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787"
@@ -9858,14 +8669,6 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
source-map-url "^0.4.0"
urix "^0.1.0"
-source-map-support@^0.5.6:
- version "0.5.21"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
- integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
- dependencies:
- buffer-from "^1.0.0"
- source-map "^0.6.0"
-
source-map-url@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
@@ -9876,7 +8679,7 @@ source-map@^0.5.6:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
-source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -9953,12 +8756,10 @@ stack-utils@^1.0.1:
dependencies:
escape-string-regexp "^2.0.0"
-stack-utils@^2.0.2, stack-utils@^2.0.3:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5"
- integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==
- dependencies:
- escape-string-regexp "^2.0.0"
+stackback@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b"
+ integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==
static-extend@^0.1.1:
version "0.1.2"
@@ -9968,6 +8769,16 @@ static-extend@^0.1.1:
define-property "^0.2.5"
object-copy "^0.1.0"
+statuses@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
+ integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
+
+std-env@^3.7.0:
+ version "3.7.0"
+ resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2"
+ integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==
+
stdout-stream@^1.4.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de"
@@ -9975,24 +8786,16 @@ stdout-stream@^1.4.0:
dependencies:
readable-stream "^2.0.1"
-stealthy-require@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
- integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==
+strict-event-emitter@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93"
+ integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==
string-argv@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
-string-length@^4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
- integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==
- dependencies:
- char-regex "^1.0.2"
- strip-ansi "^6.0.0"
-
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
@@ -10025,15 +8828,6 @@ string.prototype.matchall@^4.0.7:
regexp.prototype.flags "^1.4.1"
side-channel "^1.0.4"
-string.prototype.trim@^1.2.1:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.6.tgz#824960787db37a9e24711802ed0c1d1c0254f83e"
- integrity sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.19.5"
-
string.prototype.trimend@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
@@ -10092,11 +8886,6 @@ strip-bom@^3.0.0:
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
-strip-bom@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878"
- integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==
-
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
@@ -10165,7 +8954,7 @@ supports-color@^3.2.3:
dependencies:
has-flag "^1.0.0"
-supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
+supports-color@^5.3.0, supports-color@^5.4.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
@@ -10179,7 +8968,7 @@ supports-color@^6.1.0:
dependencies:
has-flag "^3.0.0"
-supports-color@^7.0.0, supports-color@^7.1.0:
+supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
@@ -10193,14 +8982,6 @@ supports-color@^8.1.1:
dependencies:
has-flag "^4.0.0"
-supports-hyperlinks@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb"
- integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==
- dependencies:
- has-flag "^4.0.0"
- supports-color "^7.0.0"
-
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
@@ -10214,7 +8995,7 @@ swap-case@^1.1.0:
lower-case "^1.1.1"
upper-case "^1.1.1"
-symbol-tree@^3.2.2, symbol-tree@^3.2.4:
+symbol-tree@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
@@ -10244,14 +9025,6 @@ tcomb@^3.2.21:
resolved "https://registry.yarnpkg.com/tcomb/-/tcomb-3.2.29.tgz#32404fe9456d90c2cf4798682d37439f1ccc386c"
integrity sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==
-terminal-link@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
- integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==
- dependencies:
- ansi-escapes "^4.2.1"
- supports-hyperlinks "^2.0.0"
-
test-exclude@^5.2.3:
version "5.2.3"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0"
@@ -10262,15 +9035,6 @@ test-exclude@^5.2.3:
read-pkg-up "^4.0.0"
require-main-filename "^2.0.0"
-test-exclude@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
- integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==
- dependencies:
- "@istanbuljs/schema" "^0.1.2"
- glob "^7.1.4"
- minimatch "^3.0.4"
-
tether-shepherd@^1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/tether-shepherd/-/tether-shepherd-1.8.1.tgz#4fd9b2fdd9059f04b6c4249456d5ae145a3e9223"
@@ -10288,11 +9052,6 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
-throat@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
- integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==
-
throttleit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
@@ -10321,11 +9080,31 @@ tiny-invariant@^1.0.6:
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
+tinybench@^2.8.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b"
+ integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==
+
tinycolor2@^1.4.1:
version "1.4.2"
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==
+tinypool@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.1.tgz#c64233c4fac4304e109a64340178760116dbe1fe"
+ integrity sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==
+
+tinyrainbow@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5"
+ integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==
+
+tinyspy@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.0.tgz#cb61644f2713cd84dee184863f4642e06ddf0585"
+ integrity sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==
+
title-case@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/title-case/-/title-case-1.1.2.tgz#fae4a6ae546bfa22d083a0eea910a40d12ed4f5a"
@@ -10383,7 +9162,17 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"
-tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
+tough-cookie@^4.1.4:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36"
+ integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==
+ dependencies:
+ psl "^1.1.33"
+ punycode "^2.1.1"
+ universalify "^0.2.0"
+ url-parse "^1.5.3"
+
+tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
@@ -10391,28 +9180,12 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
psl "^1.1.28"
punycode "^2.1.1"
-tough-cookie@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
- integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==
- dependencies:
- psl "^1.1.33"
- punycode "^2.1.1"
- universalify "^0.1.2"
-
-tr46@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
- integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==
- dependencies:
- punycode "^2.1.0"
-
-tr46@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
- integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==
+tr46@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.0.0.tgz#3b46d583613ec7283020d79019f1335723801cec"
+ integrity sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==
dependencies:
- punycode "^2.1.1"
+ punycode "^2.3.1"
trim-newlines@^3.0.0:
version "3.0.1"
@@ -10436,7 +9209,7 @@ tsconfig-paths@^3.14.1:
minimist "^1.2.6"
strip-bom "^3.0.0"
-tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0:
+tslib@^2.0.1, tslib@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
@@ -10465,18 +9238,6 @@ type-check@^0.4.0, type-check@~0.4.0:
dependencies:
prelude-ls "^1.2.1"
-type-check@~0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
- integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==
- dependencies:
- prelude-ls "~1.1.2"
-
-type-detect@4.0.8:
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
- integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
-
type-fest@^0.18.0:
version "0.18.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f"
@@ -10502,6 +9263,11 @@ type-fest@^0.8.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
+type-fest@^4.9.0:
+ version "4.26.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.26.1.tgz#a4a17fa314f976dd3e6d6675ef6c775c16d7955e"
+ integrity sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==
+
type@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
@@ -10512,13 +9278,6 @@ type@^2.5.0:
resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f"
integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==
-typedarray-to-buffer@^3.1.5:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
- integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
- dependencies:
- is-typedarray "^1.0.0"
-
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
@@ -10534,6 +9293,11 @@ underscore@>=1.8.3, underscore@^1.9.1:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee"
integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==
+undici-types@~6.19.2:
+ version "6.19.8"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
+ integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
+
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
@@ -10586,10 +9350,10 @@ unique-slug@^2.0.0:
dependencies:
imurmurhash "^0.1.4"
-universalify@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
- integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+universalify@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
+ integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
universalify@^2.0.0:
version "2.0.0"
@@ -10649,6 +9413,14 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==
+url-parse@^1.5.3:
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
+ integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
+ dependencies:
+ querystringify "^2.1.1"
+ requires-port "^1.0.0"
+
use-memo-one@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.2.tgz#0c8203a329f76e040047a35a1197defe342fab20"
@@ -10680,20 +9452,11 @@ uuid@^3.3.2, uuid@^3.3.3:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-uuid@^8.3.0, uuid@^8.3.2:
+uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
-v8-to-istanbul@^7.0.0:
- version "7.1.2"
- resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1"
- integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==
- dependencies:
- "@types/istanbul-lib-coverage" "^2.0.1"
- convert-source-map "^1.6.0"
- source-map "^0.7.3"
-
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -10711,6 +9474,17 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
+vite-node@2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.0.5.tgz#36d909188fc6e3aba3da5fc095b3637d0d18e27b"
+ integrity sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==
+ dependencies:
+ cac "^6.7.14"
+ debug "^4.3.5"
+ pathe "^1.1.2"
+ tinyrainbow "^1.2.0"
+ vite "^5.0.0"
+
vite-plugin-ruby@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/vite-plugin-ruby/-/vite-plugin-ruby-3.2.2.tgz#a174bc435b11350cfcb1b976342ca740d0bcaed2"
@@ -10730,19 +9504,48 @@ vite@^4.5.3:
optionalDependencies:
fsevents "~2.3.2"
-w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
- integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==
+vite@^5.0.0:
+ version "5.4.3"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.3.tgz#771c470e808cb6732f204e1ee96c2ed65b97a0eb"
+ integrity sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==
dependencies:
- browser-process-hrtime "^1.0.0"
+ esbuild "^0.21.3"
+ postcss "^8.4.43"
+ rollup "^4.20.0"
+ optionalDependencies:
+ fsevents "~2.3.3"
-w3c-xmlserializer@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
- integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
+vitest@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.0.5.tgz#2f15a532704a7181528e399cc5b754c7f335fd62"
+ integrity sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==
+ dependencies:
+ "@ampproject/remapping" "^2.3.0"
+ "@vitest/expect" "2.0.5"
+ "@vitest/pretty-format" "^2.0.5"
+ "@vitest/runner" "2.0.5"
+ "@vitest/snapshot" "2.0.5"
+ "@vitest/spy" "2.0.5"
+ "@vitest/utils" "2.0.5"
+ chai "^5.1.1"
+ debug "^4.3.5"
+ execa "^8.0.1"
+ magic-string "^0.30.10"
+ pathe "^1.1.2"
+ std-env "^3.7.0"
+ tinybench "^2.8.0"
+ tinypool "^1.0.0"
+ tinyrainbow "^1.2.0"
+ vite "^5.0.0"
+ vite-node "2.0.5"
+ why-is-node-running "^2.3.0"
+
+w3c-xmlserializer@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz#f925ba26855158594d907313cedd1476c5967f6c"
+ integrity sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==
dependencies:
- xml-name-validator "^3.0.0"
+ xml-name-validator "^5.0.0"
wait-on@^3.3.0:
version "3.3.0"
@@ -10769,59 +9572,30 @@ warning@^2.1.0:
dependencies:
loose-envify "^1.0.0"
-webidl-conversions@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
- integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
-
-webidl-conversions@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
- integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
-
-webidl-conversions@^6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
- integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
-
-whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
- integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
- dependencies:
- iconv-lite "0.4.24"
-
-whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
- integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
+webidl-conversions@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
+ integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
-whatwg-url@^6.4.1:
- version "6.5.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8"
- integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==
+whatwg-encoding@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5"
+ integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==
dependencies:
- lodash.sortby "^4.7.0"
- tr46 "^1.0.1"
- webidl-conversions "^4.0.2"
+ iconv-lite "0.6.3"
-whatwg-url@^7.0.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
- integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==
- dependencies:
- lodash.sortby "^4.7.0"
- tr46 "^1.0.1"
- webidl-conversions "^4.0.2"
+whatwg-mimetype@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a"
+ integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==
-whatwg-url@^8.0.0, whatwg-url@^8.5.0:
- version "8.7.0"
- resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
- integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
+whatwg-url@^14.0.0:
+ version "14.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.0.0.tgz#00baaa7fd198744910c4b1ef68378f2200e4ceb6"
+ integrity sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==
dependencies:
- lodash "^4.7.0"
- tr46 "^2.1.0"
- webidl-conversions "^6.1.0"
+ tr46 "^5.0.0"
+ webidl-conversions "^7.0.0"
which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2:
version "1.0.2"
@@ -10844,11 +9618,6 @@ which-collection@^1.0.1:
is-weakmap "^2.0.1"
is-weakset "^2.0.1"
-which-module@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
- integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
-
which-typed-array@^1.1.2:
version "1.1.8"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f"
@@ -10875,6 +9644,14 @@ which@^2.0.1, which@^2.0.2:
dependencies:
isexe "^2.0.0"
+why-is-node-running@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04"
+ integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==
+ dependencies:
+ siginfo "^2.0.0"
+ stackback "0.0.2"
+
wide-align@^1.1.2, wide-align@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
@@ -10887,11 +9664,6 @@ word-wrap@^1.2.5:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
-word-wrap@~1.2.3:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f"
- integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==
-
wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
@@ -10933,43 +9705,21 @@ write-file-atomic@2.4.1:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
-write-file-atomic@^3.0.0:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
- integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
- dependencies:
- imurmurhash "^0.1.4"
- is-typedarray "^1.0.0"
- signal-exit "^3.0.2"
- typedarray-to-buffer "^3.1.5"
-
-ws@^5.2.0:
- version "5.2.4"
- resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.4.tgz#c7bea9f1cfb5f410de50e70e82662e562113f9a7"
- integrity sha512-fFCejsuC8f9kOSu9FYaOw8CdO68O3h5v0lg4p74o8JqWpwTf9tniOD+nOB78aWoVSS6WptVUmDrp/KPsMVBWFQ==
- dependencies:
- async-limiter "~1.0.0"
-
-ws@^7.4.6:
- version "7.5.10"
- resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9"
- integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==
+ws@^8.18.0:
+ version "8.18.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
+ integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
-xml-name-validator@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
- integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+xml-name-validator@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673"
+ integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
-y18n@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
- integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
-
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
@@ -10990,14 +9740,6 @@ yaml@~2.5.0:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d"
integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==
-yargs-parser@^18.1.2:
- version "18.1.3"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
- integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
-
yargs-parser@^20.2.3:
version "20.2.9"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
@@ -11008,22 +9750,10 @@ yargs-parser@^21.0.0:
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35"
integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==
-yargs@^15.4.1:
- version "15.4.1"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
- integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
- dependencies:
- cliui "^6.0.0"
- decamelize "^1.2.0"
- find-up "^4.1.0"
- get-caller-file "^2.0.1"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^4.2.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^18.1.2"
+yargs-parser@^21.1.1:
+ version "21.1.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+ integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.2.1:
version "17.5.1"
@@ -11038,6 +9768,19 @@ yargs@^17.2.1:
y18n "^5.0.5"
yargs-parser "^21.0.0"
+yargs@^17.7.2:
+ version "17.7.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
+ integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
+ dependencies:
+ cliui "^8.0.1"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.3"
+ y18n "^5.0.5"
+ yargs-parser "^21.1.1"
+
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
@@ -11050,3 +9793,8 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+yoctocolors-cjs@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242"
+ integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==