dev: errors: improve error test generation
This commit is contained in:
		
							parent
							
								
									32c7f6300b
								
							
						
					
					
						commit
						fc1621e647
					
				| @ -1,51 +1,28 @@ | ||||
| HLEDGER ?= hledger | ||||
| 
 | ||||
| ERRORSCRIPTS=*.j *.timeclock # *.timedot *.csv | ||||
| 
 | ||||
| # Check error messages of hledger in $PATH against current error tests.
 | ||||
| test: | ||||
| 	@printf "Running error message tests with hledger $$($(HLEDGER) --version | awk '{print $$2}'):\n" | ||||
| 	shelltest -w $(HLEDGER) *.test | ||||
| 
 | ||||
| TESTJOURNALS=*.j | ||||
| 
 | ||||
| # Update error message tests and readme based on the latest test journals
 | ||||
| # and error output of hledger in $PATH.
 | ||||
| update: tests readme | ||||
| 
 | ||||
| tests: | ||||
| 	@printf "Updating *.test with the error messages of hledger $$(hledger --version | awk '{print $$2}')\n" | ||||
| 	@printf "(Re)generating *.test with the error messages of hledger $$($(HLEDGER) --version | awk '{print $$2}')\n" | ||||
| 	@read -p "ok ? Press enter: " | ||||
| 	for f in $(TESTJOURNALS); do make -s $$(basename $$f .j).test; done | ||||
| 	@printf "\nNow please edit *.test and limit regexps to 300 chars to avoid shelltestrunner limitation\n\n" | ||||
| 	@for f in $(ERRORSCRIPTS); do echo "HLEDGER=$(HLEDGER) ./hledger2shelltest $$f"; HLEDGER=$(HLEDGER) ./hledger2shelltest $$f; done | ||||
| 
 | ||||
| # Generate a shelltest. Run the test script/journal to generate the error message.
 | ||||
| # Since the error will contain an absolute file path, we must:
 | ||||
| # 1. remove most of the file path
 | ||||
| # 2. test with a (multiline) regex rather than literal text
 | ||||
| # 3. backslash-quote most forward slashes in error messages
 | ||||
| # 4. neutralise any remaining problematic error text (eg in parseable-regexps.test)
 | ||||
| %.test: %.j | ||||
| 	head -1 $< | sed -E 's%#!/usr/bin/env -S (.*)%$$$$$$ \1 $<%' >$@ | ||||
| 	printf ">>>2 /" >>$@ | ||||
| 	-./$< 2>&1 | sed -E \
 | ||||
| 		-e 's%(hledger: Error: ).*/\./(.*)%\1.*\2%' \
 | ||||
| 		-e 's%/%\\/%g' \
 | ||||
| 		-e 's/\^/\\^/g' \
 | ||||
| 		-e 's/\$$/\\$$/g' \
 | ||||
| 		-e 's/\(/\\(/g' \
 | ||||
| 		-e 's/\)/\\)/g' \
 | ||||
| 		-e 's/\|/\\|/g' \
 | ||||
| 		>>$@ | ||||
| 	printf "/\n>>>= 1" >>$@ | ||||
| #		-e 's%alias \\/\(\\/%alias \\/\\(\\/%' \
 | ||||
| #		-e 's%compiled: \(%compiled: \\(%' \
 | ||||
| 
 | ||||
| readme: $(TESTJOURNALS) | ||||
| 	@printf "Updating README.md with the error messages of hledger $$(hledger --version | awk '{print $$2}')\n" | ||||
| readme: $(ERRORSCRIPTS) | ||||
| 	@printf "Updating README.md with the error messages of hledger $$($(HLEDGER) --version)\n" | ||||
| 	@read -p "ok ? Press enter: " | ||||
| 	sed '/<!-- GENERATED: -->/q' <README.md >README.md.tmp | ||||
| 	echo "$$(hledger --version | cut -d, -f1) error messages:" >>README.md.tmp | ||||
| 	for f in $(TESTJOURNALS); do \
 | ||||
| 		printf '\n### %s\n```\n%s\n```\n\n' "$$(basename "$$f" .j)" "$$(./"$$f" 2>&1)"; \
 | ||||
| 	echo "$$($(HLEDGER) --version | cut -d, -f1) error messages:" >>README.md.tmp | ||||
| 	for f in $(ERRORSCRIPTS); do \
 | ||||
| 		printf '\n### %s\n```\n%s\n```\n\n' "$$(echo "$$f" | sed -E 's/\.[^.]+$$//')" "$$(./"$$f" 2>&1)"; \
 | ||||
| 	done >>README.md.tmp | ||||
| 	mv README.md.tmp README.md | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										42
									
								
								hledger/test/errors/hledger2shelltest
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								hledger/test/errors/hledger2shelltest
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #!/usr/bin/env bash | ||||
| # hledger2shelltest SCRIPT | ||||
| # | ||||
| # Speaking generally: given an executable hashbang script (beginning with #!/usr/bin/env), | ||||
| # this generates a similarly-named shelltestrunner test that will repeatably | ||||
| # run the same command as the script and test its (stderr) output. | ||||
| # (Ideally, this would be built in to shelltestrunner.) | ||||
| # More precisely, this generates a test expecting no stdout, the given stderr, | ||||
| # and an error exit code, for scripts reproducing various hledger errors. | ||||
| # | ||||
| # The script is run once to capture its output, which is then adjusted | ||||
| # for use in a shelltest regex matcher: | ||||
| # - common regex metacharacters are escaped | ||||
| # - file paths are simplified | ||||
| # - any remaining problematic text is sanitised | ||||
| # - the regex is trimmed to <= 300 chars, to avoid a shelltestrunner limitation. | ||||
| 
 | ||||
| SCRIPT="$1" | ||||
| TEST=$(echo "$SCRIPT" | sed -E 's/\.[^.]+$//').test | ||||
| 
 | ||||
| { | ||||
| head -1 "$SCRIPT" | sed -E "s%#!/usr/bin/env -S (.*)%\$\$\$ \1 $SCRIPT%" | ||||
| printf ">>>2 /" | ||||
| "./$SCRIPT" 2>&1 | sed -E \ | ||||
|   -e 's%(hledger: Error: ).*/\./(.*)%\1.*\2%' \ | ||||
|   -e 's%/%\\/%g' \ | ||||
|   -e 's/\^/\\^/g' \ | ||||
|   -e 's/\$/\\$/g' \ | ||||
|   -e 's/\(/\\(/g' \ | ||||
|   -e 's/\)/\\)/g' \ | ||||
|   -e 's/\|/\\|/g' \ | ||||
|   | head -c 300 | ||||
| printf "/\n>>>= 1\n" | ||||
| } >"$TEST" | ||||
| 
 | ||||
| 
 | ||||
| #  -e 's%alias \\/\(\\/%alias \\/\\(\\/%' \ | ||||
| #  -e 's%compiled: \(%compiled: \\(%' \ | ||||
| 
 | ||||
| # gnused() {  # GNU sed, called gsed on mac | ||||
| #     if hash gsed 2>/dev/null; then gsed "$@"; else sed "$@"; fi | ||||
| # } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user