Skip to content

Commit

Permalink
Merge 99da1ae into a11c9d5
Browse files Browse the repository at this point in the history
  • Loading branch information
voisinhugo authored Feb 29, 2024
2 parents a11c9d5 + 99da1ae commit c32598b
Show file tree
Hide file tree
Showing 32 changed files with 324 additions and 174 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports = {
'local-rules/todo-format': ['error'],
'local-rules/use-the-right-test-utils': ['error'],
'local-rules/no-use-of-algolia-multiple-queries': ['error'],
'local-rules/toSorted-instead-of-sort': ['warn'],
'@typescript-eslint/ban-ts-comment': [
'error',
{
Expand Down
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
framework: '@storybook/react',
webpackFinal: async (config) => {
config.resolve.alias['react-query'] = require.resolve('./mocks/react-query.js')
config.optimization.minimize = false
return config
},
}
6 changes: 3 additions & 3 deletions doc/development/how-to/eslint-custom-rule.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Mode opératoire

En cas de doute, la règle [use-the-right-test-utils](../eslint-custom-rules/use-the-right-test-utils.js) est bon exemple de règle ESLint custom.
En cas de doute, la règle [use-the-right-test-utils](../../../eslint-custom-rules/use-the-right-test-utils.js) est bon exemple de règle ESLint custom.

### 1. Vérifier qu'il n'y a pas une règle existante

Expand All @@ -14,9 +14,9 @@ Sinon, continuer ce mode opératoire.

- Créer un fichier JS dans `/eslint-custom-rules` et utiliser le snippet `eslint-rule` pour générer une règle vide.

- Dans [eslint-local-rules.js](../eslint-local-rules.js), importer sa règle du fichier créé, et l'exporter.
- Dans [eslint-local-rules.js](../../../eslint-local-rules.js), importer sa règle du fichier créé, et l'exporter.

- Dans [.eslintrc.js](../.eslintrc.js), ajouter dans `rules` : `'local-rules/<ma-règle-ESLint>': ['error'],`
- Dans [.eslintrc.js](../../../.eslintrc.js), ajouter dans `rules` : `'local-rules/<ma-règle-ESLint>': ['error'],`

- Créer un fichier de test dans `/eslint-custom-rules/__tests__` : `<ma-règle-ESLint>.test.js`, et utiliser le snippet `eslint-test` pour générer des tests à remplir.

Expand Down
41 changes: 41 additions & 0 deletions eslint-custom-rules/__tests__/toSorted-instead-of-sort.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { RuleTester } from 'eslint'
import { config } from './config'

import rule from '../toSorted-instead-of-sort'

const ruleTester = new RuleTester()

const tests = {
valid: [{ code: 'array.toSorted()' }, { code: 'sortArray.toSorted()' }],
invalid: [
{
code: 'array.sort()',
errors: [
{
suggestions: [
{
output: 'array.toSorted()',
},
],
},
],
},
{
code: 'sortArray.sort()',
errors: [
{
suggestions: [
{
output: 'sortArray.toSorted()',
},
],
},
],
},
],
}

tests.valid.forEach((t) => Object.assign(t, config))
tests.invalid.forEach((t) => Object.assign(t, config))

ruleTester.run('toSorted-instead-of-sort', rule, tests)
34 changes: 34 additions & 0 deletions eslint-custom-rules/toSorted-instead-of-sort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = {
name: 'toSorted-instead-of-sort',
meta: {
type: 'suggestion',
docs: {
description: 'A rule to use .toSorted instead of .sort',
},
fixable: 'code',
hasSuggestions: true,
},
create(context) {
return {
"MemberExpression[property.name='sort']": (node) => {
context.report({
node,
message:
'Avoid .sort(), prefer .toSorted() that creates a copy instead of altering the array. See documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted).',
suggest: [
{
desc: 'use .toSorted()',
fix(fixer) {
const nodeSrc = context.getSourceCode().getText(node)

const fixedSrc = nodeSrc.replace(/sort$/, 'toSorted')

return fixer.replaceText(node, fixedSrc)
},
},
],
})
},
}
},
}
2 changes: 2 additions & 0 deletions eslint-local-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const useTheRightTestUtils = require('./eslint-custom-rules/use-the-right-test-u
const noUseOfAlgoliaMultipleQueries = require('./eslint-custom-rules/no-use-of-algolia-multiple-queries')
const noHardcodeIdInSvg = require('./eslint-custom-rules/no-hardcoded-id-in-svg')
const noTruthyCheckAfterQueryAllMatchers = require('./eslint-custom-rules/no-truthy-check-after-queryAll-matchers')
const toSortedInsteadOfSort = require('./eslint-custom-rules/toSorted-instead-of-sort.js')

module.exports = {
'independent-mocks': independentMocks,
Expand All @@ -20,4 +21,5 @@ module.exports = {
'use-the-right-test-utils': useTheRightTestUtils,
'no-use-of-algolia-multiple-queries': noUseOfAlgoliaMultipleQueries,
'no-truthy-check-after-queryAll-matchers': noTruthyCheckAfterQueryAllMatchers,
'toSorted-instead-of-sort': toSortedInsteadOfSort,
}
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'core-js/es/array/to-sorted'
import { AppRegistry } from 'react-native'

import { name as appName } from './app.json'
Expand Down
3 changes: 3 additions & 0 deletions metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ module.exports = {
transform: {
experimentalImportSupport: false,
inlineRequires: true,
// Fix for core-js cyclic dependency that lead to require stack exceeded error
// https://github.com/facebook/hermes/issues/135#issuecomment-808817771
nonInlinedRequires: ['../internals/inspect-source'],
},
}),
},
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"chromatic": "^6.19.8",
"color-alpha": "^1.1.3",
"contentful-resolve-response": "^1.3.0",
"core-js": "^3.36.0",
"date-fns": "^2.29.1",
"date-fns-tz": "^2.0.0",
"firebase": "^9.6.11",
Expand Down Expand Up @@ -236,7 +237,7 @@
"@types/jest-axe": "^3.5.5",
"@types/lodash": "^4.14.182",
"@types/mailparser": "^3.4.0",
"@types/node": "18",
"@types/node": "20.10.0",
"@types/react": "18.2.21",
"@types/react-dom": "^18.0.0",
"@types/react-helmet": "^6.1.2",
Expand All @@ -249,8 +250,8 @@
"@types/uuid": "^8.3.0",
"@types/webpack": "^4.41.32",
"@types/webpack-dev-server": "^3.11.3",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"@vue/preload-webpack-plugin": "^2.0.0",
"@welldone-software/why-did-you-render": "^7.0.1",
"appcenter-cli": "^2.14.0",
Expand All @@ -273,7 +274,7 @@
"deepmerge": "^4.2.2",
"dotenv": "^8.2.0",
"dotenv-expand": "^5.1.0",
"eslint": "^8.48.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.22.1",
Expand Down Expand Up @@ -338,7 +339,7 @@
"ts-jest": "^29.1.1",
"ts-node": "^10.8.0",
"ts-prune": "^0.10.3",
"typescript": "4.8.4",
"typescript": "5.3.3",
"url-loader": "^4.1.1",
"webpack": "^4.44.2",
"webpack-bundle-analyzer": "^4.5.0",
Expand Down Expand Up @@ -378,7 +379,8 @@
"react-side-effect": "2.1.2",
"react-is": "^16.13.1",
"@sentry/core": "7.62.0",
"@babel/runtime": "^7.23"
"@babel/runtime": "^7.23",
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.f9c48c0.0"
},
"exports": {
".": "./index.js",
Expand Down
9 changes: 4 additions & 5 deletions src/features/bookOffer/components/BookHourChoice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,15 @@ function getHourChoiceForSingleStock(
offerCredit: number
) {
return stocks
.filter(({ beginningDatetime }) => {
.filter((stock): stock is OfferStockResponse & { beginningDatetime: string } => {
const { beginningDatetime } = stock
if (beginningDatetime === undefined || beginningDatetime === null) return false
return selectedDate && beginningDatetime
? formatToKeyDate(beginningDatetime) === selectedDate
: false
})
.sort(
(a, b) =>
//@ts-expect-error : stocks with no beginningDatetime was filtered
new Date(a.beginningDatetime).getTime() - new Date(b.beginningDatetime).getTime()
.toSorted(
(a, b) => new Date(a.beginningDatetime).getTime() - new Date(b.beginningDatetime).getTime()
)
.map((stock, index) => (
<HourChoice
Expand Down
2 changes: 1 addition & 1 deletion src/features/bookOffer/components/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const getMinAvailableDate = (markedDates: MarkedDates): string | undefine
if (availableDates.length === 0) return undefined
if (availableDates.length === 1) return availableDates[0]

return [...availableDates].sort(
return availableDates.toSorted(
(dateA, dateB) => new Date(dateA).valueOf() - new Date(dateB).valueOf()
)[0]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function getSortedHoursFromDate(stocks: OfferStockResponse[], selectedDat
.filter(getStockWithCategoryFromDate(selectedDate))
.map((stock) => stock.beginningDatetime)
.filter(filterBool)
.sort(sortByDateStringPredicate)
.toSorted(sortByDateStringPredicate)
}

export function getDistinctPricesFromAllStock(stocks: OfferStockResponse[]) {
Expand All @@ -141,7 +141,7 @@ const sortByPricePredicate = (a: OfferStockResponse, b: OfferStockResponse) => {
}

export function getStockSortedByPriceFromHour(stocks: OfferStockResponse[], selectedHour: string) {
return stocks.filter(getStockWithCategoryFromHour(selectedHour)).sort(sortByPricePredicate)
return stocks.filter(getStockWithCategoryFromHour(selectedHour)).toSorted(sortByPricePredicate)
}

export function getStockWithCategory(
Expand Down
6 changes: 3 additions & 3 deletions src/features/favorites/components/FavoritesResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ function applySortBy(list: Array<FavoriteResponse>, sortBy: FavoriteSortBy, posi
// fix concurrency sentry/issues/288586
return []
} else if (sortBy === 'ASCENDING_PRICE') {
list.sort(sortByAscendingPrice)
list.toSorted(sortByAscendingPrice)
return list
} else if (sortBy === 'AROUND_ME') {
list.sort(sortByDistanceAroundMe(position))
list.toSorted(sortByDistanceAroundMe(position))
return list
} else if (sortBy === 'RECENTLY_ADDED') {
list.sort(sortByIdDesc)
list.toSorted(sortByIdDesc)
return list
} else {
return list
Expand Down
18 changes: 6 additions & 12 deletions src/features/favorites/helpers/sorts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ describe('Favorites sorts', () => {
{ ...baseOffer, id: 3 },
{ ...baseOffer, id: 2 },
]
data.sort(sortByIdDesc)

expect(data.map(({ id }) => id)).toEqual([3, 2, 1])
expect(data.toSorted(sortByIdDesc).map(({ id }) => id)).toEqual([3, 2, 1])
})

it('should sort by ASCENDING_PRICE', () => {
Expand All @@ -29,9 +28,8 @@ describe('Favorites sorts', () => {
{ ...baseOffer, id: 4, offer: { ...baseOffer.offer, price: 0 } },
{ ...baseOffer, id: 2, offer: { ...baseOffer.offer, price: 20 } },
]
data.sort(sortByAscendingPrice)

expect(data.map(({ id }) => id)).toEqual([4, 1, 2, 3])
expect(data.toSorted(sortByAscendingPrice).map(({ id }) => id)).toEqual([4, 1, 2, 3])
})

it('should sort by ASCENDING_PRICE and place expired offer last', () => {
Expand All @@ -41,9 +39,8 @@ describe('Favorites sorts', () => {
{ ...baseOffer, id: 4, offer: { ...baseOffer.offer, price: 0 } },
{ ...baseOffer, id: 2, offer: { ...baseOffer.offer, price: 20, isExpired: true } },
]
data.sort(sortByAscendingPrice)

expect(data.map(({ id }) => id)).toEqual([4, 1, 3, 2])
expect(data.toSorted(sortByAscendingPrice).map(({ id }) => id)).toEqual([4, 1, 3, 2])
})

it('should sort by ASCENDING_PRICE and place offer with no price last', () => {
Expand All @@ -53,9 +50,8 @@ describe('Favorites sorts', () => {
{ ...baseOffer, id: 4, offer: { ...baseOffer.offer, price: 0 } },
{ ...baseOffer, id: 2, offer: { ...baseOffer.offer, price: null } },
]
data.sort(sortByAscendingPrice)

expect(data.map(({ id }) => id)).toEqual([4, 1, 3, 2])
expect(data.toSorted(sortByAscendingPrice).map(({ id }) => id)).toEqual([4, 1, 3, 2])
})

it('should sort by AROUND_ME', () => {
Expand All @@ -64,9 +60,8 @@ describe('Favorites sorts', () => {
{ ...baseOffer, id: 3, offer: { ...baseOffer.offer, coordinates: position3 } },
{ ...baseOffer, id: 2, offer: { ...baseOffer.offer, coordinates: position2 } },
]
data.sort(sortByDistanceAroundMe(position))

expect(data.map(({ id }) => id)).toEqual([1, 2, 3])
expect(data.toSorted(sortByDistanceAroundMe(position)).map(({ id }) => id)).toEqual([1, 2, 3])
})

it('should sort by AROUND_ME and place offer with no coordinates last', () => {
Expand All @@ -75,8 +70,7 @@ describe('Favorites sorts', () => {
{ ...baseOffer, id: 3, offer: { ...baseOffer.offer, coordinates: position3 } },
{ ...baseOffer, id: 2 },
]
data.sort(sortByDistanceAroundMe(position))

expect(data.map(({ id }) => id)).toEqual([1, 3, 2])
expect(data.toSorted(sortByDistanceAroundMe(position)).map(({ id }) => id)).toEqual([1, 3, 2])
})
})
2 changes: 1 addition & 1 deletion src/features/home/helpers/selectHomepageEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useSelectHomepageEntry = (
const scoredEntries = homepageList
.map((homepageEntry) => scoreHomepageByTags(homepageEntry, user))
.filter(({ score }) => score > 0)
.sort((a, b) => b.score - a.score)
.toSorted((a, b) => b.score - a.score)

const defaultHomepageEntry = scoredEntries.length
? omit(scoredEntries[0], 'score')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const IconsContainer: ComponentStory<
}>
> = ({ title, icons, isBicolor = false }) => {
const sortedIcons = useMemo(() => {
return Object.entries(icons).sort(([iconName1], [iconName2]) => {
return Object.entries(icons).toSorted(([iconName1], [iconName2]) => {
if (iconName1 < iconName2) return -1
else if (iconName1 > iconName2) return 1
else return 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const OfferNativeCategoryChoices = (props: Props) => {
categories.forEach((categoryEnum) => {
nativeCategories = [...nativeCategories, ...getNativeCategories(data, categoryEnum)]
})
return nativeCategories.sort((a, b) => (a?.value ?? '').localeCompare(b?.value ?? ''))
return nativeCategories.toSorted((a, b) => (a?.value ?? '').localeCompare(b?.value ?? ''))
}, [data, categories])

const onPress = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe('TabBar', () => {
'Mes réservations',
'Mes favoris',
'Mon profil',
].sort()
].toSorted()

expectedTabsTestIds.forEach((tab) => {
expect(screen.getByTestId(tab)).toBeOnTheScreen()
Expand All @@ -131,7 +131,7 @@ describe('TabBar', () => {
'Mes réservations sélectionné',
'Mes favoris',
'Mon profil',
].sort()
].toSorted()

expectedTabsTestIds.forEach((tab) => {
expect(screen.getByTestId(tab)).toBeOnTheScreen()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const getContentFromOffer = (
if (photoCredit && photoCredit !== 'undefined')
hits.push({ key: 'photoCredit', value: photoCredit })

return hits.sort(sortExtraData)
return hits.toSorted(sortExtraData)
}

const renderExtraData = ({ item }: { item: Item }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('categoriesHelpers', () => {
it('should sort categories by alphabetical order', () => {
const categories = mockData.searchGroups
.filter((category) => category.name !== SearchGroupNameEnumv2.NONE)
.sort(searchGroupOrNativeCategorySortComparator)
.toSorted(searchGroupOrNativeCategorySortComparator)

expect(categories).toEqual([
{
Expand Down
Loading

0 comments on commit c32598b

Please sign in to comment.