csvm: Add test cases and support for all variable expressions

This allows variables to contain any type of expansion, treating them
as (recursively) string replacements.

* csvm2csv: Add Copyright year.
  (expand_vars): New function.
  (parseline): Use it.  Expand before all other replacements so that
    variable expansions may support all types of expressions.  Expand
    variables in range expressions.
* test/test-csvm2csv: New file.
master
Mike Gerwitz 2018-10-01 16:07:34 -04:00
parent bd65f433d2
commit c741b4a84e
2 changed files with 230 additions and 10 deletions

View File

@ -2,7 +2,7 @@
#
# Compiles a "magic" CSV file into a normal CSV
#
# Copyright (C) 2016 R-T Specialty, LLC.
# Copyright (C) 2016, 2018 R-T Specialty, LLC.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -45,6 +45,20 @@
##
# Expand variable with its value, if any
function expand_vars( s )
{
# attempt to parse variable (may expand into a range)
if ( match( s, /^\$([a-zA-Z_-]+)$/, m ) )
{
return vars[ m[1] ];
}
return s
}
# Expand line
function parseline( i, m, j, me, orig )
{
if ( i > NF )
@ -55,6 +69,10 @@ function parseline( i, m, j, me, orig )
orig = $i
# expand variables before any processing so that expansions
# can include any type of formatting
$i = expand_vars( $i )
if ( match( $i, /^([0-9]+\/){2}[0-9]+$/, m ) )
{
cmd = "date --date=" $i " +%s"
@ -78,17 +96,12 @@ function parseline( i, m, j, me, orig )
return
}
# attempt to parse variable (may expand into a range)
if ( match( $i, /^\$([a-zA-Z_-]+)$/, m ) )
{
$i = vars[ m[1] ];
}
# parse range
if ( match( $i, /^([0-9]+)--([0-9]+)$/, m ) )
if ( match( $i, /^([^-]+)--([^-]+)$/, m ) )
{
j = m[1]
me = m[2]
j = expand_vars( m[1] )
me = expand_vars( m[2] )
do
{
$i = j

View File

@ -0,0 +1,207 @@
#!/bin/bash
# Test csvm2csv
#
# Copyright (C) 2018 R-T Specialty, LLC.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
##
cd "$( dirname "$0" )"
# just to ensure that we run all the tests
declare -i testsum=0
# Run test case with input and expected values
run-test()
{
local -r input="${1?Missing input}"
local -r expected="${2?Missing expected}"
((testsum++))
# SUT invocation
declare -r given=$( ../csvm2csv < <( cat <<< "$input" ) )
# expected output
diff <( cat <<< "$expected" ) <( cat <<< "$given" )
}
test-comment()
{
local -r input='# comment before header should be removed
header, line
# this is also a comment
1, 2
# which should be ignored
3, 4'
local -r expected='header,line
1,2
3,4'
run-test "$input" "$expected"
}
test-range()
{
declare -r input='header, line
1--3, 2
3--5, 4--6'
declare -r expected='header,line
1,2
2,2
3,2
3,4
3,5
3,6
4,4
4,5
4,6
5,4
5,5
5,6'
run-test "$input" "$expected"
}
test-delim()
{
declare -r input='header, line
1;4, 2
4;3, 6;9'
declare -r expected='header,line
1,2
4,2
4,6
4,9
3,6
3,9'
run-test "$input" "$expected"
}
test-var()
{
declare -r input='header, line
:foo=1
:bar_baz-quux=2
$foo,1
$bar_baz-quux,$foo'
declare -r expected='header,line
1,1
2,1'
run-test "$input" "$expected"
}
test-range-delim()
{
declare -r input='header, line
1--3;5--6, 2'
declare -r expected='header,line
1,2
2,2
3,2
5,2
6,2'
run-test "$input" "$expected"
}
test-var-in-range-delim()
{
declare -r input='header, line
:foo=1
:bar=3
$foo--$bar, $foo;$bar'
declare -r expected='header,line
1,1
1,3
2,1
2,3
3,1
3,3'
run-test "$input" "$expected"
}
test-var-with-range-delim()
{
declare -r input='header, line
:foo=1--2;4
:bar=5
$foo;$bar, 1'
declare -r expected='header,line
1,1
2,1
4,1
5,1'
run-test "$input" "$expected"
}
test-var-with-var()
{
declare -r input='header, line
:foo=2
:bar=4
:range=$foo--$bar
:baz=$range;$foo
$baz, 5'
declare -r expected='header,line
2,5
3,5
4,5
2,5'
run-test "$input" "$expected"
}
test-comment \
&& test-range \
&& test-delim \
&& test-var \
&& test-range-delim \
&& test-var-in-range-delim \
&& test-var-with-range-delim \
&& test-var-with-var \
|| {
echo 'csvm2csv test failed' >&2
exit 1
}
# safety check
test "$testsum" -eq 8 || {
echo 'error: did not run all csvm2csv tests!' >&2
exit 1
}