Skip to content

Commit 3045954

Browse files
Fix: console errors in unix format (#96)
* fix: console errors in unix format * remove dupicate coments * fix: console errors in unix format * Fix: more error codes * Fix: more error codes * Fix: more error codes * Fix: more error codes * Fix: more error codes * version update
1 parent becb607 commit 3045954

File tree

3 files changed

+191
-8
lines changed

3 files changed

+191
-8
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-cron-generator",
3-
"version": "2.1.0",
3+
"version": "2.1.1",
44
"description": "A powerful React component for building cron expressions with support for both Unix (5 fields) and Quartz (7 fields) formats. Features validation, format conversion, TypeScript support, and accessibility.",
55
"keywords": [
66
"react",

src/lib/cron.test.tsx

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,179 @@ describe('Cron Component - Custom Headers', () => {
559559
expect(screen.getByText('Monthly')).toBeInTheDocument();
560560
expect(screen.getByText('Custom')).toBeInTheDocument();
561561
});
562+
});
563+
564+
describe('Unix Format Initialization with Values', () => {
565+
it('should initialize with Unix format value without console errors', () => {
566+
const onChange = vi.fn();
567+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
568+
const consoleWarn = vi.spyOn(console, 'warn').mockImplementation(() => {});
569+
570+
render(
571+
<Cron
572+
value="*/5 * * * *"
573+
onChange={onChange}
574+
showResultText={false}
575+
showResultCron={true}
576+
isUnix={true}
577+
/>,
578+
);
579+
580+
// Should display the Unix value
581+
expect(screen.getByText('*/5 * * * *')).toBeInTheDocument();
582+
583+
// Should not have any console errors
584+
expect(consoleError).not.toHaveBeenCalled();
585+
expect(consoleWarn).not.toHaveBeenCalled();
586+
587+
consoleError.mockRestore();
588+
consoleWarn.mockRestore();
589+
});
590+
591+
it('should initialize with hourly Unix format value', () => {
592+
const onChange = vi.fn();
593+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
594+
595+
render(
596+
<Cron
597+
value="0 * * * *"
598+
onChange={onChange}
599+
showResultText={false}
600+
showResultCron={true}
601+
isUnix={true}
602+
/>,
603+
);
604+
605+
expect(screen.getByText('0 * * * *')).toBeInTheDocument();
606+
expect(consoleError).not.toHaveBeenCalled();
607+
608+
consoleError.mockRestore();
609+
});
610+
611+
it('should initialize with daily Unix format value', () => {
612+
const onChange = vi.fn();
613+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
614+
615+
render(
616+
<Cron
617+
value="0 0 * * *"
618+
onChange={onChange}
619+
showResultText={false}
620+
showResultCron={true}
621+
isUnix={true}
622+
/>,
623+
);
624+
625+
expect(screen.getByText('0 0 * * *')).toBeInTheDocument();
626+
expect(consoleError).not.toHaveBeenCalled();
627+
628+
consoleError.mockRestore();
629+
});
630+
631+
it('should initialize with weekly Unix format value', () => {
632+
const onChange = vi.fn();
633+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
634+
635+
render(
636+
<Cron
637+
value="0 0 * * 1"
638+
onChange={onChange}
639+
showResultText={false}
640+
showResultCron={true}
641+
isUnix={true}
642+
/>,
643+
);
644+
645+
expect(screen.getByText('0 0 * * 1')).toBeInTheDocument();
646+
expect(consoleError).not.toHaveBeenCalled();
647+
648+
consoleError.mockRestore();
649+
});
650+
651+
it('should initialize with monthly Unix format value', () => {
652+
const onChange = vi.fn();
653+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
654+
655+
render(
656+
<Cron
657+
value="0 0 1 * *"
658+
onChange={onChange}
659+
showResultText={false}
660+
showResultCron={true}
661+
isUnix={true}
662+
/>,
663+
);
664+
665+
expect(screen.getByText('0 0 1 * *')).toBeInTheDocument();
666+
expect(consoleError).not.toHaveBeenCalled();
667+
668+
consoleError.mockRestore();
669+
});
670+
671+
it('should handle complex Unix cron expressions', () => {
672+
const onChange = vi.fn();
673+
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
674+
675+
render(
676+
<Cron
677+
value="*/15 2-5 * * 1-5"
678+
onChange={onChange}
679+
showResultText={false}
680+
showResultCron={true}
681+
isUnix={true}
682+
/>,
683+
);
684+
685+
expect(screen.getByText('*/15 2-5 * * 1-5')).toBeInTheDocument();
686+
expect(consoleError).not.toHaveBeenCalled();
687+
688+
consoleError.mockRestore();
689+
});
690+
691+
it('should convert Unix to Quartz internally and back to Unix for display', () => {
692+
const onChange = vi.fn();
693+
694+
render(
695+
<Cron
696+
value="*/5 * * * *"
697+
onChange={onChange}
698+
showResultText={true}
699+
showResultCron={true}
700+
isUnix={true}
701+
/>,
702+
);
703+
704+
// Should display Unix format
705+
expect(screen.getByText('*/5 * * * *')).toBeInTheDocument();
706+
// Should have human-readable text
707+
expect(screen.getByText(/every 5 minutes/i)).toBeInTheDocument();
708+
});
709+
710+
it('should handle onChange callback with Unix format', async () => {
711+
const onChange = vi.fn();
712+
const user = userEvent.setup();
713+
714+
render(
715+
<Cron
716+
value="*/5 * * * *"
717+
onChange={onChange}
718+
showResultText={false}
719+
showResultCron={true}
720+
isUnix={true}
721+
/>,
722+
);
723+
724+
// Switch to hourly tab
725+
const hourlyTab = screen.getByLabelText('Select Hourly tab');
726+
await user.click(hourlyTab);
727+
728+
await waitFor(() => {
729+
expect(onChange).toHaveBeenCalled();
730+
// Should call with Unix format (5 fields)
731+
const lastCall = onChange.mock.calls[onChange.mock.calls.length - 1];
732+
expect(lastCall[0].split(' ').length).toBe(5);
733+
});
734+
});
562735

563736
it('should work with custom headers and translations', () => {
564737
const onChange = vi.fn();

src/lib/cron.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,24 @@ const Cron: React.FunctionComponent<CronProp> = (props) => {
177177

178178
// Convert Unix to Quartz if needed for internal representation
179179
if (props.isUnix && value) {
180-
const parts = value.split(' ');
181-
if (parts.length === 5) {
180+
if (value.split(' ').length === 5) {
182181
try {
183182
processedValue = unixToQuartz(value);
184183
} catch (e) {
185-
console.error('Error converting Unix to Quartz:', e);
184+
console.error('Error: converting Unix to Quartz:', e);
186185
processedValue = defaultCron;
187186
}
188187
}
189188
}
189+
if (!props.isUnix && value && value.split(' ').length === 5) {
190+
try {
191+
console.error('Warning: Unix value found,Converting to Quartz');
192+
processedValue = unixToQuartz(value);
193+
} catch (e) {
194+
console.error('Error: converting Unix to Quartz:', e);
195+
processedValue = defaultCron;
196+
}
197+
}
190198

191199
let valueArray = processedValue.replace(/,/g, '!').split(' ');
192200

@@ -286,7 +294,8 @@ const Cron: React.FunctionComponent<CronProp> = (props) => {
286294
* Sync with external value prop
287295
*/
288296
useEffect(() => {
289-
const compareVal = convertToOutputFormat(stateRef.current.value);
297+
const hasValidState = stateRef.current.value && stateRef.current.value.length > 0;
298+
const compareVal = hasValidState ? convertToOutputFormat(stateRef.current.value) : '';
290299

291300
if (props.value !== compareVal) {
292301
setValue(props.value ? props.value : '');
@@ -297,9 +306,6 @@ const Cron: React.FunctionComponent<CronProp> = (props) => {
297306
}
298307
}, [props.value, props.translateFn, props.locale, setValue, convertToOutputFormat]);
299308

300-
/**
301-
* Handle isUnix prop changes - notify parent with converted format
302-
*/
303309
/**
304310
* Handle isUnix prop changes - notify parent with converted format
305311
*/
@@ -381,6 +387,10 @@ const Cron: React.FunctionComponent<CronProp> = (props) => {
381387
* Get display value for result cron (uses single source of truth)
382388
*/
383389
const displayCron = useMemo(() => {
390+
// Only convert if we have a valid state with actual values
391+
if (!state.value || state.value.length === 0) {
392+
return '';
393+
}
384394
return convertToOutputFormat(state.value, props.isUnix);
385395
}, [state.value, props.isUnix, convertToOutputFormat]);
386396

0 commit comments

Comments
 (0)