<commit_before>#! test/for/moderni/sh
# See the file LICENSE in the main modernish directory for the licence.

# Regression tests related to (built-in) utilities of the shell.

doTest1() {
	title="options to 'command' can be expansions"
	v='-v'
	command $v : >/dev/null 2>&1
	case $? in
	( 0 )	mustNotHave BUG_CMDOPTEXP ;;
	# test suite runs with PATH=/dev/null, so we can rely on 127 = not found
	( 127 )	mustHave BUG_CMDOPTEXP ;;
	( * )	return 1 ;;
	esac
}

doTest2() {
	title="'command -v -p' searches default PATH"
	command -v -p chmod >/dev/null 2>&1 \
	&& command -v -p : >/dev/null 2>&1
	e=$?
	case $e in
	( 0 )	mustNotHave BUG_CMDPV ;;
	( 1 | 127 )
		if ( eval '[[ ${.sh.version} == Version\ *\ 201?-??-?? ]]' ) 2>/dev/null; then
			xfailmsg='ksh intermittent -p bug'
			# ref.: https://github.com/att/ast/issues/426
			return 2
		fi
		mustHave BUG_CMDPV ;;
	( * )	failmsg="e = $e"
		return 1 ;;
	esac
}

doTest3() {
	title="'command' prevents exit on 'set' error"
	v=$(command set +o bad@option 2>/dev/null; putln ok)
	case $v in
	( ok )	mustNotHave BUG_CMDSPEXIT ;;
	( '' )	mustHave BUG_CMDSPEXIT ;;
	( * )	return 1 ;;
	esac
}

doTest4() {
	title="'command -v' finds reserved words"
	v=$(command -v until)
	case $v in
	( until )
		mustNotHave BUG_CMDVRESV ;;
	( '' )	mustHave BUG_CMDVRESV ;;
	( * )	return 1 ;;
	esac
}

doTest5() {
	title="'break' works from within 'eval'"
	(
		for v in 0 1 2; do
			eval 'break' 2>/dev/null
			exit 13
		done
		exit 42
	)
	case $? in
	( 42 )	mustNotHave BUG_EVALCOBR ;;
	( * )	mustHave BUG_EVALCOBR ;;
	esac
}

doTest6() {
	title="'continue' works from within 'eval'"
	(
		for v in 1 2 42; do
			eval 'continue' 2>/dev/null
			break
		done
		exit $v
	)
	case $? in
	( 42 )	mustNotHave BUG_EVALCOBR ;;
	( * )	mustHave BUG_EVALCOBR ;;
	esac
}

doTest7() {
	title="\$LINENO works from within 'eval'"
	v=$LINENO; eval "${CCn}x=\$LINENO${CCn}y=\$LINENO${CCn}z=\$LINENO${CCn}"
	if let "y == x + 1 && z == y + 1"; then
		mustNotHave BUG_LNNOEVAL
	elif let "x == v && y == v && z == v"; then
		mustNotHave BUG_LNNOEVAL && okmsg='no increment'
	elif let "x == 0 && y == 0 && z == 0"; then
		mustHave BUG_LNNOEVAL
	else
		failmsg="x==$x; y==$y; z==$z"
		return 1
	fi
}

doTest8() {
	title="\$LINENO works within alias expansion"
	alias _util_test8="${CCn}x=\$LINENO${CCn}y=\$LINENO${CCn}z=\$LINENO${CCn}"
	# use 'eval' to force immediate alias expansion in function definition
	eval 'testFn() {
		_util_test8
	}'
	testFn
	unalias _util_test8
	unset -f testFn
	if let "y == x + 1 && z == y + 1"; then
		mustNotHave BUG_LNNOALIAS
	elif let "x == 0 && y == 0 && z == 0"; then
		mustHave BUG_LNNOALIAS
	elif let "y == x && z == y"; then
		mustNotHave BUG_LNNOALIAS && okmsg='no increment'
	else
		failmsg="x==$x; y==$y; z==$z"
		return 1
	fi
}

lastTest=8<commit_msg>add regression test for correct BUG_NOEXPRO detection<commit_after>#! test/for/moderni/sh
# See the file LICENSE in the main modernish directory for the licence.

# Regression tests related to (built-in) utilities of the shell.

doTest1() {
	title="options to 'command' can be expansions"
	v='-v'
	command $v : >/dev/null 2>&1
	case $? in
	( 0 )	mustNotHave BUG_CMDOPTEXP ;;
	# test suite runs with PATH=/dev/null, so we can rely on 127 = not found
	( 127 )	mustHave BUG_CMDOPTEXP ;;
	( * )	return 1 ;;
	esac
}

doTest2() {
	title="'command -v -p' searches default PATH"
	command -v -p chmod >/dev/null 2>&1 \
	&& command -v -p : >/dev/null 2>&1
	e=$?
	case $e in
	( 0 )	mustNotHave BUG_CMDPV ;;
	( 1 | 127 )
		if ( eval '[[ ${.sh.version} == Version\ *\ 201?-??-?? ]]' ) 2>/dev/null; then
			xfailmsg='ksh intermittent -p bug'
			# ref.: https://github.com/att/ast/issues/426
			return 2
		fi
		mustHave BUG_CMDPV ;;
	( * )	failmsg="e = $e"
		return 1 ;;
	esac
}

doTest3() {
	title="'command' prevents exit on 'set' error"
	v=$(command set +o bad@option 2>/dev/null; putln ok)
	case $v in
	( ok )	mustNotHave BUG_CMDSPEXIT ;;
	( '' )	mustHave BUG_CMDSPEXIT ;;
	( * )	return 1 ;;
	esac
}

doTest4() {
	title="'command -v' finds reserved words"
	v=$(command -v until)
	case $v in
	( until )
		mustNotHave BUG_CMDVRESV ;;
	( '' )	mustHave BUG_CMDVRESV ;;
	( * )	return 1 ;;
	esac
}

doTest5() {
	title="'break' works from within 'eval'"
	(
		for v in 0 1 2; do
			eval 'break' 2>/dev/null
			exit 13
		done
		exit 42
	)
	case $? in
	( 42 )	mustNotHave BUG_EVALCOBR ;;
	( * )	mustHave BUG_EVALCOBR ;;
	esac
}

doTest6() {
	title="'continue' works from within 'eval'"
	(
		for v in 1 2 42; do
			eval 'continue' 2>/dev/null
			break
		done
		exit $v
	)
	case $? in
	( 42 )	mustNotHave BUG_EVALCOBR ;;
	( * )	mustHave BUG_EVALCOBR ;;
	esac
}

doTest7() {
	title="\$LINENO works from within 'eval'"
	v=$LINENO; eval "${CCn}x=\$LINENO${CCn}y=\$LINENO${CCn}z=\$LINENO${CCn}"
	if let "y == x + 1 && z == y + 1"; then
		mustNotHave BUG_LNNOEVAL
	elif let "x == v && y == v && z == v"; then
		mustNotHave BUG_LNNOEVAL && okmsg='no increment'
	elif let "x == 0 && y == 0 && z == 0"; then
		mustHave BUG_LNNOEVAL
	else
		failmsg="x==$x; y==$y; z==$z"
		return 1
	fi
}

doTest8() {
	title="\$LINENO works within alias expansion"
	alias _util_test8="${CCn}x=\$LINENO${CCn}y=\$LINENO${CCn}z=\$LINENO${CCn}"
	# use 'eval' to force immediate alias expansion in function definition
	eval 'testFn() {
		_util_test8
	}'
	testFn
	unalias _util_test8
	unset -f testFn
	if let "y == x + 1 && z == y + 1"; then
		mustNotHave BUG_LNNOALIAS
	elif let "x == 0 && y == 0 && z == 0"; then
		mustHave BUG_LNNOALIAS
	elif let "y == x && z == y"; then
		mustNotHave BUG_LNNOALIAS && okmsg='no increment'
	else
		failmsg="x==$x; y==$y; z==$z"
		return 1
	fi
}

doTest9() {
	title="'export' can export readonly variables"
	v=$(
		msh_util_test9=ok
		readonly msh_util_test9
		export msh_util_test9 2>/dev/null
		$MSH_SHELL -c 'echo "$msh_util_test9"' 2>&1
	)
	case $v in
	( ok )	mustNotHave BUG_NOEXPRO ;;
	( '' )	mustHave BUG_NOEXPRO ;;
	( * )	return 1 ;;
	esac
}

lastTest=9
{'fraction_non_alphanumeric': 0.1653198653198653, 'fraction_numerical': 0.025757575757575757, 'mean_word_length': 3.305072463768116, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3285283', 'n_tokens_mistral': 2788, 'n_tokens_neox': 2513, 'n_words': 694}