Compare commits

..

No commits in common. "master" and "v1.0.0" have entirely different histories.

24 changed files with 179 additions and 3982 deletions

View file

@ -1 +0,0 @@
2.5b

22
LICENSE
View file

@ -1,22 +0,0 @@
MIT License
Copyright (c) 2020 Brandon Rozek
Copyright (c) 2019 Sławomir Śledź
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

294
README.md
View file

@ -1,293 +1 @@
# Introduction # bash-fun
This is a fork of [ssledz's fun.sh library](https://github.com/ssledz/bash-fun).
This is mainly for my own personal use cases. So I would recommend using ssledz's version instead.
I mainly worked towards getting this library to mostly pass shellcheck, removed some functionality,
and name deconflicted some of the functions with what I had in my system.
# Quick start
```bash
#!/bin/bash
. <(test -e fun.sh || curl -Ls https://raw.githubusercontent.com/brandon-rozek/bash-fun/master/src/fun.sh > fun.sh; cat fun.sh)
seq 1 4 | sum
```
# Functions overview
|||||||
|------|------|------|------|------|------|
|**list_append**|**divide**|**take_while**|
|**list_drop**|**drop_while**|**factorial**|**filter**|**foldl**|
|**isint**|**isempty**|**isfile**|**isnonzerofile**|**isreadable**|**iswritable**|
|**isdir**|**list_join**|**lambda**|**list_last**|**list_head**|**list**|
|**list_tail**|**list_zip**|**list_map**|
|**mod**|**multiply**|**not**|
|**add**|**list_prepend**|**product**|**ret**|
|**revers**|**revers_str**|**scanl**|**splitc**|**strip**|
|**stripl**|**stripr**|**subtract**|**sum**|**take**|
|**tup**|**unlist**|**λ**|
## *list/unlist*
```bash
$ list 1 2 3
1
2
3
$ list 1 2 3 4 5 | unlist
1 2 3 4 5
```
## *list_take/list_drop/list_tail/list_head/list_last*
```bash
$ list 1 2 3 4 | list_drop 2
3
4
$ list 1 2 3 4 5 | list_head
1
$ list 1 2 3 4 | list_tail
2
3
4
$ list 1 2 3 4 5 | list_last
5
$ list 1 2 3 4 5 | list_take 2
1
2
```
## *join*
```bash
$ list 1 2 3 4 5 | list_join ,
1,2,3,4,5
```
## *map*
```bash
$ seq 1 5 | list_map λ a . 'echo $((a + 5))'
6
7
8
9
10
$ list a b s d e | list_map λ a . 'echo $a$(echo $a | tr a-z A-Z)'
aA
bB
sS
dD
eE
$ list 1 2 3 | list_map tee
1
2
3
```
## *filter*
```bash
$ seq 1 10 | filter even
2
4
6
8
10
```
## *foldl/foldr*
```bash
$ list a b c d | foldl λ acc el . 'echo -n $acc-$el'
a-b-c-d
```
```bash
$ seq 1 4 | foldl λ acc el . 'echo $(($acc + $el))'
10
```
```bash
$ seq 1 4 | foldl λ acc el . 'echo $(multiply $(($acc + 1)) $el)'
64 # 1 + (1 + 1) * 2 + (4 + 1) * 3 + (15 + 1) * 4 = 64
```
## *tup/tupx/tupl/tupr*
```bash
$ tup a 1
(a,1)
$ tup 'foo bar' 1 'one' 2
(foo bar,1,one,2)
$ tup , 1 3
(,,1,3)
```
```bash
$ echo tup a 1 | tupl
a
$ echo tup a 1 | tupr
1
$ tup 'foo bar' 1 'one' 2 | tupl
foo bar
$ tup 'foo bar' 1 'one' 2 | tupr
2
```
## *list_zip*
```bash
$ list a b c d e f | list_zip $(seq 1 10)
(a,1)
(b,2)
(c,3)
(d,4)
(e,5)
(f,6)
```
```bash
$ list a b c d e f | list_zip $(seq 1 10) | list_last | tupr
6
```
## *not/isint/isempty*
```bash
$ isint 42
true
$ list blah | isint
false
$ not true
false
$ not "isint 777"
false
$ list 1 2 "" c d 6 | filter λ a . 'isint $a'
1
2
6
$ list 1 2 "" c d 6 | filter λ a . 'not "isempty $a"'
1
2
c
d
6
```
## *isfile/isnonzerofile/isreadable/iswritable/isdir*
```bash
$ touch /tmp/foo
$ isfile /tmp/foo
true
$ not iswritable /
true
$ files="/etc/passwd /etc/sudoers /tmp /tmp/foo /no_such_file"
$ list $files | filter λ a . 'isfile $a'
/etc/passwd
/etc/sudoers
/tmp/foo
$ list $files | filter λ a . 'isdir $a'
/tmp
$ list $files | filter λ a . 'isreadable $a'
/etc/passwd
/tmp
/tmp/foo
$ list $files | filter λ a . 'iswritable $a'
/tmp
/tmp/foo
$ list $files | filter λ a . 'isnonzerofile $a'
/etc/passwd
/etc/sudoers
/tmp
$ list $files | filter λ a . 'not isfile $a'
/tmp
/no_such_file
```
## *scanl*
```bash
$ seq 1 5 | scanl lambda acc el . 'echo $(($acc + $el))'
1
3
6
10
15
```
```bash
$ seq 1 5 | scanl lambda a b . 'echo $(($a + $b))' | list_last
15
```
# Examples
```bash
processNames() {
uppercase() {
local str=$1
echo $(tr 'a-z' 'A-Z' <<< ${str:0:1})${str:1}
}
list $@ \
| filter λ name . '[[ ${#name} -gt 1 ]] && ret true || ret false' \
| list_map λ name . 'uppercase $name' \
| foldl λ acc el . 'echo $acc,$el'
}
processNames adam monika s slawek d daniel Bartek j k
```
```bash
Adam,Monika,Slawek,Daniel,Bartek
```
# Running tests
TODO: Need to change the tests here
```bash
cd test
./test_runner
```
# Contribution guidelines
Feel free to ask questions in chat, open issues, or contribute by creating pull requests.
In order to create a pull request
* checkout master branch
* introduce your changes & bump version
* submit pull request
# Resources
* [Inspiration](https://quasimal.com/posts/2012-05-21-funsh.html)
* [Functional Programming in Bash](https://medium.com/@joydeepubuntu/functional-programming-in-bash-145b6db336b7)

View file

@ -1,29 +1,30 @@
#!/bin/bash #!/bin/bash
source ../src/fun.sh source ../src/fun.sh
seq 1 4 | sum seq 1 4 | sum
seq 1 4 | product seq 1 4 | product
factorial 4 factorial 4
seq 1 4 | scanl lambda a b . 'echo $(add $a $b)' seq 1 4 | scanl lambda a b . 'echo $(add $a $b)'
echo map multiply echo map mul
seq 1 4 | list_map lambda a . 'echo $(multiply $a 2)' seq 1 4 | map lambda a . 'echo $(mul $a 2)'
echo map minus echo map sub
seq 1 4 | list_map lambda a . 'echo $(minus $a 2)' seq 1 4 | map lambda a . 'echo $(sub $a 2)'
echo map add echo map add
seq 1 4 | list_map lambda a . 'echo $(add $a 2)' seq 1 4 | map lambda a . 'echo $(add $a 2)'
echo map divide echo map div
seq 1 4 | list_map lambda a . 'echo $(divide $a 2)' seq 1 4 | map lambda a . 'echo $(div $a 2)'
echo list_map mod echo map mod
seq 1 4 | list_map lambda a . 'echo $(mod $a 2)' seq 1 4 | map lambda a . 'echo $(mod $a 2)'
echo 'list & head' echo 'list & head'
list 1 2 3 4 5 | list_head list 1 2 3 4 5 | head
list {1..2} | list_append {3..4} | list_prepend {99..102} list {1..2} | append {3..4} | prepend {99..102}
list {1..2} | unlist list {1..2} | unlist
list {1..10} | list_head list {1..10} | head
list {1..10} | list_drop 7 list {1..10} | drop 7
list {1..10} | list_take 3 list {1..10} | take 3
list {1..10} | list_last list {1..10} | last
list {1..10} | list_map λ a . 'echo $(multiply $a 2)' list {1..10} | map λ a . 'echo $(mul $a 2)'
id() { id() {
λ x . '$x' λ x . '$x'
@ -38,31 +39,11 @@ foobar() {
list {1,2,3} | foobar list {1,2,3} | foobar
echo -n abcdefg | revers_str # gfedcba echo -n abcdefg | revers_str # gfedcba
echo -n abcdefg | splitc | list_join , # a,b,c,d,e,f,g echo -n abcdefg | splitc | join , '[' ']' # [a,b,c,d,e,f,g]
echo -n abcdefg | splitc | revers | list_join , # g,f,e,d,c,b,a echo -n abcdefg | splitc | revers | join , '[' ']' # [g,f,e,d,c,b,a]
list {1..10} | filter lambda a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false' | list_join , # 2,4,6,8,10 echo -n ' abcdefg' | splitc | foldr lambda a b . 'echo $a$b' # gfedcba
list a b c d | foldl lambda acc el . 'echo -n $acc-$el' echo 'ls' | try λ cmd status ret . 'echo $cmd [$status]; echo $ret'
seq 1 4 | foldl lambda acc el . 'echo $(($acc + $el))'
#1 - 2 - 3 - 4 list {1..10} | filter lambda a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false' | join , '[' ']' # [2,4,6,8,10]
seq 1 4 | foldl lambda acc el . 'echo $(($acc - $el))'
#1 + (1 + 1) * 2 + (4 + 1) * 3 + (15 + 1) * 4 = 64
seq 1 4 | foldl lambda acc el . 'echo $(multiply $(($acc + 1)) $el)'
tup a 1
tup a 1 | tupl
tup a 1 | tupr
list a b c d e f | list_zip $(seq 1 10)
echo
list a b c d e f | list_zip $(seq 1 10) | list_last | tupr
seq 1 5 | scanl lambda a b . 'echo $(($a + $b))'
seq 1 5 | scanl lambda a b . 'echo $(($a + $b))' | list_last
seq 2 3 | list_map lambda a . 'seq 1 $a' | list_join ,
list a b c | list_map lambda a . 'echo $a; echo $a | tr a-z A-z' | list_join ,

575
src/fun.sh Normal file → Executable file
View file

@ -1,8 +1,25 @@
#!/bin/sh #!/bin/bash
drop() {
command tail -n +$(($1 + 1))
}
take() {
command head -n ${1}
}
tail() {
drop 1
}
head() {
take 1
}
last() {
command tail -n 1
}
###############################################
## List Functions
###############################################
list() { list() {
for i in "$@"; do for i in "$@"; do
echo "$i" echo "$i"
@ -10,63 +27,28 @@ list() {
} }
unlist() { unlist() {
xargs cat - | xargs
} }
# Drop the first n items of a list. append() {
list_drop() {
command tail -n +$(($1 + 1))
}
# Take the first n items of a list.
list_take() {
command head -n "$1"
}
# Take the 'tail' of a list.
# Otherwise known as dropping the first element.
list_tail() {
list_drop 1
}
# Take only the first element of the list.
list_head() {
list_take 1
}
# Take the last element of the list.
list_last() {
command tail -n 1
}
# Add the contents of standard input
# to the end of the list.
list_append() {
cat - cat -
list "$@" list "$@"
} }
# Add the contents of standard input prepend() {
# to the beginning of the list.
list_prepend() {
list "$@" list "$@"
cat - cat -
} }
###############################################
## Lambdas and Lists
###############################################
# Defines an anonymous function.
lambda() { lambda() {
# shellcheck disable=2039
local expression
lam() { lam() {
# shellcheck disable=2039
local arg local arg
while [ $# -gt 0 ]; do while [[ $# -gt 0 ]]; do
arg="$1" arg="$1"
shift shift
if [ "$arg" = '.' ]; then if [[ $arg = '.' ]]; then
echo "$@" echo "$@"
return return
else else
@ -75,479 +57,180 @@ lambda() {
done done
} }
expression=$(lam "$@") eval $(lam "$@")
eval "$expression"
} }
# Same as lambda.
# shellcheck disable=2039
λ() { λ() {
lambda "$@" lambda "$@"
} }
# Print the number of arguments a lambda takes. map() {
# shellcheck disable=2039
λ_num_args() {
# Calculates the number of arguments a lambda takes
minus "$#" 3
}
# Perform an operation to each
# element(s) of a list provided
# through standard input.
list_map() {
# shellcheck disable=2039
local x local x
# shellcheck disable=2039 while read x; do
local i
# shellcheck disable=2039
local arguments
# shellcheck disable=2039
local num_args
if [ "$1" = "λ" ] || [ "$1" = "lambda" ]; then
num_args=$(λ_num_args "$@")
while read -r x; do
arguments="$x"
i=2
while [ $i -le "$num_args" ] ; do
read -r x
arguments="$arguments $x"
i=$(add $i 1)
done
# We want to word split arguments, so no quotes
eval "list $arguments" | "$@"
done
else # Do not know the arity, assume 1
while read -r x; do
echo "$x" | "$@" echo "$x" | "$@"
done done
fi
} }
# Perform a binary operation on a list
# where one element is the accumulation
# of the results so far.
# Ex: seq 3 | foldl lambda a b . 'minus $a $b'
# First is (1 - 2 = -1) then (-1 - 3 = -4).
foldl() { foldl() {
# shellcheck disable=2039 local f="$@"
local acc local acc
read -r acc read acc
while read -r elem; do while read elem; do
acc=$({ echo "$acc"; echo "$elem"; } | "$@" ) acc="$({ echo $acc; echo $elem; } | $f )"
done done
echo "$acc" echo "$acc"
} }
# Constructs a list where each element foldr() {
# is the foldl of the 0th-ith elements of local f="$@"
# the list. local acc
read acc
foldrr() {
local elem
read elem && acc=$(foldrr)
acc="$({ echo $acc; echo $elem; } | $f )"
echo "$acc"
}
foldrr
}
scanl() { scanl() {
# shellcheck disable=2039 local f="$@"
local acc local acc
read -r acc read acc
echo "$acc" echo $acc
while read -r elem; do while read elem; do
acc=$({ echo "$acc"; echo "$elem"; } | "$@" ) acc="$({ echo $acc; echo $elem; } | $f )"
echo "$acc" echo "$acc"
done done
} }
# Drops any elements of the list where the mul() {
# function performed on it evaluates to false. ( set -f; echo $(($1 * $2)) )
filter() {
# shellcheck disable=2039
local x
while read -r x; do
ret=$(echo "$x" | "$@")
if_then "$ret" "echo $x"
done
}
# Keep taking elements until a certain condition
# is false.
take_while() {
# shellcheck disable=2039
local x
# shellcheck disable=2039
local condition
while read -r x; do
condition="$(echo "$x" | "$@")"
if_then_else "$condition" "echo $x" "break"
done
}
# Keep dropping elements until a certain condition
# is false.
drop_while() {
# shellcheck disable=2039
local x
while read -r x; do
condition="$(echo "$x" | "$@")"
if_then_else "$condition" 'do_nothing' 'break'
done
if_then "[ -n $x ]" "{ echo $x; cat -; }"
}
###############################################
## Arithmetic Functions
###############################################
multiply() {
# shellcheck disable=2039
local a
# shellcheck disable=2039
local b
a=$1
if [ $# -lt 2 ] ; then
read -r b
else
b=$2
fi
isint "$a" > /dev/null && \
isint "$b" > /dev/null && \
echo $((a * b))
} }
add() { add() {
# shellcheck disable=2039 echo $(($1 + $2))
local a
# shellcheck disable=2039
local b
a=$1
if [ $# -lt 2 ] ; then
read -r b
else
b=$2
fi
isint "$a" > /dev/null && \
isint "$b" > /dev/null && \
echo $((a + b))
} }
minus() { sub() {
# shellcheck disable=2039 echo $(($1 - $2))
local a
# shellcheck disable=2039
local b
a=$1
if [ $# -lt 2 ] ; then
b=$1
read -r a
else
b=$2
fi
isint "$a" > /dev/null && \
isint "$b" > /dev/null && \
echo $((a - b))
} }
divide() { div() {
# shellcheck disable=2039 echo $(($1 / $2))
local a
# shellcheck disable=2039
local b
a=$1
if [ $# -lt 2 ] ; then
b=$1
read -r a
else
b=$2
fi
isint "$a" > /dev/null && \
isint "$b" > /dev/null && \
echo $((a / b))
} }
mod() { mod() {
# shellcheck disable=2039 echo $(($1 % $2))
local a
# shellcheck disable=2039
local b
a=$1
if [ $# -lt 2 ] ; then
b=$1
read -r a
else
b=$2
fi
isint "$a" > /dev/null && \
isint "$b" > /dev/null && \
echo $((a % b))
} }
even() {
# shellcheck disable=2039
local n
# shellcheck disable=2039
local result
# shellcheck disable=2039
local result_code
if [ $# -lt 1 ] ; then
read -r n
else
n=$1
fi
result=$(mod "$n" 2)
result_code=$?
if [ $result_code -ne 0 ] ; then
ret false
else
result_to_bool "[ $result = 0 ]"
fi
}
odd() {
not even
}
less_than() {
# shellcheck disable=2039
local n
read -r n
if isint "$n" > /dev/null && \
[ "$n" -lt "$1" ] ; then
ret true
else
ret false
fi
}
sum() { sum() {
foldl lambda a b . "add \$a \$b" foldl lambda a b . 'echo $(($a + $b))'
} }
product() { product() {
foldl lambda a b . "multiply \$a \$b" foldl lambda a b . 'echo $(mul $a $b)'
} }
factorial() { factorial() {
seq 1 "$1" | product seq 1 $1 | product
} }
###############################################
## String Operations
###############################################
# Splits a string into a list where each element
# is one character.
splitc() { splitc() {
sed 's/./\n&/g' | list_tail cat - | sed 's/./&\n/g'
} }
# Takes a list and creates a string where join() {
# each element is seperated by a delimiter. local delim=$1
list_join() { local pref=$2
# shellcheck disable=2039 local suff=$3
local delim echo $pref$(cat - | foldl lambda a b . 'echo $a$delim$b')$suff
delim=$1
foldl lambda a b . "echo \$a$delim\$b"
} }
# Split a string into a list
# by a specified delimeter
str_split() {
sed "s/$1/\n/g"
}
# Reverses a list.
revers() { revers() {
# shellcheck disable=2039 foldl lambda a b . 'append $b $a'
local result
# shellcheck disable=2039
local n
while read -r n; do
result="$n\n$result"
done
echo "$result"
} }
# Reverses a string
revers_str() { revers_str() {
splitc | revers | list_join cat - | splitc | revers | join
} }
# Removes multiple occurences of try() {
# a single character from the beginning local f="$@"
# of the list. local cmd=$(cat -)
lstrip() { ret="$(2>&1 $cmd)"
# shellcheck disable=2039 local status=$?
local c list "$cmd" $status $(list $ret | join \#) | $f
if [ $# -eq 0 ] ; then
c=" "
else
c="$1"
fi
sed "s/^$c*//g"
}
# Removes multiple occurences of
# a single character from the end
# of the list.
rstrip() {
# shellcheck disable=2039
local c
if [ $# -eq 0 ] ; then
c=" "
else
c="$1"
fi
sed "s/$c*$//g"
}
# Removes multiple occurences of
# a single character from the beginning
# and end of the list.
strip() {
lstrip "$@" | rstrip "$@"
}
###############################################
## Tuple Functions
###############################################
# Creates a tuple, which is a string with
# multiple elements seperated by a comma,
# and it begins with a ( and ends with a ).
tup() {
# shellcheck disable=2039
local args
# shellcheck disable=2039
local result
if [ $# -eq 0 ]; then
args=$(unlist)
eval "tup $args"
else
result=$(list "$@" | list_join ,)
echo "($result)"
fi
}
# Takes a tuple and outputs it as a list
tup_to_list() {
local li
local f
local la
li=$(str_split ",")
# Remove '(' from the first element
f=$(echo "$li" | list_head)
f=$(echo "$f" | sed 's/^(//')
la=$(echo "$li" | list_last)
# If there is only one element in the list
# Remove ')' from the only element
if [ "$(echo "$la" | cut -c1)" = "(" ]; then
f=$(echo "$f" | sed "s/)$//")
echo "$f"
# If there is more than one element in the list
# Remove ')' from the last element
else
la=$(echo "$la" | sed "s/)$//")
# Remove the first and last element from li
li=$(echo "$li" | list_tail | sed '$d')
# Print the list
{ echo "$f"; echo "$li"; echo "$la"; }
fi
}
# Takes the first element of the tuple
tupl() {
tup_to_list | list_head
}
# Takes the last element of the tuple
tupr() {
tup_to_list | list_last
}
# Takes each element from a list in standard
# input and matches it with a list provided
# as the argument to this function.
# The result is a list of 2-tuples.
list_zip() {
# shellcheck disable=2039
local l
l=$(list "$@")
while read -r x; do
y=$(echo "$l" | list_take 1)
tup "$x" "$y"
l=$(echo "$l" | list_drop 1)
done
}
###############################################
## Logic Based Functions
###############################################
if_then() {
# shellcheck disable=2039
local result
eval "$1"
result=$?
if [ $result -eq 0 ] ; then
eval "$2"
fi
}
if_then_else() {
# shellcheck disable=2039
local result
eval "$1"
result=$?
if [ $result -eq 0 ] ; then
eval "$2"
else
eval "$3"
fi
}
result_to_bool() {
if_then_else "$1" 'ret true' 'ret false'
}
not() {
if_then_else "$1 > /dev/null" "ret false" "ret true"
} }
ret() { ret() {
echo "$@" echo $1
"$@"
} }
do_nothing() { filter() {
echo > /dev/null local x
while read x; do
ret=$(echo "$x" | "$@")
$ret && echo $x
done
} }
strip() {
############################################### local arg=$1
## Useful utility functions cat - | map lambda l . 'ret ${l##'$arg'}' | map lambda l . 'ret ${l%%'$arg'}'
###############################################
isint() {
result_to_bool "echo \"$1\" | grep -Eq '^-?[0-9]+$'"
} }
isempty() { buff() {
result_to_bool "[ -z \"$1\" ]" local cnt=-1
for x in $@; do
[[ $x = '.' ]] && break
cnt=$(add $cnt 1)
done
local args=''
local i=$cnt
while read arg; do
[[ $i -eq 0 ]] && list $args | "$@" && i=$cnt && args=''
args="$args $arg"
i=$(sub $i 1)
done
[[ ! -z $args ]] && list $args | "$@"
} }
isfile() { tup() {
result_to_bool "[ -f \"$1\" ]" list "$@" | join , '(' ')'
} }
isnonzerofile() { tupx() {
result_to_bool "[ -s \"$1\" ]" if [[ $# -eq 1 ]]; then
local arg
read arg
tupx "$1" "$arg"
else
local n=$1
shift
list "$@" | strip '\(' | strip '\)' | unlist | cut -d',' -f${n}
fi
} }
isreadable() { tupl() {
result_to_bool "[ -r \"$1\" ]" tupx 1 "$@"
} }
iswritable() { tupr() {
result_to_bool "[ -w \"$1\" ]" tupx 2 "$@"
} }
isdir() { zip() {
result_to_bool "[ -d \"$1\" ]" local list=$*
cat - | while read x; do
y=$(list $list | take 1)
tup $x $y
list=$(list $list | drop 1)
done
} }

View file

@ -1,15 +0,0 @@
#! /bin/bash
testAppendToEmptyList() {
assertEquals 4 "$(list | list_append 4)"
}
testAppendToOneElementList() {
assertEquals "1 4" "$(list 1 | list_append 4 | unlist)"
}
testAppendToList() {
assertEquals "1 2 3 4 5 4" "$(list 1 2 3 4 5 | list_append 4 | unlist)"
}
. ./shunit2-init.sh

View file

@ -1,23 +0,0 @@
#! /bin/bash
testDrop9From10() {
assertEquals 10 $(list {1..10} | list_drop 9)
}
testDrop8From10() {
assertEquals "9 10" "$(list {1..10} | list_drop 8 | unlist)"
}
testDropAll() {
assertEquals "" "$(list {1..10} | list_drop 10)"
}
testDropMoreThanAvailable() {
assertEquals "" "$(list {1..10} | list_drop 15)"
}
testDropZero() {
assertEquals "1 2 3 4 5 6 7 8 9 10" "$(list {1..10} | list_drop 0 | unlist)"
}
. ./shunit2-init.sh

View file

@ -1,16 +0,0 @@
#! /bin/bash
testLHeadFromList() {
assertEquals 1 $(list {1..10} | list_head)
assertEquals 5 $(list 5 6 7 | list_head)
}
testLHeadFromOneElementList() {
assertEquals 1 $(list 1 | list_head)
}
testLHeadFromEmptyList() {
assertEquals "" "$(list | list_head)"
}
. ./shunit2-init.sh

View file

@ -1,38 +0,0 @@
#! /bin/bash
testLambdaNoArguments_ifNoInput() {
assertEquals 'Hi there' "$(echo | lambda . 'echo Hi there')"
}
testLambdaNoArguments_ifSomeInputArguments() {
assertEquals 'Hi there' "$(echo 'xx\nyy\nzz' | lambda . 'echo Hi there')"
}
testLambdaOneArgument() {
identity() {
lambda x . '$x'
}
assertEquals "hi there !" "$(identity <<< 'echo hi there !')"
assertEquals 3 $(lambda x . 'echo $(($x + 1))' <<< '2')
assertEquals "hi there !" "$(λ x . 'echo $x' <<< 'hi there !')"
}
testLambdaSymbolTwoArguments() {
assertEquals 3 $(echo -e '1\n2' | lambda x y . 'echo $(($x + $y))')
assertEquals 5 $(echo -e '7\n2' | λ x y . 'echo $(($x - $y))')
}
testLambdaSymbolManyArguments() {
assertEquals 5 $(echo -e '1\n2\n3\n4\n5' | lambda a b c d e . 'echo $(($a + $b + $c + $d - $e))')
}
testLambdaSymbolManyArguments_ifInsufficientNumberOfArgumentsInLambda() {
assertEquals 6 $(echo -e '1\n2\n3\n4\n5' | lambda a b c . 'echo $(($a + $b + $c))')
}
testLambdaSymbolManyArguments_ifInsufficientNumberOfInputArguments() {
echo -e '1\n2' | lambda a b c d e . 'echo $(($a + $b + $c + $d + $e))' 2> /dev/null \
&& fail "There should be syntax error"
}
. ./shunit2-init.sh

View file

@ -1,16 +0,0 @@
#! /bin/bash
testLastFromList() {
assertEquals 10 $(list {1..10} | list_last)
assertEquals 7 $(list 5 6 7 | list_last)
}
testLastFromOneElementList() {
assertEquals 1 $(list 1 | list_last)
}
testLastFromEmptyList() {
assertEquals "" "$(list | list_last)"
}
. ./shunit2-init.sh

File diff suppressed because it is too large Load diff

View file

@ -1,39 +0,0 @@
# vim:et:ft=sh:sts=2:sw=2
#
# Copyright 2008 Kate Ward. All Rights Reserved.
# Released under the LGPL (GNU Lesser General Public License).
#
# Author: kate.ward@forestent.com (Kate Ward)
#
# Library of shell functions.
# Convert a relative path into it's absolute equivalent.
#
# This function will automatically prepend the current working directory if the
# path is not already absolute. It then removes all parent references (../) to
# reconstruct the proper absolute path.
#
# Args:
# shlib_path_: string: relative path
# Outputs:
# string: absolute path
shlib_relToAbsPath()
{
shlib_path_=$1
# prepend current directory to relative paths
echo "${shlib_path_}" |grep '^/' >/dev/null 2>&1 \
|| shlib_path_="${PWD}/${shlib_path_}"
# clean up the path. if all seds supported true regular expressions, then
# this is what it would be:
shlib_old_=${shlib_path_}
while true; do
shlib_new_=`echo "${shlib_old_}" |sed 's/[^/]*\/\.\.\/*//;s/\/\.\//\//'`
[ "${shlib_old_}" = "${shlib_new_}" ] && break
shlib_old_=${shlib_new_}
done
echo "${shlib_new_}"
unset shlib_path_ shlib_old_ shlib_new_
}

View file

@ -1,251 +0,0 @@
#! /bin/sh
# vim:et:ft=sh:sts=2:sw=2
#
# Versions determines the versions of all installed shells.
#
# Copyright 2008-2017 Kate Ward. All Rights Reserved.
# Released under the Apache 2.0 License.
#
# Author: kate.ward@forestent.com (Kate Ward)
# https://github.com/kward/shlib
#
# This library provides reusable functions that determine actual names and
# versions of installed shells and the OS. The library can also be run as a
# script if set executable.
#
# Disable checks that aren't fully portable (POSIX != portable).
# shellcheck disable=SC2006
ARGV0=`basename "$0"`
LSB_RELEASE='/etc/lsb-release'
VERSIONS_SHELLS="ash /bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/sh /bin/zsh"
true; TRUE=$?
false; FALSE=$?
ERROR=2
UNAME_R=`uname -r`
UNAME_S=`uname -s`
__versions_haveStrings=${ERROR}
versions_osName() {
os_name_='unrecognized'
os_system_=${UNAME_S}
os_release_=${UNAME_R}
case ${os_system_} in
CYGWIN_NT-*) os_name_='Cygwin' ;;
Darwin)
os_name_=`/usr/bin/sw_vers -productName`
os_version_=`versions_osVersion`
case ${os_version_} in
10.4|10.4.[0-9]*) os_name_='Mac OS X Tiger' ;;
10.5|10.5.[0-9]*) os_name_='Mac OS X Leopard' ;;
10.6|10.6.[0-9]*) os_name_='Mac OS X Snow Leopard' ;;
10.7|10.7.[0-9]*) os_name_='Mac OS X Lion' ;;
10.8|10.8.[0-9]*) os_name_='Mac OS X Mountain Lion' ;;
10.9|10.9.[0-9]*) os_name_='Mac OS X Mavericks' ;;
10.10|10.10.[0-9]*) os_name_='Mac OS X Yosemite' ;;
10.11|10.11.[0-9]*) os_name_='Mac OS X El Capitan' ;;
10.12|10.12.[0-9]*) os_name_='macOS Sierra' ;;
10.13|10.13.[0-9]*) os_name_='macOS High Sierra' ;;
*) os_name_='macOS' ;;
esac
;;
FreeBSD) os_name_='FreeBSD' ;;
Linux) os_name_='Linux' ;;
SunOS)
if grep 'OpenSolaris' /etc/release >/dev/null; then
os_name_='OpenSolaris'
else
os_name_='Solaris'
fi
;;
esac
echo ${os_name_}
unset os_name_ os_system_ os_release_ os_version_
}
versions_osVersion() {
os_version_='unrecognized'
os_system_=${UNAME_S}
os_release_=${UNAME_R}
case ${os_system_} in
CYGWIN_NT-*)
os_version_=`expr "${os_release_}" : '\([0-9]*\.[0-9]\.[0-9]*\).*'`
;;
Darwin)
os_version_=`/usr/bin/sw_vers -productVersion`
;;
FreeBSD)
os_version_=`expr "${os_release_}" : '\([0-9]*\.[0-9]*\)-.*'`
;;
Linux)
if [ -r '/etc/os-release' ]; then
os_version_=`awk -F= '$1~/PRETTY_NAME/{print $2}' /etc/os-release \
|sed 's/"//g'`
elif [ -r '/etc/redhat-release' ]; then
os_version_=`cat /etc/redhat-release`
elif [ -r '/etc/SuSE-release' ]; then
os_version_=`head -n 1 /etc/SuSE-release`
elif [ -r "${LSB_RELEASE}" ]; then
if grep -q 'DISTRIB_ID=Ubuntu' "${LSB_RELEASE}"; then
# shellcheck disable=SC2002
os_version_=`cat "${LSB_RELEASE}" \
|awk -F= '$1~/DISTRIB_DESCRIPTION/{print $2}' \
|sed 's/"//g;s/ /-/g'`
fi
fi
;;
SunOS)
if grep 'OpenSolaris' /etc/release >/dev/null; then
os_version_=`grep 'OpenSolaris' /etc/release |awk '{print $2"("$3")"}'`
else
major_=`echo "${os_release_}" |sed 's/[0-9]*\.\([0-9]*\)/\1/'`
minor_=`grep Solaris /etc/release |sed 's/[^u]*\(u[0-9]*\).*/\1/'`
os_version_="${major_}${minor_}"
fi
;;
esac
echo "${os_version_}"
unset os_name_ os_release_ os_version_ major_ minor_
}
versions_shellVersion() {
shell_=$1
shell_present_=${FALSE}
case "${shell_}" in
ash)
[ -x '/bin/busybox' ] && shell_present_=${TRUE}
;;
*)
[ -x "${shell_}" ] && shell_present_=${TRUE}
;;
esac
if [ ${shell_present_} -eq ${FALSE} ]; then
echo 'not installed'
return ${FALSE}
fi
version_=''
case ${shell_} in
*/sh)
# TODO(kward): fix this
## this could be one of any number of shells. try until one fits.
#version_=`versions_shell_bash ${shell_}`
## dash cannot be self determined yet
#[ -z "${version_}" ] && version_=`versions_shell_ksh ${shell_}`
## pdksh is covered in versions_shell_ksh()
#[ -z "${version_}" ] && version_=`versions_shell_zsh ${shell_}`
;;
ash) version_=`versions_shell_ash "${shell_}"` ;;
*/bash) version_=`versions_shell_bash "${shell_}"` ;;
*/dash)
# simply assuming Ubuntu Linux until somebody comes up with a better
# test. the following test will return an empty string if dash is not
# installed.
version_=`versions_shell_dash`
;;
*/ksh) version_=`versions_shell_ksh "${shell_}"` ;;
*/pdksh) version_=`versions_shell_pdksh "${shell_}"` ;;
*/zsh) version_=`versions_shell_zsh "${shell_}"` ;;
*) version_='invalid'
esac
echo "${version_:-unknown}"
unset shell_ version_
}
# The ash shell is included in BusyBox.
versions_shell_ash() {
busybox --help |head -1 |sed 's/BusyBox v\([0-9.]*\) .*/\1/'
}
versions_shell_bash() {
$1 --version 2>&1 |grep 'GNU bash' |sed 's/.*version \([^ ]*\).*/\1/'
}
versions_shell_dash() {
eval dpkg >/dev/null 2>&1
[ $? -eq 127 ] && return # return if dpkg not found
dpkg -l |grep ' dash ' |awk '{print $3}'
}
versions_shell_ksh() {
versions_shell_=$1
versions_version_=''
# Try a few different ways to figure out the version.
if versions_version_=`${versions_shell_} --version : 2>&1`; then
versions_version_=`echo "${versions_version_}" \
|sed 's/.*\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/'`
fi
if [ -z "${versions_version_}" ]; then
_versions_have_strings
versions_version_=`strings "${versions_shell_}" 2>&1 \
|grep Version \
|sed 's/^.*Version \(.*\)$/\1/;s/ s+ \$$//;s/ /-/g'`
fi
if [ -z "${versions_version_}" ]; then
versions_version_=`versions_shell_pdksh "${versions_shell_}"`
fi
echo "${versions_version_}"
unset versions_shell_ versions_version_
}
versions_shell_pdksh() {
_versions_have_strings
strings "$1" 2>&1 \
|grep 'PD KSH' \
|sed -e 's/.*PD KSH \(.*\)/\1/;s/ /-/g'
}
versions_shell_zsh() {
versions_shell_=$1
# Try a few different ways to figure out the version.
# shellcheck disable=SC2016
versions_version_=`echo 'echo ${ZSH_VERSION}' |${versions_shell_}`
if [ -z "${versions_version_}" ]; then
versions_version_=`${versions_shell_} --version 2>&1 |awk '{print $2}'`
fi
echo "${versions_version_}"
unset versions_shell_ versions_version_
}
# Determine if the 'strings' binary installed.
_versions_have_strings() {
[ ${__versions_haveStrings} -ne ${ERROR} ] && return
if eval strings /dev/null >/dev/null 2>&1; then
__versions_haveStrings=${TRUE}
return
fi
echo 'WARN: strings not installed. try installing binutils?' >&2
__versions_haveStrings=${FALSE}
}
versions_main() {
# Treat unset variables as an error.
set -u
os_name=`versions_osName`
os_version=`versions_osVersion`
echo "os: ${os_name} version: ${os_version}"
for shell in ${VERSIONS_SHELLS}; do
shell_version=`versions_shellVersion "${shell}"`
echo "shell: ${shell} version: ${shell_version}"
done
}
if [ "${ARGV0}" = 'versions' ]; then
versions_main "$@"
fi

View file

@ -1,25 +0,0 @@
#! /bin/bash
testListFromOneElement() {
assertEquals 1 $(list 1)
}
testListFromEmpty() {
assertEquals "" "$(list)"
}
testListUnlist() {
assertEquals "1 3 6" "$(list 1 3 6 | unlist)"
}
testList() {
list=$(cat <<EOF
1
3
6
EOF
)
assertEquals "$list" "$(list 1 3 6)"
}
. ./shunit2-init.sh

View file

@ -1,33 +0,0 @@
#!/bin/bash
testMapEmptyList() {
assertEquals "" "$(list | list_map lambda x . 'echo $(($x + 1))')"
}
testMapEmptyList_ifNoArgumentsInLambda() {
assertEquals "" "$(list | list_map lambda . 'echo 3')"
}
testMapOneElementList() {
assertEquals "3" "$(list 2 | list_map lambda x . 'echo $(($x + 1))')"
}
testMapList() {
assertEquals "2 3 4 5 6" "$(list {1..5} | list_map lambda x . 'echo $(($x + 1))' | unlist)"
}
testMapList_ifNoArgumentsInLambda() {
assertEquals "9 9 9 9 9" "$(list {1..5} | list_map lambda . 'echo 9' | unlist)"
}
testMapList_ifManyArgumentsInLambda() {
list {1..5} | list_map lambda x y . 'echo $(($x + $y))' 2> /dev/null \
&& fail "There should be syntax error, because map is an one argument operation"
}
testFlatMap() {
assertEquals "1 2 3 2 3 3" "$(list {1..3} | list_map lambda x . 'seq $x 3' | unlist)"
assertEquals "d e h l l l o o r w" "$(list hello world | list_map lambda x . 'command fold -w 1 <<< $x' | sort | unlist)"
}
. ./shunit2-init.sh

View file

@ -1,52 +0,0 @@
#! /bin/bash
testIsint() {
assertEquals 'true' $(isint 1)
assertEquals 'true' $(isint -1)
assertEquals 'false' $(isint a)
assertEquals 'false' $(isint "")
assertEquals '1 2 3 4 5' "$(list 1 a 2 b 3 c 4 d 5 e | filter lambda x . 'isint $x' | unlist )"
assertEquals '1 2' "$(list 1 a 2 b 3 c 4 d 5 e | filter lambda x . '($(isint $x) && [[ $x -le 2 ]] && ret true) || ret false ' | unlist )"
assertEquals 'false' $(not "isint 1")
assertEquals 'true' $(not "isint a")
}
testIsempty() {
assertEquals 'true' $(isempty "")
assertEquals 'false' $(isempty a)
assertEquals 'true' $(not "isempty a")
assertEquals 'false' $(not "isempty \"\"")
}
testIsfile() {
f=$(mktemp)
assertEquals 'true' $(isfile $f)
assertEquals 'false' $(isfile $f.xxx)
assertEquals 'false' $(isfile "")
assertEquals 'true' $(not "isfile $f.xxx")
assertEquals 'false' $(isnonzerofile $f)
echo hello world >$f
assertEquals 'true' $(isnonzerofile $f)
assertEquals 'true' $(iswritable $f)
chmod 400 $f
assertEquals 'false' $(iswritable $f)
assertEquals 'true' $(isreadable $f)
chmod 200 $f
assertEquals 'false' $(isreadable $f)
chmod 600 $f
rm $f
}
testIsdir() {
assertEquals 'true' $(isdir .)
assertEquals 'false' $(isdir sir_not_appearing_in_this_film)
}
. ./shunit2-init.sh

View file

@ -1,15 +0,0 @@
#! /bin/bash
testPrependToEmptyList() {
assertEquals 4 "$(list | list_prepend 4)"
}
testPrependToOneElementList() {
assertEquals "4 1" "$(list 1 | list_prepend 4 | unlist)"
}
testPrependToList() {
assertEquals "4 1 2 3 4 5" "$(list 1 2 3 4 5 | list_prepend 4 | unlist)"
}
. ./shunit2-init.sh

File diff suppressed because it is too large Load diff

View file

@ -1,8 +0,0 @@
#!/bin/bash
oneTimeSetUp() {
. ../src/fun.sh
}
# Load shUnit2.
. ./shunit2

View file

@ -1,15 +0,0 @@
#! /bin/bash
testLTailFrom10() {
assertEquals "2 3 4 5 6 7 8 9 10" "$(list {1..10} | list_tail | unlist)"
}
testLTailFromOneElementList() {
assertEquals "" "$(list 1 | list_tail)"
}
testLTailFromEmptyList() {
assertEquals "" "$(list | list_tail)"
}
. ./shunit2-init.sh

View file

@ -1,23 +0,0 @@
#! /bin/bash
testTake9From10() {
assertEquals "1 2 3 4 5 6 7 8 9" "$(list {1..10} | list_take 9 | unlist)"
}
testTake8From10() {
assertEquals "1 2 3 4 5 6 7 8" "$(list {1..10} | list_take 8 | unlist)"
}
testTakeAll() {
assertEquals "1 2 3 4 5 6 7 8 9 10" "$(list {1..10} | list_take 10 | unlist)"
}
testTakeMoreThanAvailable() {
assertEquals "1 2 3 4 5 6 7 8 9 10" "$(list {1..10} | list_take 15 | unlist)"
}
testTakeZero() {
assertEquals "" "$(list {1..10} | list_take 0 | unlist)"
}
. ./shunit2-init.sh

View file

@ -1,163 +0,0 @@
#! /bin/sh
# vim:et:ft=sh:sts=2:sw=2
#
# Unit test suite runner.
#
# Copyright 2008-2017 Kate Ward. All Rights Reserved.
# Released under the Apache 2.0 license.
#
# Author: kate.ward@forestent.com (Kate Ward)
# https://github.com/kward/shlib
#
# This script runs all the unit tests that can be found, and generates a nice
# report of the tests.
#
### ShellCheck (http://www.shellcheck.net/)
# Disable source following.
# shellcheck disable=SC1090,SC1091
# expr may be antiquated, but it is the only solution in some cases.
# shellcheck disable=SC2003
# Return if test_runner already loaded.
[ -z "${RUNNER_LOADED:-}" ] || return 0
RUNNER_LOADED=0
RUNNER_ARGV0=$(basename "$0")
RUNNER_SHELLS='/bin/bash'
RUNNER_TEST_SUFFIX='_test.sh'
runner_warn() { echo "runner:WARN $*" >&2; }
runner_error() { echo "runner:ERROR $*" >&2; }
runner_fatal() { echo "runner:FATAL $*" >&2; exit 1; }
runner_usage() {
echo "usage: ${RUNNER_ARGV0} [-e key=val ...] [-s shell(s)] [-t test(s)]"
}
_runner_tests() { echo ./*${RUNNER_TEST_SUFFIX} |sed 's#./##g'; }
_runner_testName() {
# shellcheck disable=SC1117
_runner_testName_=$(expr "${1:-}" : "\(.*\)${RUNNER_TEST_SUFFIX}")
if [ -n "${_runner_testName_}" ]; then
echo "${_runner_testName_}"
else
echo 'unknown'
fi
unset _runner_testName_
}
main() {
# Find and load versions library.
for _runner_dir_ in . ${LIB_DIR:-lib}; do
if [ -r "${_runner_dir_}/versions" ]; then
_runner_lib_dir_="${_runner_dir_}"
break
fi
done
[ -n "${_runner_lib_dir_}" ] || runner_fatal 'Unable to find versions library.'
. "${_runner_lib_dir_}/versions" || runner_fatal 'Unable to load versions library.'
unset _runner_dir_ _runner_lib_dir_
# Process command line flags.
env=''
while getopts 'e:hs:t:' opt; do
case ${opt} in
e) # set an environment variable
key=$(expr "${OPTARG}" : '\([^=]*\)=')
val=$(expr "${OPTARG}" : '[^=]*=\(.*\)')
# shellcheck disable=SC2166
if [ -z "${key}" -o -z "${val}" ]; then
runner_usage
exit 1
fi
eval "${key}='${val}'"
eval "export ${key}"
env="${env:+${env} }${key}"
;;
h) runner_usage; exit 0 ;; # help output
s) shells=${OPTARG} ;; # list of shells to run
t) tests=${OPTARG} ;; # list of tests to run
*) runner_usage; exit 1 ;;
esac
done
shift "$(expr ${OPTIND} - 1)"
# Fill shells and/or tests.
shells=${shells:-${RUNNER_SHELLS}}
tests=${tests:-$(_runner_tests)}
# Error checking.
if [ -z "${tests}" ]; then
runner_error 'no tests found to run; exiting'
exit 1
fi
cat <<EOF
#------------------------------------------------------------------------------
# System data.
#
$ uname -mprsv
$(uname -mprsv)
OS Name: $(versions_osName)
OS Version: $(versions_osVersion)
### Test run info.
shells: ${shells}
tests: ${tests}
EOF
for key in ${env}; do
eval "echo \"${key}=\$${key}\""
done
# Run tests.
for shell in ${shells}; do
echo
cat <<EOF
#------------------------------------------------------------------------------
# Running the test suite with ${shell}.
#
EOF
# Check for existence of shell.
shell_bin=${shell}
shell_name=''
shell_present=${FALSE}
case ${shell} in
ash)
shell_bin=$(which busybox)
[ $? -eq "${TRUE}" ] && shell_present="${TRUE}"
shell_bin="${shell_bin} ash"
shell_name=${shell}
;;
*)
[ -x "${shell_bin}" ] && shell_present="${TRUE}"
shell_name=$(basename "${shell}")
;;
esac
if [ "${shell_present}" -eq "${FALSE}" ]; then
runner_warn "unable to run tests with the ${shell_name} shell"
continue
fi
shell_version=$(versions_shellVersion "${shell}")
echo "shell name: ${shell_name}"
echo "shell version: ${shell_version}"
# Execute the tests.
for t in ${tests}; do
echo
echo "--- Executing the '$(_runner_testName "${t}'")' test suite. ---"
# ${shell_bin} needs word splitting.
# shellcheck disable=SC2086
( exec ${shell_bin} "./${t}" 2>&1; )
done
done
}
# Execute main() if this is run in standalone mode (i.e. not from a unit test).
[ -z "${SHUNIT_VERSION}" ] && main "$@"

View file

@ -1,40 +0,0 @@
#! /bin/bash
testTupIfEmpty() {
assertEquals '()' $(tup '')
}
testTupIfOneElement() {
assertEquals '(1)' $(tup 1)
assertEquals '(")' $(tup '"')
assertEquals "(')" $(tup "'")
assertEquals "(,)" $(tup ",")
assertEquals "(,,)" $(tup ",,")
assertEquals "(()" $(tup "(")
assertEquals "())" $(tup ")")
}
testTupHappyPath() {
assertEquals '(1,2,3,4,5)' $(tup 1 2 3 4 5)
assertEquals '(a-1,b-2,c-3)' $(tup 'a-1' 'b-2' 'c-3')
assertEquals '(a b,c d e,f)' "$(tup 'a b' 'c d e' 'f')"
}
testTupxIfZeroIndex() {
assertEquals '' "$(tup 1 3 | tupx 0 2>/dev/null)"
}
testTupl() {
assertEquals '4' "$(tup 4 5 | tupl)"
assertEquals '4' "$(tup 4 5 6 | tupl)"
assertEquals '6' "$(tup 6 | tupl)"
assertEquals 'foo bar' "$(tup 'foo bar' 1 'one' 2 | tupl)"
}
testTupr() {
assertEquals '5' "$(tup 4 5 | tupr)"
assertEquals '5' "$(tup 1 4 5 | tupr)"
assertEquals '5' "$(tup 5 | tupr)"
}
. ./shunit2-init.sh

View file

@ -1,21 +0,0 @@
#! /bin/bash
testUnlistFromList() {
list=$(cat <<EOF
1
2
6
EOF
)
assertEquals "1 2 6" "$(echo $list | unlist)"
}
testUnlistFromEmptyList() {
assertEquals "" "$(echo | unlist)"
}
testUnlistFromOneElementList() {
assertEquals "1" "$(echo 1 | unlist)"
}
. ./shunit2-init.sh