mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-31 02:44:50 +01:00 
			
		
		
		
	restore test
This commit is contained in:
		| @@ -1,9 +1,11 @@ | ||||
| import { mutateElement } from "./element/mutateElement"; | ||||
| import { ExcalidrawElement } from "./element/types"; | ||||
| import { | ||||
|   generateJitteredKeyBetween, | ||||
|   generateKeyBetween, | ||||
|   generateNKeysBetween, | ||||
|   generateNJitteredKeysBetween, | ||||
| } from "fractional-indexing-jittered"; | ||||
| import { ENV } from "./constants"; | ||||
|  | ||||
| type FractionalIndex = ExcalidrawElement["fractionalIndex"]; | ||||
|  | ||||
| @@ -83,11 +85,21 @@ export const fixFractionalIndices = ( | ||||
|         elements[movedIndices[movedIndices.length - 1] + 1]?.fractionalIndex || | ||||
|         null; | ||||
|  | ||||
|       const newKeys = generateNJitteredKeysBetween( | ||||
|         predecessor, | ||||
|         successor, | ||||
|         movedIndices.length, | ||||
|       ); | ||||
|       let newKeys = []; | ||||
|  | ||||
|       if (import.meta.env.MODE === ENV.TEST || import.meta.env.DEV) { | ||||
|         newKeys = generateNKeysBetween( | ||||
|           predecessor, | ||||
|           successor, | ||||
|           movedIndices.length, | ||||
|         ); | ||||
|       } else { | ||||
|         newKeys = generateNJitteredKeysBetween( | ||||
|           predecessor, | ||||
|           successor, | ||||
|           movedIndices.length, | ||||
|         ); | ||||
|       } | ||||
|  | ||||
|       for (let i = 0; i < movedIndices.length; i++) { | ||||
|         const element = elements[movedIndices[i]]; | ||||
| @@ -128,33 +140,24 @@ export const orderByFractionalIndex = (allElements: ExcalidrawElement[]) => { | ||||
| }; | ||||
|  | ||||
| const restoreFractionalIndex = ( | ||||
|   index: FractionalIndex, | ||||
|   predecessor: FractionalIndex, | ||||
|   successor: FractionalIndex, | ||||
| ) => { | ||||
|   if (index) { | ||||
|     if (!predecessor && !successor) { | ||||
|       return index; | ||||
|     } | ||||
|  | ||||
|     if (successor && !predecessor) { | ||||
|       // first element in the array | ||||
|       // insert before successor | ||||
|       return generateJitteredKeyBetween(null, successor); | ||||
|     } | ||||
|  | ||||
|     if (predecessor && !successor) { | ||||
|       // last element in the array | ||||
|       // insert after predecessor | ||||
|       return generateJitteredKeyBetween(predecessor, null); | ||||
|     } | ||||
|  | ||||
|     // both predecessor and successor exist | ||||
|     // insert after predecessor | ||||
|     return generateJitteredKeyBetween(predecessor, null); | ||||
|   if (successor && !predecessor) { | ||||
|     // first element in the array | ||||
|     // insert before successor | ||||
|     return generateKeyBetween(null, successor); | ||||
|   } | ||||
|  | ||||
|   return generateJitteredKeyBetween(null, null); | ||||
|   if (predecessor && !successor) { | ||||
|     // last element in the array | ||||
|     // insert after predecessor | ||||
|     return generateKeyBetween(predecessor, null); | ||||
|   } | ||||
|  | ||||
|   // both predecessor and successor exist (or both do not) | ||||
|   // insert after predecessor | ||||
|   return generateKeyBetween(predecessor, null); | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -169,13 +172,13 @@ const restoreFractionalIndex = ( | ||||
| export const restoreFractionalIndicies = ( | ||||
|   allElements: readonly ExcalidrawElement[], | ||||
| ) => { | ||||
|   let pre = -1; | ||||
|   let suc = 1; | ||||
|  | ||||
|   const normalized: ExcalidrawElement[] = []; | ||||
|  | ||||
|   for (const element of allElements) { | ||||
|     const predecessor = allElements[pre]?.fractionalIndex || null; | ||||
|     const predecessor = | ||||
|       normalized[normalized.length - 1]?.fractionalIndex || null; | ||||
|     const successor = allElements[suc]?.fractionalIndex || null; | ||||
|  | ||||
|     if ( | ||||
| @@ -183,7 +186,6 @@ export const restoreFractionalIndicies = ( | ||||
|     ) { | ||||
|       try { | ||||
|         const nextFractionalIndex = restoreFractionalIndex( | ||||
|           element.fractionalIndex, | ||||
|           predecessor, | ||||
|           successor, | ||||
|         ); | ||||
| @@ -198,7 +200,6 @@ export const restoreFractionalIndicies = ( | ||||
|     } else { | ||||
|       normalized.push(element); | ||||
|     } | ||||
|     pre++; | ||||
|     suc++; | ||||
|   } | ||||
|  | ||||
| @@ -212,24 +213,16 @@ export const validateFractionalIndicies = ( | ||||
|     const element = elements[i]; | ||||
|     const successor = elements[i + 1]; | ||||
|  | ||||
|     if (successor) { | ||||
|       if (element.fractionalIndex && successor.fractionalIndex) { | ||||
|         if (element.fractionalIndex >= successor.fractionalIndex) { | ||||
|           console.log( | ||||
|             "this is the case", | ||||
|             element.fractionalIndex, | ||||
|             successor.fractionalIndex, | ||||
|           ); | ||||
|           return false; | ||||
|         } | ||||
|       } else { | ||||
|         console.log( | ||||
|           "this is the other case", | ||||
|           element.fractionalIndex, | ||||
|           successor.fractionalIndex, | ||||
|         ); | ||||
|     if (element.fractionalIndex) { | ||||
|       if ( | ||||
|         successor && | ||||
|         successor.fractionalIndex && | ||||
|         element.fractionalIndex >= successor.fractionalIndex | ||||
|       ) { | ||||
|         return false; | ||||
|       } | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
							
								
								
									
										96
									
								
								src/tests/fractionalIndex.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/tests/fractionalIndex.test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| import { nanoid } from "nanoid"; | ||||
| import { | ||||
|   restoreFractionalIndicies, | ||||
|   validateFractionalIndicies, | ||||
| } from "../fractionalIndex"; | ||||
| import { ExcalidrawElement } from "../element/types"; | ||||
| import { API } from "./helpers/api"; | ||||
|  | ||||
| const createElementWithIndex = ( | ||||
|   fractionalIndex: string | null = null, | ||||
| ): ExcalidrawElement => { | ||||
|   return API.createElement({ | ||||
|     type: "rectangle", | ||||
|     fractionalIndex, | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| describe("restoring fractional indicies", () => { | ||||
|   it("restore all null fractional indices", () => { | ||||
|     const randomNumOfElements = Math.floor(Math.random() * 100); | ||||
|  | ||||
|     const elements: ExcalidrawElement[] = []; | ||||
|  | ||||
|     let i = 0; | ||||
|  | ||||
|     while (i < randomNumOfElements) { | ||||
|       elements.push(createElementWithIndex()); | ||||
|       i++; | ||||
|     } | ||||
|  | ||||
|     const restoredElements = restoreFractionalIndicies(elements); | ||||
|  | ||||
|     // length is not changed | ||||
|     expect(restoredElements.length).toBe(randomNumOfElements); | ||||
|     // order is not changed | ||||
|     expect(restoredElements.map((e) => e.id)).deep.equal( | ||||
|       elements.map((e) => e.id), | ||||
|     ); | ||||
|     // fractional indices are valid | ||||
|     expect(validateFractionalIndicies(restoredElements)).toBe(true); | ||||
|   }); | ||||
|  | ||||
|   it("restore out of order fractional indices", () => { | ||||
|     const elements = [ | ||||
|       createElementWithIndex("a0"), | ||||
|       createElementWithIndex("c0"), | ||||
|       createElementWithIndex("b0"), | ||||
|       createElementWithIndex("d0"), | ||||
|     ]; | ||||
|  | ||||
|     const restoredElements = restoreFractionalIndicies(elements); | ||||
|  | ||||
|     // length is not changed | ||||
|     expect(restoredElements.length).toBe(4); | ||||
|     // order is not changed | ||||
|     expect(restoredElements.map((e) => e.id)).deep.equal( | ||||
|       elements.map((e) => e.id), | ||||
|     ); | ||||
|     // fractional indices are valid | ||||
|     expect(validateFractionalIndicies(restoredElements)).toBe(true); | ||||
|     // should only fix the second element's fractional index | ||||
|     expect(elements[1].fractionalIndex).not.toEqual( | ||||
|       restoredElements[1].fractionalIndex, | ||||
|     ); | ||||
|     expect(elements.filter((value, index) => index !== 1)).deep.equal( | ||||
|       restoredElements.filter((value, index) => index !== 1), | ||||
|     ); | ||||
|   }); | ||||
|  | ||||
|   it("restore same fractional indices", () => { | ||||
|     const randomNumOfElements = Math.floor(Math.random() * 100); | ||||
|  | ||||
|     const elements: ExcalidrawElement[] = []; | ||||
|  | ||||
|     let i = 0; | ||||
|  | ||||
|     while (i < randomNumOfElements) { | ||||
|       elements.push(createElementWithIndex("a0")); | ||||
|       i++; | ||||
|     } | ||||
|  | ||||
|     const restoredElements = restoreFractionalIndicies(elements); | ||||
|  | ||||
|     // length is not changed | ||||
|     expect(restoredElements.length).toBe(randomNumOfElements); | ||||
|     // order is not changed | ||||
|     expect(restoredElements.map((e) => e.id)).deep.equal( | ||||
|       elements.map((e) => e.id), | ||||
|     ); | ||||
|     // should've restored fractional indices properly | ||||
|     expect(validateFractionalIndicies(restoredElements)).toBe(true); | ||||
|     expect(new Set(restoredElements.map((e) => e.fractionalIndex)).size).toBe( | ||||
|       randomNumOfElements, | ||||
|     ); | ||||
|   }); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user
	 Ryan Di
					Ryan Di