diff options
29 files changed, 419 insertions, 289 deletions
@@ -574,3 +574,6 @@ gem 'error_tracking_open_api', path: 'vendor/gems/error_tracking_open_api' # Vulnerability advisories gem 'cvss-suite', '~> 3.0.1', require: 'cvss_suite' + +# Work with RPM packages +gem 'arr-pm', '~> 0.0.12' diff --git a/Gemfile.checksum b/Gemfile.checksum index 357d0e4119f..c292b46bc81 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -19,6 +19,7 @@ {"name":"akismet","version":"3.0.0","platform":"ruby","checksum":"74991b8e3d3257eeea996b47069abb8da2006c84a144255123e8dffd1c86b230"}, {"name":"android_key_attestation","version":"0.3.0","platform":"ruby","checksum":"467eb01a99d2bb48ef9cf24cc13712669d7056cba5a52d009554ff037560570b"}, {"name":"apollo_upload_server","version":"2.1.0","platform":"ruby","checksum":"e5f3c9dda0c2ca775d007072742b98d517dfd91a667111fedbcdc94dfabd904e"}, +{"name":"arr-pm","version":"0.0.12","platform":"ruby","checksum":"fdff482f75239239201f4d667d93424412639aad0b3b0ad4d827e7c637e0ad39"}, {"name":"asana","version":"0.10.13","platform":"ruby","checksum":"36d0d37f8dd6118a54580f1b80224875d7b6a9027598938e1722a508bfc2d7ac"}, {"name":"asciidoctor","version":"2.0.17","platform":"ruby","checksum":"ed5b5e399e8d64994cc16f0983f993d6e33990909a8415b6fc8b786cdeb00f3d"}, {"name":"asciidoctor-include-ext","version":"0.4.0","platform":"ruby","checksum":"406adb9d2fbfc25536609ca13b787ed704dc06a4e49d6709b83f3bad578f7878"}, diff --git a/Gemfile.lock b/Gemfile.lock index d16843b2438..395e3f4b1b8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -169,6 +169,7 @@ GEM apollo_upload_server (2.1.0) actionpack (>= 4.2) graphql (>= 1.8) + arr-pm (0.0.12) asana (0.10.13) faraday (~> 1.0) faraday_middleware (~> 1.0) @@ -1535,6 +1536,7 @@ DEPENDENCIES addressable (~> 2.8) akismet (~> 3.0) apollo_upload_server (~> 2.1.0) + arr-pm (~> 0.0.12) asana (~> 0.10.13) asciidoctor (~> 2.0.17) asciidoctor-include-ext (~> 0.4.0) diff --git a/app/services/packages/rpm/parse_package_service.rb b/app/services/packages/rpm/parse_package_service.rb new file mode 100644 index 00000000000..689a161a81a --- /dev/null +++ b/app/services/packages/rpm/parse_package_service.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module Packages + module Rpm + class ParsePackageService + include ::Gitlab::Utils::StrongMemoize + + BUILD_ATTRIBUTES_METHOD_NAMES = %i[changelogs requirements provides].freeze + STATIC_ATTRIBUTES = %i[name version release summary description arch + license sourcerpm group buildhost packager vendor].freeze + + CHANGELOGS_RPM_KEYS = %i[changelogtext changelogtime].freeze + REQUIREMENTS_RPM_KEYS = %i[requirename requireversion requireflags].freeze + PROVIDES_RPM_KEYS = %i[providename provideflags provideversion].freeze + + def initialize(package_file) + @rpm = RPM::File.new(package_file) + end + + def execute + raise ArgumentError, 'Unable to parse package' unless valid_package? + + { + files: rpm.files || [], + epoch: package_tags[:epoch] || '0', + changelogs: build_changelogs, + requirements: build_requirements, + provides: build_provides + }.merge(extract_static_attributes) + end + + private + + attr_reader :rpm + + def valid_package? + rpm.files && package_tags && true + rescue RuntimeError + # if arr-pm throws an error due to an incorrect file format, + # we just want this validation to fail rather than throw an exception + false + end + + def package_tags + strong_memoize(:package_tags) do + rpm.tags + end + end + + def extract_static_attributes + STATIC_ATTRIBUTES.each_with_object({}) do |attribute, hash| + hash[attribute] = package_tags[attribute] + end + end + + # Define methods for building RPM attribute data from parsed package + # Transform + # changelogtime: [123, 234], + # changelogname: ["First", "Second"] + # changelogtext: ["Work1", "Work2"] + # Into + # changelog: [ + # {changelogname: "First", changelogtext: "Work1", changelogtime: 123}, + # {changelogname: "Second", changelogtext: "Work2", changelogtime: 234} + # ] + BUILD_ATTRIBUTES_METHOD_NAMES.each do |resource| + define_method("build_#{resource}") do + resource_keys = self.class.const_get("#{resource.upcase}_RPM_KEYS", false).dup + return [] if resource_keys.any? { package_tags[_1].blank? } + + first_attributes = package_tags[resource_keys.first] + zipped_data = first_attributes.zip(*resource_keys[1..].map { package_tags[_1] }) + build_hashes(resource_keys, zipped_data) + end + end + + def build_hashes(resource_keys, zipped_data) + zipped_data.map do |data| + resource_keys.zip(data).to_h + end + end + end + end +end diff --git a/config/feature_flags/development/child_epics_from_different_hierarchies.yml b/config/feature_flags/development/child_epics_from_different_hierarchies.yml new file mode 100644 index 00000000000..9bafdea8465 --- /dev/null +++ b/config/feature_flags/development/child_epics_from_different_hierarchies.yml @@ -0,0 +1,8 @@ +--- +name: child_epics_from_different_hierarchies +introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/99147" +rollout_issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/375622" +milestone: '15.5' +type: development +group: group::product planning +default_enabled: false diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 025e3f16c7f..7cfe9c67b0d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -41034,6 +41034,27 @@ msgstr "" msgid "This epic already has the maximum number of child epics." msgstr "" +msgid "This epic cannot be added. An epic cannot be added to itself." +msgstr "" + +msgid "This epic cannot be added. An epic cannot belong to an ancestor group of its parent epic." +msgstr "" + +msgid "This epic cannot be added. An epic must belong to the same group or subgroup as its parent epic." +msgstr "" + +msgid "This epic cannot be added. It is already an ancestor of the parent epic." +msgstr "" + +msgid "This epic cannot be added. It is already assigned to the parent epic." +msgstr "" + +msgid "This epic cannot be added. One or more epics would exceed the maximum depth (%{max_depth}) from its most distant ancestor." +msgstr "" + +msgid "This epic cannot be added. You don't have access to perform this action." +msgstr "" + msgid "This epic does not exist or you don't have sufficient permission." msgstr "" diff --git a/package.json b/package.json index 71051725cd9..e6885d418ed 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "yaml": "^2.0.0-10" }, "devDependencies": { - "@gitlab/eslint-plugin": "17.0.0", + "@gitlab/eslint-plugin": "18.1.0", "@gitlab/stylelint-config": "4.1.0", "@graphql-eslint/eslint-plugin": "3.11.2", "@testing-library/dom": "^7.16.2", diff --git a/spec/fixtures/packages/rpm/hello-0.0.1-1.fc29.src.rpm b/spec/fixtures/packages/rpm/hello-0.0.1-1.fc29.src.rpm Binary files differnew file mode 100644 index 00000000000..8284faab80a --- /dev/null +++ b/spec/fixtures/packages/rpm/hello-0.0.1-1.fc29.src.rpm diff --git a/spec/frontend/__helpers__/class_spec_helper.js b/spec/frontend/__helpers__/class_spec_helper.js deleted file mode 100644 index b26f087f0c5..00000000000 --- a/spec/frontend/__helpers__/class_spec_helper.js +++ /dev/null @@ -1,10 +0,0 @@ -// eslint-disable-next-line jest/no-export -export default class ClassSpecHelper { - static itShouldBeAStaticMethod(base, method) { - return it('should be a static method', () => { - expect(Object.prototype.hasOwnProperty.call(base, method)).toBeTruthy(); - }); - } -} - -window.ClassSpecHelper = ClassSpecHelper; diff --git a/spec/frontend/__helpers__/class_spec_helper_spec.js b/spec/frontend/__helpers__/class_spec_helper_spec.js deleted file mode 100644 index 533d5687bde..00000000000 --- a/spec/frontend/__helpers__/class_spec_helper_spec.js +++ /dev/null @@ -1,26 +0,0 @@ -/* global ClassSpecHelper */ - -import './class_spec_helper'; - -describe('ClassSpecHelper', () => { - let testContext; - - beforeEach(() => { - testContext = {}; - }); - - describe('itShouldBeAStaticMethod', () => { - beforeEach(() => { - class TestClass { - instanceMethod() { - this.prop = 'val'; - } - static staticMethod() {} - } - - testContext.TestClass = TestClass; - }); - - ClassSpecHelper.itShouldBeAStaticMethod(ClassSpecHelper, 'itShouldBeAStaticMethod'); - }); -}); diff --git a/spec/frontend/__helpers__/shared_test_setup.js b/spec/frontend/__helpers__/shared_test_setup.js index 62cfc8d560f..bc295bc62ae 100644 --- a/spec/frontend/__helpers__/shared_test_setup.js +++ b/spec/frontend/__helpers__/shared_test_setup.js @@ -61,6 +61,7 @@ Object.assign(global, { beforeEach(() => { // make sure that each test actually tests something // see https://jestjs.io/docs/en/expect#expecthasassertions + // eslint-disable-next-line jest/no-standalone-expect expect.hasAssertions(); // Reset the mocked window.location. This ensures tests don't interfere with diff --git a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js index fb9e97e7505..e0075aa71d9 100644 --- a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js +++ b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js @@ -304,12 +304,12 @@ describe('AlertsSettingsForm', () => { }); describe.each` - payload | resetPayloadAndMappingConfirmed | disabled - ${validSamplePayload} | ${true} | ${undefined} - ${emptySamplePayload} | ${true} | ${undefined} - ${validSamplePayload} | ${false} | ${'disabled'} - ${emptySamplePayload} | ${false} | ${undefined} - `('', ({ payload, resetPayloadAndMappingConfirmed, disabled }) => { + context | payload | resetPayloadAndMappingConfirmed | disabled + ${'valid payload, confirmed and enabled'} | ${validSamplePayload} | ${true} | ${undefined} + ${'empty payload, confirmed and enabled'} | ${emptySamplePayload} | ${true} | ${undefined} + ${'valid payload, unconfirmed and disabled'} | ${validSamplePayload} | ${false} | ${'disabled'} + ${'empty payload, unconfirmed and enabled'} | ${emptySamplePayload} | ${false} | ${undefined} + `('given $context', ({ payload, resetPayloadAndMappingConfirmed, disabled }) => { const payloadResetMsg = resetPayloadAndMappingConfirmed ? 'was confirmed' : 'was not confirmed'; @@ -333,12 +333,12 @@ describe('AlertsSettingsForm', () => { describe('action buttons for sample payload', () => { describe.each` - resetPayloadAndMappingConfirmed | payloadExample | caption - ${false} | ${validSamplePayload} | ${'Edit payload'} - ${true} | ${emptySamplePayload} | ${'Parse payload fields'} - ${true} | ${validSamplePayload} | ${'Parse payload fields'} - ${false} | ${emptySamplePayload} | ${'Parse payload fields'} - `('', ({ resetPayloadAndMappingConfirmed, payloadExample, caption }) => { + context | resetPayloadAndMappingConfirmed | payloadExample | caption + ${'valid payload, unconfirmed'} | ${false} | ${validSamplePayload} | ${'Edit payload'} + ${'empty payload, confirmed'} | ${true} | ${emptySamplePayload} | ${'Parse payload fields'} + ${'valid payload, confirmed'} | ${true} | ${validSamplePayload} | ${'Parse payload fields'} + ${'empty payload, unconfirmed'} | ${false} | ${emptySamplePayload} | ${'Parse payload fields'} + `('given $context', ({ resetPayloadAndMappingConfirmed, payloadExample, caption }) => { const samplePayloadMsg = payloadExample ? 'was provided' : 'was not provided'; const payloadResetMsg = resetPayloadAndMappingConfirmed ? 'was confirmed' @@ -402,24 +402,27 @@ describe('AlertsSettingsForm', () => { ${true} | ${true} | ${2} | ${false} ${true} | ${false} | ${1} | ${false} ${false} | ${true} | ${1} | ${false} - `('', ({ alertFieldsProvided, multiIntegrations, integrationOption, visible }) => { - const visibleMsg = visible ? 'rendered' : 'not rendered'; - const alertFieldsMsg = alertFieldsProvided ? 'provided' : 'not provided'; - const integrationType = integrationOption === 1 ? typeSet.http : typeSet.prometheus; - const multiIntegrationsEnabled = multiIntegrations ? 'enabled' : 'not enabled'; + `( + 'given alertFieldsProvided: $alertFieldsProvided, multiIntegrations: $multiIntegrations, integrationOption: $integrationOption, visible: $visible', + ({ alertFieldsProvided, multiIntegrations, integrationOption, visible }) => { + const visibleMsg = visible ? 'rendered' : 'not rendered'; + const alertFieldsMsg = alertFieldsProvided ? 'provided' : 'not provided'; + const integrationType = integrationOption === 1 ? typeSet.http : typeSet.prometheus; + const multiIntegrationsEnabled = multiIntegrations ? 'enabled' : 'not enabled'; + + it(`is ${visibleMsg} when multiIntegrations are ${multiIntegrationsEnabled}, integration type is ${integrationType} and alert fields are ${alertFieldsMsg}`, async () => { + createComponent({ + multiIntegrations, + props: { + alertFields: alertFieldsProvided ? alertFields : [], + }, + }); + await selectOptionAtIndex(integrationOption); - it(`is ${visibleMsg} when multiIntegrations are ${multiIntegrationsEnabled}, integration type is ${integrationType} and alert fields are ${alertFieldsMsg}`, async () => { - createComponent({ - multiIntegrations, - props: { - alertFields: alertFieldsProvided ? alertFields : [], - }, + expect(findMappingBuilder().exists()).toBe(visible); }); - await selectOptionAtIndex(integrationOption); - - expect(findMappingBuilder().exists()).toBe(visible); - }); - }); + }, + ); }); describe('Form validation', () => { diff --git a/spec/frontend/behaviors/bind_in_out_spec.js b/spec/frontend/behaviors/bind_in_out_spec.js index 4d958e30b4d..7b40b1d3cd7 100644 --- a/spec/frontend/behaviors/bind_in_out_spec.js +++ b/spec/frontend/behaviors/bind_in_out_spec.js @@ -1,4 +1,3 @@ -import ClassSpecHelper from 'helpers/class_spec_helper'; import BindInOut from '~/behaviors/bind_in_out'; describe('BindInOut', () => { @@ -142,7 +141,9 @@ describe('BindInOut', () => { testContext.initAll = BindInOut.initAll(); }); - ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'initAll'); + it('should be a static method', () => { + expect(BindInOut.initAll).toEqual(expect.any(Function)); + }); it('should call .querySelectorAll', () => { expect(document.querySelectorAll).toHaveBeenCalledWith('*[data-bind-in]'); @@ -169,7 +170,9 @@ describe('BindInOut', () => { testContext.init = BindInOut.init({}, {}); }); - ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'init'); + it('should be a static method', () => { + expect(BindInOut.init).toEqual(expect.any(Function)); + }); it('should call .addEvents', () => { expect(BindInOut.prototype.addEvents).toHaveBeenCalled(); diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index e919300228a..78859525a63 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -1047,60 +1047,58 @@ describe('moveIssueCard and undoMoveIssueCard', () => { let undoMutations; describe('when re-ordering card', () => { - beforeEach( - ({ - itemId = 123, - fromListId = 'gid://gitlab/List/1', - toListId = 'gid://gitlab/List/1', - originalIssue = { foo: 'bar' }, - originalIndex = 0, - moveBeforeId = undefined, - moveAfterId = undefined, - allItemsLoadedInList = true, - listPosition = undefined, - } = {}) => { - state = { - boardLists: { - [toListId]: { listType: ListType.backlog }, - [fromListId]: { listType: ListType.backlog }, - }, - boardItems: { [itemId]: originalIssue }, - boardItemsByListId: { [fromListId]: [123] }, - }; - params = { - itemId, - fromListId, - toListId, - moveBeforeId, - moveAfterId, - listPosition, - allItemsLoadedInList, - }; - moveMutations = [ - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { - itemId, - listId: toListId, - moveBeforeId, - moveAfterId, - listPosition, - allItemsLoadedInList, - atIndex: originalIndex, - }, - }, - ]; - undoMutations = [ - { type: types.UPDATE_BOARD_ITEM, payload: originalIssue }, - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { itemId, listId: fromListId, atIndex: originalIndex }, + beforeEach(() => { + const itemId = 123; + const fromListId = 'gid://gitlab/List/1'; + const toListId = 'gid://gitlab/List/1'; + const originalIssue = { foo: 'bar' }; + const originalIndex = 0; + const moveBeforeId = undefined; + const moveAfterId = undefined; + const allItemsLoadedInList = true; + const listPosition = undefined; + + state = { + boardLists: { + [toListId]: { listType: ListType.backlog }, + [fromListId]: { listType: ListType.backlog }, + }, + boardItems: { [itemId]: originalIssue }, + boardItemsByListId: { [fromListId]: [123] }, + }; + params = { + itemId, + fromListId, + toListId, + moveBeforeId, + moveAfterId, + listPosition, + allItemsLoadedInList, + }; + moveMutations = [ + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { + itemId, + listId: toListId, + moveBeforeId, + moveAfterId, + listPosition, + allItemsLoadedInList, + atIndex: originalIndex, }, - ]; - }, - ); + }, + ]; + undoMutations = [ + { type: types.UPDATE_BOARD_ITEM, payload: originalIssue }, + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { itemId, listId: fromListId, atIndex: originalIndex }, + }, + ]; + }); it('moveIssueCard commits a correct set of actions', () => { testAction({ @@ -1144,42 +1142,40 @@ describe('moveIssueCard and undoMoveIssueCard', () => { }, ], ])('when %s', (_, { toListType, fromListType }) => { - beforeEach( - ({ - itemId = 123, - fromListId = 'gid://gitlab/List/1', - toListId = 'gid://gitlab/List/2', - originalIssue = { foo: 'bar' }, - originalIndex = 0, - moveBeforeId = undefined, - moveAfterId = undefined, - } = {}) => { - state = { - boardLists: { - [fromListId]: { listType: fromListType }, - [toListId]: { listType: toListType }, - }, - boardItems: { [itemId]: originalIssue }, - boardItemsByListId: { [fromListId]: [123], [toListId]: [] }, - }; - params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId }; - moveMutations = [ - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { itemId, listId: toListId, moveBeforeId, moveAfterId }, - }, - ]; - undoMutations = [ - { type: types.UPDATE_BOARD_ITEM, payload: originalIssue }, - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: toListId } }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { itemId, listId: fromListId, atIndex: originalIndex }, - }, - ]; - }, - ); + beforeEach(() => { + const itemId = 123; + const fromListId = 'gid://gitlab/List/1'; + const toListId = 'gid://gitlab/List/2'; + const originalIssue = { foo: 'bar' }; + const originalIndex = 0; + const moveBeforeId = undefined; + const moveAfterId = undefined; + + state = { + boardLists: { + [fromListId]: { listType: fromListType }, + [toListId]: { listType: toListType }, + }, + boardItems: { [itemId]: originalIssue }, + boardItemsByListId: { [fromListId]: [123], [toListId]: [] }, + }; + params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId }; + moveMutations = [ + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { itemId, listId: toListId, moveBeforeId, moveAfterId }, + }, + ]; + undoMutations = [ + { type: types.UPDATE_BOARD_ITEM, payload: originalIssue }, + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: toListId } }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { itemId, listId: fromListId, atIndex: originalIndex }, + }, + ]; + }); it('moveIssueCard commits a correct set of actions', () => { testAction({ @@ -1216,47 +1212,45 @@ describe('moveIssueCard and undoMoveIssueCard', () => { }, ], ])('when %s', (_, { toListType, fromListType }) => { - beforeEach( - ({ - itemId = 123, - fromListId = 'gid://gitlab/List/1', - toListId = 'gid://gitlab/List/2', - originalIssue = { foo: 'bar' }, - originalIndex = 0, - moveBeforeId = undefined, - moveAfterId = undefined, - } = {}) => { - state = { - boardLists: { - [fromListId]: { listType: fromListType }, - [toListId]: { listType: toListType }, - }, - boardItems: { [itemId]: originalIssue }, - boardItemsByListId: { [fromListId]: [123], [toListId]: [] }, - }; - params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId }; - moveMutations = [ - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { itemId, listId: toListId, moveBeforeId, moveAfterId }, - }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { itemId, listId: fromListId, atIndex: originalIndex }, - }, - ]; - undoMutations = [ - { type: types.UPDATE_BOARD_ITEM, payload: originalIssue }, - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, - { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: toListId } }, - { - type: types.ADD_BOARD_ITEM_TO_LIST, - payload: { itemId, listId: fromListId, atIndex: originalIndex }, - }, - ]; - }, - ); + beforeEach(() => { + const itemId = 123; + const fromListId = 'gid://gitlab/List/1'; + const toListId = 'gid://gitlab/List/2'; + const originalIssue = { foo: 'bar' }; + const originalIndex = 0; + const moveBeforeId = undefined; + const moveAfterId = undefined; + + state = { + boardLists: { + [fromListId]: { listType: fromListType }, + [toListId]: { listType: toListType }, + }, + boardItems: { [itemId]: originalIssue }, + boardItemsByListId: { [fromListId]: [123], [toListId]: [] }, + }; + params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId }; + moveMutations = [ + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { itemId, listId: toListId, moveBeforeId, moveAfterId }, + }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { itemId, listId: fromListId, atIndex: originalIndex }, + }, + ]; + undoMutations = [ + { type: types.UPDATE_BOARD_ITEM, payload: originalIssue }, + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } }, + { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: toListId } }, + { + type: types.ADD_BOARD_ITEM_TO_LIST, + payload: { itemId, listId: fromListId, atIndex: originalIndex }, + }, + ]; + }); it('moveIssueCard commits a correct set of actions', () => { testAction({ diff --git a/spec/frontend/captcha/init_recaptcha_script_spec.js b/spec/frontend/captcha/init_recaptcha_script_spec.js index af07c9e474e..78480821d95 100644 --- a/spec/frontend/captcha/init_recaptcha_script_spec.js +++ b/spec/frontend/captcha/init_recaptcha_script_spec.js @@ -1,5 +1,4 @@ import { - RECAPTCHA_API_URL_PREFIX, RECAPTCHA_ONLOAD_CALLBACK_NAME, clearMemoizeCache, initRecaptchaScript, @@ -26,7 +25,7 @@ describe('initRecaptchaScript', () => { <head> <script class="js-recaptcha-script" - src="${RECAPTCHA_API_URL_PREFIX}?onload=${RECAPTCHA_ONLOAD_CALLBACK_NAME}&render=explicit" + src="undefined?onload=recaptchaOnloadCallback&render=explicit" /> </head> `); diff --git a/spec/frontend/content_editor/markdown_processing_spec_helper.js b/spec/frontend/content_editor/markdown_processing_spec_helper.js index 38d384df235..6f10f294fb0 100644 --- a/spec/frontend/content_editor/markdown_processing_spec_helper.js +++ b/spec/frontend/content_editor/markdown_processing_spec_helper.js @@ -84,7 +84,7 @@ export const describeMarkdownProcessing = (description, markdownYamlPath) => { return; } - it(exampleName, async () => { + it(`${exampleName}`, async () => { await testSerializesHtmlToMarkdownForElement(example); }); }); diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js index 638e4713ddc..9fb00d37060 100644 --- a/spec/frontend/diffs/store/actions_spec.js +++ b/spec/frontend/diffs/store/actions_spec.js @@ -175,31 +175,6 @@ describe('DiffsStoreActions', () => { [{ type: 'startRenderDiffsQueue' }, { type: 'startRenderDiffsQueue' }], ); }); - - it.each` - viewStyle | otherView - ${'inline'} | ${'parallel'} - ${'parallel'} | ${'inline'} - `( - 'should make a request with the view parameter "$viewStyle" when the batchEndpoint already contains "$otherView"', - ({ viewStyle, otherView }) => { - const endpointBatch = '/fetch/diffs_batch'; - - diffActions - .fetchDiffFilesBatch({ - commit: () => {}, - state: { - endpointBatch: `${endpointBatch}?view=${otherView}`, - diffViewType: viewStyle, - }, - }) - .then(() => { - expect(mock.history.get[0].url).toContain(`view=${viewStyle}`); - expect(mock.history.get[0].url).not.toContain(`view=${otherView}`); - }) - .catch(() => {}); - }, - ); }); describe('fetchDiffFilesMeta', () => { diff --git a/spec/frontend/groups/components/app_spec.js b/spec/frontend/groups/components/app_spec.js index 75f70bbf19d..56529726350 100644 --- a/spec/frontend/groups/components/app_spec.js +++ b/spec/frontend/groups/components/app_spec.js @@ -396,7 +396,7 @@ describe('AppComponent', () => { `( 'when `action` is $action, `groups` is $groups, `fromSearch` is $fromSearch, and `renderEmptyState` is $renderEmptyState', ({ action, groups, fromSearch, renderEmptyState, expected }) => { - it(expected ? 'renders empty state' : 'does not render empty state', async () => { + it(`${expected ? 'renders' : 'does not render'} empty state`, async () => { createShallowComponent({ propsData: { action, renderEmptyState }, }); diff --git a/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js b/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js index cc8346253ee..d41031f9eaa 100644 --- a/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js +++ b/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js @@ -238,7 +238,7 @@ describe('NewBranchForm', () => { scenario | mutation | alertTitle | alertText ${'with errors-as-data'} | ${mockCreateBranchMutationWithErrors} | ${CREATE_BRANCH_ERROR_WITH_CONTEXT} | ${mockCreateBranchMutationResponseWithErrors.data.createBranch.errors[0]} ${'top-level error'} | ${mockCreateBranchMutationFailed} | ${''} | ${CREATE_BRANCH_ERROR_GENERIC} - `('', ({ mutation, alertTitle, alertText }) => { + `('given $scenario', ({ mutation, alertTitle, alertText }) => { beforeEach(async () => { createComponent({ mockApollo: createMockApolloProvider({ diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js index d16c13d6fd3..e414ada1854 100644 --- a/spec/frontend/notes/components/discussion_actions_spec.js +++ b/spec/frontend/notes/components/discussion_actions_spec.js @@ -81,7 +81,7 @@ describe('DiscussionActions', () => { }); }); - it(shouldRender ? 'renders resolve buttons' : 'does not render resolve buttons', () => { + it(`${shouldRender ? 'renders' : 'does not render'} resolve buttons`, () => { expect(wrapper.findComponent(ResolveDiscussionButton).exists()).toBe(shouldRender); expect(wrapper.findComponent(ResolveWithIssueButton).exists()).toBe(shouldRender); }); diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js index 4dea34ebd41..849215e286b 100644 --- a/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js +++ b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js @@ -58,7 +58,7 @@ describe('Harbor tag list row', () => { expect(findByTestId('name').text()).toBe(harborTagsList[0].name); }); - describe(' clipboard button', () => { + describe('clipboard button', () => { it('exists', () => { expect(findClipboardButton().exists()).toBe(true); }); diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js index 93d013bb458..aca6b0942cc 100644 --- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js +++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js @@ -74,7 +74,7 @@ describe('Infrastructure Title', () => { mountComponent({ ...exampleProps, count }); }); - it(exist ? 'exists' : 'does not exist', () => { + it(`${exist ? 'exists' : 'does not exist'}`, () => { expect(findMetadataItem().exists()).toBe(exist); }); diff --git a/spec/frontend/releases/stores/modules/detail/getters_spec.js b/spec/frontend/releases/stores/modules/detail/getters_spec.js index 2e0f9eca285..f8b87ec71dc 100644 --- a/spec/frontend/releases/stores/modules/detail/getters_spec.js +++ b/spec/frontend/releases/stores/modules/detail/getters_spec.js @@ -317,7 +317,7 @@ describe('Release edit/new getters', () => { { milestones: ['release.milestone[0].title'] }, ], ])('releaseUpdateMutatationVariables', (description, state, expectedVariables) => { - it(description, () => { + it(`${description}`, () => { const expectedVariablesObject = { input: expect.objectContaining(expectedVariables) }; const actualVariables = getters.releaseUpdateMutatationVariables(state, { diff --git a/spec/frontend/security_configuration/components/app_spec.js b/spec/frontend/security_configuration/components/app_spec.js index 222cabc6a63..ddefda2ffc3 100644 --- a/spec/frontend/security_configuration/components/app_spec.js +++ b/spec/frontend/security_configuration/components/app_spec.js @@ -281,7 +281,7 @@ describe('App component', () => { }); }); - it(shouldRender ? 'renders' : 'does not render', () => { + it(`${shouldRender ? 'renders' : 'does not render'}`, () => { expect(findAutoDevopsEnabledAlert().exists()).toBe(shouldRender); }); }); diff --git a/spec/frontend/snippet/collapsible_input_spec.js b/spec/frontend/snippet/collapsible_input_spec.js index 56e64d136c2..4a6fd33b9e4 100644 --- a/spec/frontend/snippet/collapsible_input_spec.js +++ b/spec/frontend/snippet/collapsible_input_spec.js @@ -9,7 +9,7 @@ describe('~/snippet/collapsible_input', () => { beforeEach(() => { setHTMLFixture(` - <form> + <form> <div class="js-collapsible-input js-title"> <div class="js-collapsed d-none"> <input type="text" /> @@ -72,7 +72,7 @@ describe('~/snippet/collapsible_input', () => { ${'is collapsed'} | ${''} | ${true} ${'stays open if given value'} | ${'Hello world!'} | ${false} `('when loses focus', ({ desc, value, isCollapsed }) => { - it(desc, () => { + it(`${desc}`, () => { findExpandedInput(descriptionEl).value = value; focusIn(fooEl); diff --git a/spec/frontend/work_items/components/work_item_due_date_spec.js b/spec/frontend/work_items/components/work_item_due_date_spec.js index 1d76154a1f0..701406b9588 100644 --- a/spec/frontend/work_items/components/work_item_due_date_spec.js +++ b/spec/frontend/work_items/components/work_item_due_date_spec.js @@ -62,7 +62,7 @@ describe('WorkItemDueDate component', () => { createComponent({ canUpdate: true, startDate }); }); - it(exists ? 'renders' : 'does not render', () => { + it(`${exists ? 'renders' : 'does not render'}`, () => { expect(findStartDateButton().exists()).toBe(exists); }); }); @@ -172,7 +172,7 @@ describe('WorkItemDueDate component', () => { createComponent({ canUpdate: true, dueDate }); }); - it(exists ? 'renders' : 'does not render', () => { + it(`${exists ? 'renders' : 'does not render'}`, () => { expect(findDueDateButton().exists()).toBe(exists); }); }); diff --git a/spec/frontend_integration/diffs/diffs_interopability_spec.js b/spec/frontend_integration/diffs/diffs_interopability_spec.js index 8e9bc4f0a5f..5017fb8c49d 100644 --- a/spec/frontend_integration/diffs/diffs_interopability_spec.js +++ b/spec/frontend_integration/diffs/diffs_interopability_spec.js @@ -121,6 +121,7 @@ describe('diffs third party interoperability', () => { vm = startDiffsApp(); + // eslint-disable-next-line jest/no-standalone-expect await waitFor(() => expect(hasLines(rowSelector)).toBe(true)); }); diff --git a/spec/services/packages/rpm/parse_package_service_spec.rb b/spec/services/packages/rpm/parse_package_service_spec.rb new file mode 100644 index 00000000000..f330587bfa0 --- /dev/null +++ b/spec/services/packages/rpm/parse_package_service_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe Packages::Rpm::ParsePackageService do + let(:package_file) { File.open('spec/fixtures/packages/rpm/hello-0.0.1-1.fc29.x86_64.rpm') } + + describe 'dynamic private methods' do + described_class::BUILD_ATTRIBUTES_METHOD_NAMES.each do |attribute| + it 'define dynamic build attribute method' do + expect(described_class).to be_private_method_defined("build_#{attribute}") + end + end + end + + describe '#execute' do + subject { described_class.new(package_file).execute } + + shared_examples 'valid package parsing' do + it 'return hash' do + expect(subject).to be_a(Hash) + end + + it 'has all static attribute keys' do + expect(subject.keys).to include(*described_class::STATIC_ATTRIBUTES) + end + + it 'includes epoch attribute' do + expect(subject[:epoch]).not_to be_blank + end + + it 'has all built attributes with array values' do + result = subject + described_class::BUILD_ATTRIBUTES_METHOD_NAMES.each do |attribute| + expect(result).to have_key(attribute) + expect(result[attribute]).to be_a(Array) + end + end + end + + context 'when wrong format file received' do + let(:package_file) { File.open('spec/fixtures/rails_sample.jpg') } + + it 'raise error' do + expect { subject }.to raise_error(ArgumentError) + end + end + + context 'when valid file uploaded' do + context 'when .rpm file uploaded' do + it_behaves_like 'valid package parsing' + end + + context 'when .src.rpm file uploaded' do + let(:package_file) { File.open('spec/fixtures/packages/rpm/hello-0.0.1-1.fc29.src.rpm') } + + it_behaves_like 'valid package parsing' + end + end + end +end diff --git a/yarn.lock b/yarn.lock index a232bd48d15..1829f61185d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1037,10 +1037,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/at.js/-/at.js-1.5.7.tgz#1ee6f838cc4410a1d797770934df91d90df8179e" integrity sha512-c6ySRK/Ma7lxwpIVbSAF3P+xiTLrNTGTLRx4/pHK111AdFxwgUwrYF6aVZFXvmG65jHOJHoa0eQQ21RW6rm0Rg== -"@gitlab/eslint-plugin@17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-17.0.0.tgz#5451fbbad96b09d812af2afb247f6602fe0be6c6" - integrity sha512-c+sJtjzYl+KGPtZScU8Mji9seJw7dSEn31APyYEYTyWp72yMsFvXmg46txT2QCz+ueZlqk0/C2IQmgfe6fLcBw== +"@gitlab/eslint-plugin@18.1.0": + version "18.1.0" + resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-18.1.0.tgz#8300cc938f50114b3e74d97660721486c13caea5" + integrity sha512-O803ResZfPpbSk8USzYwT79OXKSyuR4z4qbjOae/NIhzobxrlEHm4LbauVuaFpHurF5gYceNtHltczwK8e+mOg== dependencies: "@babel/core" "^7.17.0" "@babel/eslint-parser" "^7.17.0" @@ -1049,8 +1049,8 @@ eslint-config-prettier "^6.10.0" eslint-plugin-babel "^5.3.0" eslint-plugin-import "^2.26.0" - eslint-plugin-jest "^23.8.2" - eslint-plugin-promise "^4.2.1" + eslint-plugin-jest "^27.0.4" + eslint-plugin-promise "^6.0.1" eslint-plugin-unicorn "^40.1.0" eslint-plugin-vue "^9.3.0" lodash "^4.17.21" @@ -2066,7 +2066,7 @@ jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" -"@types/json-schema@^7.0.0", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.0", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== @@ -2223,28 +2223,51 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/experimental-utils@^2.5.0": - version "2.30.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.30.0.tgz#9845e868c01f3aed66472c561d4b6bac44809dd0" - integrity sha512-L3/tS9t+hAHksy8xuorhOzhdefN0ERPDWmR9CclsIGOUqGKy6tqc/P+SoXeJRye5gazkuPO0cK9MQRnolykzkA== +"@typescript-eslint/scope-manager@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz#8f0927024b6b24e28671352c93b393a810ab4553" + integrity sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA== dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.30.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/visitor-keys" "5.38.0" -"@typescript-eslint/typescript-estree@2.30.0": - version "2.30.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.30.0.tgz#1b8e848b55144270255ffbfe4c63291f8f766615" - integrity sha512-nI5WOechrA0qAhnr+DzqwmqHsx7Ulr/+0H7bWCcClDhhWkSyZR5BmTvnBEyONwJCTWHfc5PAQExX24VD26IAVw== +"@typescript-eslint/types@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.0.tgz#8cd15825e4874354e31800dcac321d07548b8a5f" + integrity sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA== + +"@typescript-eslint/typescript-estree@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz#89f86b2279815c6fb7f57d68cf9b813f0dc25d98" + integrity sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg== dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^6.3.0" - tsutils "^3.17.1" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/visitor-keys" "5.38.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@^5.10.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.38.0.tgz#5b31f4896471818153790700eb02ac869a1543f4" + integrity sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.38.0" + "@typescript-eslint/types" "5.38.0" + "@typescript-eslint/typescript-estree" "5.38.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.38.0": + version "5.38.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz#60591ca3bf78aa12b25002c0993d067c00887e34" + integrity sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w== + dependencies: + "@typescript-eslint/types" "5.38.0" + eslint-visitor-keys "^3.3.0" "@vue/component-compiler-utils@^3.1.0": version "3.3.0" @@ -5358,12 +5381,12 @@ eslint-plugin-import@^2.26.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-plugin-jest@^23.8.2: - version "23.8.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz#6f28b41c67ef635f803ebd9e168f6b73858eb8d4" - integrity sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg== +eslint-plugin-jest@^27.0.4: + version "27.0.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.0.4.tgz#ab9c7b3f48bfade4762c24c415a5d9bbc0174a61" + integrity sha512-BuvY78pHMpMJ6Cio7sKg6jrqEcnRYPUc4Nlihku4vKx3FjlmMINSX4vcYokZIe+8TKcyr1aI5Kq7vYwgJNdQSA== dependencies: - "@typescript-eslint/experimental-utils" "^2.5.0" + "@typescript-eslint/utils" "^5.10.0" eslint-plugin-no-jquery@2.7.0: version "2.7.0" @@ -5375,10 +5398,10 @@ eslint-plugin-no-unsanitized@^4.0.1: resolved "https://registry.yarnpkg.com/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-4.0.1.tgz#e2343265467ba2270ade478cbe07bbafeaea412d" integrity sha512-y/lAMWnPPC7RYuUdxlEL/XiCL8FehN9h9s3Kjqbp/Kv0i9NZs+IXSC2kS546Fa4Bumwy31HlVS/OdWX0Kxb5Xg== -eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== +eslint-plugin-promise@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.0.1.tgz#a8cddf96a67c4059bdabf4d724a29572188ae423" + integrity sha512-uM4Tgo5u3UWQiroOyDEsYcVMOo7re3zmno0IZmB5auxoaQNIceAbXEkSt8RNrKtaYehARHG06pYK6K1JhtP0Zw== eslint-plugin-unicorn@^40.1.0: version "40.1.0" @@ -5426,7 +5449,7 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -5442,13 +5465,6 @@ eslint-scope@^7.1.1: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - eslint-utils@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" @@ -5456,11 +5472,6 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" @@ -11704,10 +11715,10 @@ tslib@^2, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.4.0, tslib@~2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" |