import { parseNum, parseWeight, truncateText, splitName } from '../shared/utils/parse'; // ------------------------------------------------------------------------- describe( 'parseNum', () => { // Positive it( 'parses a positive integer string', () => { expect( parseNum( '42' ) ).toBe( 42 ); } ); it( 'parses a float string', () => { expect( parseNum( '3.14' ) ).toBeCloseTo( 3.14 ); } ); it( 'returns the value when given a number directly', () => { expect( parseNum( 7 ) ).toBe( 7 ); } ); it( 'parses negative numbers', () => { expect( parseNum( '-5' ) ).toBe( -5 ); } ); it( 'parses zero', () => { expect( parseNum( 0 ) ).toBe( 0 ); } ); // Negative it( 'returns null for empty string', () => { expect( parseNum( '' ) ).toBeNull(); } ); it( 'returns null for null', () => { expect( parseNum( null ) ).toBeNull(); } ); it( 'returns null for undefined', () => { expect( parseNum( undefined ) ).toBeNull(); } ); it( 'returns null for a non-numeric string', () => { expect( parseNum( 'abc' ) ).toBeNull(); } ); it( 'returns null for Infinity', () => { expect( parseNum( Infinity ) ).toBeNull(); } ); it( 'returns null for NaN', () => { expect( parseNum( NaN ) ).toBeNull(); } ); } ); // ------------------------------------------------------------------------- describe( 'parseWeight', () => { // Positive it( 'parses a valid weight string', () => { expect( parseWeight( '1.5' ) ).toBe( 1.5 ); } ); it( 'parses a numeric weight', () => { expect( parseWeight( 2 ) ).toBe( 2 ); } ); // Negative it( 'returns 0 for null', () => { expect( parseWeight( null ) ).toBe( 0 ); } ); it( 'returns 0 for undefined', () => { expect( parseWeight( undefined ) ).toBe( 0 ); } ); it( 'returns 0 for non-numeric string', () => { expect( parseWeight( 'heavy' ) ).toBe( 0 ); } ); } ); // ------------------------------------------------------------------------- describe( 'truncateText', () => { // Positive it( 'returns text unchanged when shorter than maxLength', () => { expect( truncateText( 'Hello', 10 ) ).toBe( 'Hello' ); } ); it( 'returns text unchanged when exactly equal to maxLength', () => { expect( truncateText( 'Hello', 5 ) ).toBe( 'Hello' ); } ); // Negative it( 'truncates text longer than maxLength', () => { const result = truncateText( 'Hello World', 8 ); expect( result ).toHaveLength( 8 ); expect( result.endsWith( '…' ) ).toBe( true ); } ); it( 'truncates to 1 character plus ellipsis when maxLength is 2', () => { const result = truncateText( 'Hello', 2 ); expect( result ).toHaveLength( 2 ); expect( result ).toBe( 'H…' ); } ); } ); // ------------------------------------------------------------------------- describe( 'splitName', () => { // Positive it( 'splits "First Last" into forename and surname', () => { const result = splitName( 'John Smith' ); expect( result.forename ).toBe( 'John' ); expect( result.surname ).toBe( 'Smith' ); } ); it( 'uses first word as forename and ignores extra words for surname', () => { const result = splitName( 'John Paul Smith' ); expect( result.forename ).toBe( 'John' ); expect( result.surname ).toBe( 'Paul' ); } ); it( 'returns truncated values within 50 chars', () => { const long = 'A'.repeat( 60 ) + ' ' + 'B'.repeat( 60 ); const result = splitName( long ); expect( result.forename.length ).toBeLessThanOrEqual( 50 ); expect( result.surname.length ).toBeLessThanOrEqual( 50 ); } ); // Negative it( 'defaults to Woo/Shop for empty string', () => { const result = splitName( '' ); expect( result.forename ).toBe( 'Woo' ); expect( result.surname ).toBe( 'Shop' ); } ); it( 'uses single word as forename and defaults surname to Shop', () => { const result = splitName( 'Madonna' ); expect( result.forename ).toBe( 'Madonna' ); expect( result.surname ).toBe( 'Shop' ); } ); it( 'strips special characters before splitting', () => { const result = splitName( 'John@Smith' ); // @ stripped → "John Smith" treated as two parts expect( result.forename ).toBeDefined(); expect( result.surname ).toBeDefined(); } ); } );