Compare commits

...

38 commits
v2.1 ... master

Author SHA1 Message Date
705798eeb0 Added back revers_str and changed the example script 2020-12-14 10:19:02 -05:00
46722c9b5d Simplified, shellchecked, and name deconflicted for personal use 2020-12-14 10:08:36 -05:00
Sławomir Śledź
142e1bade4 Simplifying release procedure 2019-10-07 10:27:02 +02:00
Slawomir Sledz
4c16fc52f7
Merge pull request #4 from tpoindex/master
Update docs
2019-10-07 01:46:34 +02:00
Tom Poindexter
5e1cf52840
Add docs for ntup, maybe, is* predicates
Updated ntup docs to show nested tuples, and comma safe elements.
Added docs for maybe and is* predicates.
2019-10-02 17:54:48 -06:00
Tom Poindexter
da8e3ca3cf
Merge pull request #1 from ssledz/master
sync with upstream
2019-10-02 16:54:02 -06:00
Sławomir Śledź
b783ac9e8f Merge branch 'develop' 2019-10-01 00:37:03 +02:00
Slawomir Sledz
9840e94a5d
Create LICENSE 2019-10-01 00:34:01 +02:00
Sławomir Śledź
67c88a5b3f more docs 2019-10-01 00:24:56 +02:00
Sławomir Śledź
b590285ec9 Fixing examples & documentation + adding example of usage to documentation. 2019-10-01 00:02:34 +02:00
Sławomir Śledź
540840e9d2 Manually bumping version 2019-09-14 20:23:38 +02:00
tpoindex
1b234ff597 avoid collisions with common /usr/bin/ commands
rename head, tail, zip to lhead, ltail, and lzip to avoid collisions with command unix commands
2019-09-14 20:21:06 +02:00
tpoindex
44dbdd3fbc fluent predicates for filtering 2019-09-14 20:21:06 +02:00
tpoindex
b19ab5180b maybe monad and friends
maybe - return a tuple of (Nothing) or (Just,value)
maybemap - apply map function when maybe has a value and wrap in another maybe; else when nothing return nothing
maybevalue - return value of maybe; else when nothing return optional default args
2019-09-14 20:21:06 +02:00
tpoindex
7736a293a0 ntup{x,l,r} - tuples that can be nested and without quoting issues, base64 encoded elements 2019-09-14 20:21:06 +02:00
tpoindex
b40adbb643 fix comma quoting in tup/tupx by quoting all commas 2019-09-14 20:21:06 +02:00
Sławomir Śledź
febedd4c5c Bumping version 2019-09-14 19:54:57 +02:00
Slawomir Sledz
e5f3e8c5f3
Merge pull request #3 from tpoindex/master
Fix tup/tupx plus a few additions: safe nested tuples, maybe monad, filter predicates.
2019-09-14 11:55:48 +02:00
tpoindex
1ead6d0b87 avoid collisions with common /usr/bin/ commands
rename head, tail, zip to lhead, ltail, and lzip to avoid collisions with command unix commands
2019-09-11 23:53:56 -06:00
tpoindex
7b6531a74e fluent predicates for filtering 2019-09-11 23:46:47 -06:00
tpoindex
912b3f2491 maybe monad and friends
maybe - return a tuple of (Nothing) or (Just,value)
maybemap - apply map function when maybe has a value and wrap in another maybe; else when nothing return nothing
maybevalue - return value of maybe; else when nothing return optional default args
2019-09-11 22:47:39 -06:00
tpoindex
9c238777e1 ntup{x,l,r} - tuples that can be nested and without quoting issues, base64 encoded elements 2019-09-11 20:58:30 -06:00
tpoindex
cba3556da8 fix comma quoting in tup/tupx by quoting all commas 2019-09-11 20:17:45 -06:00
Sławomir Śledź
20242e1d3f [release] merge release/2.3 into develop 2019-08-31 02:14:44 +02:00
Sławomir Śledź
68125ee7d8 [release] merge previous version into master to avoid the increased version number 2019-08-31 02:14:44 +02:00
Sławomir Śledź
021477770c [release] prepare for next development iteration 2019-08-31 02:14:44 +02:00
Sławomir Śledź
61e96159ec [release] prepare release v2.3 2019-08-31 02:14:44 +02:00
Sławomir Śledź
bc44865f5a ext documentation 2019-08-31 02:03:35 +02:00
Sławomir Śledź
14dd7c3993 [release] merge previous version into master to avoid the increased version number 2019-08-31 01:55:31 +02:00
Sławomir Śledź
0f8f528fcb [release] merge release/2.2 into develop 2019-08-31 01:55:31 +02:00
Sławomir Śledź
a23cb10ac6 [release] prepare release v2.2 2019-08-31 01:55:31 +02:00
Sławomir Śledź
857a3c6109 [release] prepare for next development iteration 2019-08-31 01:55:31 +02:00
Slawomir Sledz
79e6873e8e
Merge pull request #2 from ssledz/feature-#1
#1 : Shorthand notations for lambdas
2019-08-31 01:54:16 +02:00
Sławomir Śledź
c1ae19f270 #1 : Shorthand notations for lambdas 2019-08-31 01:52:16 +02:00
Sławomir Śledź
5979ac8548 [release] merge previous version into master to avoid the increased version number 2018-03-27 23:14:57 +02:00
Sławomir Śledź
adfe8ec68b [release] merge release/2.1 into develop 2018-03-27 23:14:57 +02:00
Sławomir Śledź
2a614cb04d [release] prepare for next development iteration 2018-03-27 23:14:57 +02:00
Sławomir Śledź
47d2c2b4d4 [release] merge previous version into master to avoid the increased version number 2018-03-11 00:55:52 +01:00
18 changed files with 730 additions and 675 deletions

View file

@ -1 +1 @@
2.1
2.5b

22
LICENSE Normal file
View file

@ -0,0 +1,22 @@
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.

279
README.md
View file

@ -1,12 +1,15 @@
# Introduction
[Introduction to fun.sh library](http://ssledz.github.io/presentations/bash-fun.html#/)
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/ssledz/bash-fun/master/src/fun.sh > fun.sh; cat fun.sh)
. <(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
```
@ -14,13 +17,17 @@ seq 1 4 | sum
# Functions overview
|||||||
|------|------|------|------|------|------|
|**plus**|**append**|**buff**|**curry**|**div**|**drop**|
|**factorial**|**filter**|**foldl**|**foldr**|**head**|**join**|
|**lambda**|**last**|**list**|**map**|**mod**|**mul**|
|**prepend**|**product**|**ret**|**revers_str**|**revers**|**scanl**|
|**splitc**|**strip**|**sub**|**sum**|**tail**|**take**|
|**catch**|**try**|**tupl**|**tupr**|**tup**|**tupx**|
|**unlist**|**zip**|**λ**|**with_trampoline**|**res**|**call**|
|**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*
@ -34,25 +41,25 @@ $ list 1 2 3 4 5 | unlist
1 2 3 4 5
```
## *take/drop/tail/head/last*
## *list_take/list_drop/list_tail/list_head/list_last*
```bash
$ list 1 2 3 4 | drop 2
$ list 1 2 3 4 | list_drop 2
3
4
$ list 1 2 3 4 5 | head
$ list 1 2 3 4 5 | list_head
1
$ list 1 2 3 4 | tail
$ list 1 2 3 4 | list_tail
2
3
4
$ list 1 2 3 4 5 | last
$ list 1 2 3 4 5 | list_last
5
$ list 1 2 3 4 5 | take 2
$ list 1 2 3 4 5 | list_take 2
1
2
```
@ -60,45 +67,36 @@ $ list 1 2 3 4 5 | take 2
## *join*
```bash
$ list 1 2 3 4 5 | join ,
$ list 1 2 3 4 5 | list_join ,
1,2,3,4,5
$ list 1 2 3 4 5 | join , [ ]
[1,2,3,4,5]
```
## *map*
```bash
$ seq 1 5 | map λ a . 'echo $((a + 5))'
$ seq 1 5 | list_map λ a . 'echo $((a + 5))'
6
7
8
9
10
$ list a b s d e | map λ a . 'echo $a$(echo $a | tr a-z A-Z)'
$ 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
```
## *flat map*
```bash
$ seq 2 3 | map λ a . 'seq 1 $a' | join , [ ]
[1,2,1,2,3]
$ list a b c | map λ a . 'echo $a; echo $a | tr a-z A-z' | join , [ ]
[a,A,b,B,c,C]
```
## *filter*
```bash
$ seq 1 10 | filter λ a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false'
$ seq 1 10 | filter even
2
4
6
@ -111,10 +109,6 @@ $ seq 1 10 | filter λ a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false'
```bash
$ list a b c d | foldl λ acc el . 'echo -n $acc-$el'
a-b-c-d
$ list '' a b c d | foldr λ acc el .\
'if [[ ! -z $acc ]]; then echo -n $acc-$el; else echo -n $el; fi'
d-c-b-a
```
```bash
@ -123,11 +117,8 @@ $ seq 1 4 | foldl λ acc el . 'echo $(($acc + $el))'
```
```bash
$ seq 1 4 | foldl λ acc el . 'echo $(mul $(($acc + 1)) $el)'
$ seq 1 4 | foldl λ acc el . 'echo $(multiply $(($acc + 1)) $el)'
64 # 1 + (1 + 1) * 2 + (4 + 1) * 3 + (15 + 1) * 4 = 64
$ seq 1 4 | foldr λ acc el . 'echo $(mul $(($acc + 1)) $el)'
56 # 1 + (1 + 1) * 4 + (8 + 1) * 3 + (27 + 1) * 2 = 56
```
## *tup/tupx/tupl/tupr*
@ -140,19 +131,16 @@ $ tup 'foo bar' 1 'one' 2
(foo bar,1,one,2)
$ tup , 1 3
(u002c,1,3)
(,,1,3)
```
```bash
$ tupl $(tup a 1)
$ echo tup a 1 | tupl
a
$ tupr $(tup a 1)
$ echo tup a 1 | tupr
1
$ tup , 1 3 | tupl
,
$ tup 'foo bar' 1 'one' 2 | tupl
foo bar
@ -160,39 +148,10 @@ $ tup 'foo bar' 1 'one' 2 | tupr
2
```
```bash
$ tup 'foo bar' 1 'one' 2 | tupx 2
1
$ tup 'foo bar' 1 'one' 2 | tupx 1,3
foo bar
one
$ tup 'foo bar' 1 'one' 2 | tupx 2-4
1
one
2
```
## *buff*
## *list_zip*
```bash
$ seq 1 10 | buff λ a b . 'echo $(($a + $b))'
3
7
11
15
19
$ seq 1 10 | buff λ a b c d e . 'echo $(($a + $b + $c + $d + $e))'
15
40
```
## *zip*
```bash
$ list a b c d e f | zip $(seq 1 10)
$ list a b c d e f | list_zip $(seq 1 10)
(a,1)
(b,2)
(c,3)
@ -202,60 +161,77 @@ $ list a b c d e f | zip $(seq 1 10)
```
```bash
$ list a b c d e f | zip $(seq 1 10) | last | tupr
$ list a b c d e f | list_zip $(seq 1 10) | list_last | tupr
6
```
## *curry*
## *not/isint/isempty*
```bash
add2() {
echo $(($1 + $2))
}
```
$ isint 42
true
```bash
$ curry inc add2 1
```
$ list blah | isint
false
```bash
$ inc 2
3
$ not true
false
$ seq 1 3 | map λ a . 'inc $a'
2
3
4
```
$ not "isint 777"
false
## *try/catch*
```bash
$ echo 'expr 2 / 0' | try λ _ . 'echo 0'
0
$ echo 'expr 2 / 0' | try λ status . 'echo $status'
2
$ echo 'expr 2 / 2' | try λ _ . 'echo 0'
$ list 1 2 "" c d 6 | filter λ a . 'isint $a'
1
```
2
6
```bash
try λ _ . 'echo some errors during pull; exit 1' < <(echo git pull)
```
```bash
$ echo 'expr 2 / 0' \
| LANG=en catch λ cmd status val . 'echo cmd=$cmd,status=$status,val=$val'
cmd=expr 2 / 0,status=2,val=(expr:,division,by,zero)
```
```bash
$ echo 'expr 2 / 2' | catch λ _ _ val . 'tupl $val'
$ 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
@ -268,58 +244,10 @@ $ seq 1 5 | scanl lambda acc el . 'echo $(($acc + $el))'
```
```bash
$ seq 1 5 | scanl lambda a b . 'echo $(($a + $b))' | last
$ seq 1 5 | scanl lambda a b . 'echo $(($a + $b))' | list_last
15
```
## *with_trampoline/res/call*
```bash
factorial() {
fact_iter() {
local product=$1
local counter=$2
local max_count=$3
if [[ $counter -gt $max_count ]]; then
res $product
else
call fact_iter $(echo $counter\*$product | bc) $(($counter + 1)) $max_count
fi
}
with_trampoline fact_iter 1 1 $1
}
```
```bash
$ time factorial 30 | fold -w 70
265252859812191058636308480000000
real 0m1.854s
user 0m0.072s
sys 0m0.368s
```
```bash
time factorial 60 | fold -w 70
8320987112741390144276341183223364380754172606361245952449277696409600
000000000000
real 0m3.635s
user 0m0.148s
sys 0m0.692s
```
```bash
$ time factorial 90 | fold -w 70
1485715964481761497309522733620825737885569961284688766942216863704985
393094065876545992131370884059645617234469978112000000000000000000000
real 0m4.371s
user 0m0.108s
sys 0m0.436s
```
# Examples
```bash
@ -332,7 +260,7 @@ processNames() {
list $@ \
| filter λ name . '[[ ${#name} -gt 1 ]] && ret true || ret false' \
| map λ name . 'uppercase $name' \
| list_map λ name . 'uppercase $name' \
| foldl λ acc el . 'echo $acc,$el'
}
@ -344,6 +272,21 @@ processNames adam monika s slawek d daniel Bartek j k
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)

View file

@ -1,30 +1,29 @@
#!/bin/bash
source ../src/fun.sh
seq 1 4 | sum
seq 1 4 | product
factorial 4
seq 1 4 | scanl lambda a b . 'echo $(add $a $b)'
echo map mul
seq 1 4 | map lambda a . 'echo $(mul $a 2)'
echo map sub
seq 1 4 | map lambda a . 'echo $(sub $a 2)'
echo map multiply
seq 1 4 | list_map lambda a . 'echo $(multiply $a 2)'
echo map minus
seq 1 4 | list_map lambda a . 'echo $(minus $a 2)'
echo map add
seq 1 4 | map lambda a . 'echo $(add $a 2)'
echo map div
seq 1 4 | map lambda a . 'echo $(div $a 2)'
echo map mod
seq 1 4 | map lambda a . 'echo $(mod $a 2)'
seq 1 4 | list_map lambda a . 'echo $(add $a 2)'
echo map divide
seq 1 4 | list_map lambda a . 'echo $(divide $a 2)'
echo list_map mod
seq 1 4 | list_map lambda a . 'echo $(mod $a 2)'
echo 'list & head'
list 1 2 3 4 5 | head
list {1..2} | append {3..4} | prepend {99..102}
list 1 2 3 4 5 | list_head
list {1..2} | list_append {3..4} | list_prepend {99..102}
list {1..2} | unlist
list {1..10} | head
list {1..10} | drop 7
list {1..10} | take 3
list {1..10} | last
list {1..10} | map λ a . 'echo $(mul $a 2)'
list {1..10} | list_head
list {1..10} | list_drop 7
list {1..10} | list_take 3
list {1..10} | list_last
list {1..10} | list_map λ a . 'echo $(multiply $a 2)'
id() {
λ x . '$x'
@ -38,122 +37,32 @@ foobar() {
list {1,2,3} | foobar
echo -n abcdefg | revers_str # gfedcba
echo -n abcdefg | splitc | join , '[' ']' # [a,b,c,d,e,f,g]
echo -n abcdefg | splitc | revers | join , '[' ']' # [g,f,e,d,c,b,a]
echo -n abcdefg | revers_str # gfedcba
echo -n abcdefg | splitc | list_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 | foldr lambda a b . 'echo $a$b' # gfedcba
echo 'ls' | try λ cmd status ret . 'echo $cmd [$status]; echo $ret'
list {1..10} | filter lambda a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false' | join , '[' ']' # [2,4,6,8,10]
function add() {
expr $1 + $2
}
curry add3 add 3
add3 9
list {1..10} | filter lambda a . '[[ $(mod $a 2) -eq 0 ]] && ret true || ret false' | list_join , # 2,4,6,8,10
list a b c d | foldl lambda acc el . 'echo -n $acc-$el'
list '' a b c d | foldr lambda acc el . 'if [[ ! -z $acc ]]; then echo -n $acc-$el; else echo -n $el; fi'
seq 1 4 | foldl lambda acc el . 'echo $(($acc + $el))'
#1 - 2 - 3 - 4
seq 1 4 | foldl lambda acc el . 'echo $(($acc - $el))'
#1 - 4 - 3 - 2
seq 1 4 | foldr 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 $(mul $(($acc + 1)) $el)'
#1 + (1 + 1) * 4 + (8 + 1) * 3 + (27 + 1) * 2 = 56
seq 1 4 | foldr lambda acc el . 'echo $(mul $(($acc + 1)) $el)'
seq 1 4 | foldl lambda acc el . 'echo $(multiply $(($acc + 1)) $el)'
tup a 1
tupl $(tup a 1)
tupr $(tup a 1)
tup a 1 | tupl
tup a 1 | tupr
seq 1 10 | buff lambda a b . 'echo $(($a + $b))'
echo 'XX'
seq 1 10 | buff lambda a b c d e . 'echo $(($a + $b + $c + $d + $e))'
list a b c d e f | zip $(seq 1 10)
list a b c d e f | list_zip $(seq 1 10)
echo
list a b c d e f | zip $(seq 1 10) | last | tupr
arg='[key1=value1,key2=value2,key3=value3]'
get() {
local pidx=$1
local idx=$2
local arg=$3
echo $arg | tr -d '[]' | cut -d',' -f$idx | cut -d'=' -f$pidx
}
curry get_key get 1
curry get_value get 2
get_key 1 $arg
get_value 1 $arg
seq 1 3 | map lambda a . 'tup $(get_key $a $arg) $(get_value $a $arg)'
echo 'ls /home' | try λ cmd status ret . 'echo $cmd [$status]; echo $ret'
echo '/home' | try λ cmd status ret . 'echo $cmd [$status]; echo $ret'
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))' | last
seq 1 5 | scanl lambda a b . 'echo $(($a + $b))' | list_last
seq 2 3 | map lambda a . 'seq 1 $a' | join , [ ]
list a b c | map lambda a . 'echo $a; echo $a | tr a-z A-z' | join , [ ]
echo 0 | cat - <(curl -s https://raw.githubusercontent.com/ssledz/bash-fun/v1.1.1/src/fun.sh) | \
map lambda a . 'list $a' | foldl lambda acc el . 'echo $(($acc + 1))'
echo 0 | cat - <(curl -s curl -s https://raw.githubusercontent.com/ssledz/bash-fun/v1.1.1/src/fun.sh) \
| foldl lambda acc el . 'echo $(($acc + 1))'
factorial() {
fact_iter() {
local product=$1
local counter=$2
local max_count=$3
if [[ $counter -gt $max_count ]]; then
echo $product
else
fact_iter $(echo $counter\*$product | bc) $(($counter + 1)) $max_count
fi
}
fact_iter 1 1 $1
}
factorial_trampoline() {
fact_iter() {
local product=$1
local counter=$2
local max_count=$3
if [[ $counter -gt $max_count ]]; then
res $product
else
call fact_iter $(echo $counter\*$product | bc) $(($counter + 1)) $max_count
fi
}
with_trampoline fact_iter 1 1 $1
}
echo Factorial test
time factorial 30
time factorial_trampoline 30
time factorial 60
time factorial_trampoline 60
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 ,

View file

@ -1,47 +0,0 @@
#!/bin/bash
version=$(cat .version)
release_version=${version%%-SNAPSHOT}
new_version=$(echo $release_version+0.1 | bc)
[[ $? -ne 0 ]] && echo 'Error exiting.' && exit 1
snapshot_version=${new_version}-SNAPSHOT
cat <<EOF
current version : $version
release version : $release_version
new snapshot version: $snapshot_version
EOF
git fetch
echo start the release by creating a new release branch
git checkout -b release/$release_version origin/develop
echo $release_version > ./.version
git add ./.version
git commit -m "[release] prepare release v$release_version"
git tag v$release_version
echo $snapshot_version > ./.version
git add ./.version
git commit -m "[release] prepare for next development iteration"
echo merge the version back into develop
git checkout develop
git merge --no-ff -m "[release] merge release/$release_version into develop" release/$release_version
git checkout master
echo merge the version back into master but use the tagged version instead of the release/$releaseVersion HEAD
git merge --no-ff -m "[release] merge previous version into master to avoid the increased version number" release/$release_version~1
echo get back on the develop branch
git checkout develop
echo finally push everything
git push origin develop master
git push --tags
echo removing the release branch
git branch -D release/$release_version

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

@ -1,318 +1,553 @@
#!/bin/bash
drop() {
command tail -n +$(($1 + 1))
}
take() {
command head -n ${1}
}
tail() {
drop 1
}
head() {
take 1
}
last() {
command tail -n 1
}
#!/bin/sh
###############################################
## List Functions
###############################################
list() {
for i in "$@"; do
echo "$i"
done
for i in "$@"; do
echo "$i"
done
}
unlist() {
cat - | xargs
xargs
}
append() {
cat -
list "$@"
# Drop the first n items of a list.
list_drop() {
command tail -n +$(($1 + 1))
}
prepend() {
list "$@"
cat -
# 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 -
list "$@"
}
# Add the contents of standard input
# to the beginning of the list.
list_prepend() {
list "$@"
cat -
}
###############################################
## Lambdas and Lists
###############################################
# Defines an anonymous function.
lambda() {
# shellcheck disable=2039
local expression
lam() {
# shellcheck disable=2039
local arg
while [ $# -gt 0 ]; do
arg="$1"
shift
if [ "$arg" = '.' ]; then
echo "$@"
return
else
echo "read $arg;"
fi
done
}
lam() {
local arg
while [[ $# -gt 0 ]]; do
arg="$1"
shift
if [[ $arg = '.' ]]; then
echo "$@"
return
else
echo "read $arg;"
fi
done
}
eval $(lam "$@")
expression=$(lam "$@")
eval "$expression"
}
# Same as lambda.
# shellcheck disable=2039
λ() {
lambda "$@"
lambda "$@"
}
map() {
local x
while read x; do
echo "$x" | "$@"
done
# Print the number of arguments a lambda takes.
# shellcheck disable=2039
λ_num_args() {
# Calculates the number of arguments a lambda takes
minus "$#" 3
}
foldl() {
local f="$@"
local acc
read acc
while read elem; do
acc="$({ echo $acc; echo $elem; } | $f )"
done
echo "$acc"
}
foldr() {
local f="$@"
local acc
local zero
read zero
foldrr() {
local elem
if read elem; then
acc=$(foldrr)
# [[ -z $acc ]] && echo $elem && return
else
echo $zero && return
# Perform an operation to each
# element(s) of a list provided
# through standard input.
list_map() {
# shellcheck disable=2039
local x
# shellcheck disable=2039
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" | "$@"
done
fi
acc="$({ echo $acc; echo $elem; } | $f )"
echo "$acc"
}
foldrr
}
# 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() {
# shellcheck disable=2039
local acc
read -r acc
while read -r elem; do
acc=$({ echo "$acc"; echo "$elem"; } | "$@" )
done
echo "$acc"
}
# Constructs a list where each element
# is the foldl of the 0th-ith elements of
# the list.
scanl() {
local f="$@"
local acc
read acc
echo $acc
while read elem; do
acc="$({ echo $acc; echo $elem; } | $f )"
# shellcheck disable=2039
local acc
read -r acc
echo "$acc"
done
while read -r elem; do
acc=$({ echo "$acc"; echo "$elem"; } | "$@" )
echo "$acc"
done
}
mul() {
( set -f; echo $(($1 * $2)) )
# Drops any elements of the list where the
# function performed on it evaluates to false.
filter() {
# shellcheck disable=2039
local x
while read -r x; do
ret=$(echo "$x" | "$@")
if_then "$ret" "echo $x"
done
}
plus() {
echo $(($1 + $2))
# 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
}
sub() {
echo $(($1 - $2))
# 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 -; }"
}
div() {
echo $(($1 / $2))
###############################################
## 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() {
# 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))
}
minus() {
# shellcheck disable=2039
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() {
# shellcheck disable=2039
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() {
echo $(($1 % $2))
# shellcheck disable=2039
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() {
foldl lambda a b . 'echo $(($a + $b))'
foldl lambda a b . "add \$a \$b"
}
product() {
foldl lambda a b . 'echo $(mul $a $b)'
foldl lambda a b . "multiply \$a \$b"
}
factorial() {
seq 1 $1 | product
seq 1 "$1" | product
}
###############################################
## String Operations
###############################################
# Splits a string into a list where each element
# is one character.
splitc() {
cat - | sed 's/./&\n/g'
sed 's/./\n&/g' | list_tail
}
join() {
local delim=$1
local pref=$2
local suff=$3
echo $pref$(cat - | foldl lambda a b . 'echo $a$delim$b')$suff
# Takes a list and creates a string where
# each element is seperated by a delimiter.
list_join() {
# shellcheck disable=2039
local delim
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() {
foldl lambda a b . 'append $b $a'
# shellcheck disable=2039
local result
# shellcheck disable=2039
local n
while read -r n; do
result="$n\n$result"
done
echo "$result"
}
# Reverses a string
revers_str() {
cat - | splitc | revers | join
splitc | revers | list_join
}
catch() {
local f="$@"
local cmd=$(cat -)
local val=$(2>&1 eval "$cmd"; echo $?)
local cnt=$(list $val | wc -l)
local status=$(list $val | last)
$f < <(list "$cmd" $status $(list $val | take $((cnt - 1)) | unlist | tup))
# Removes multiple occurences of
# a single character from the beginning
# of the list.
lstrip() {
# shellcheck disable=2039
local c
if [ $# -eq 0 ] ; then
c=" "
else
c="$1"
fi
sed "s/^$c*//g"
}
try() {
local f="$@"
catch lambda cmd status val . '[[ $status -eq 0 ]] && tupx 1- $val | unlist || { '"$f"' < <(list $status); }'
# 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() {
echo $@
echo "$@"
"$@"
}
filter() {
local x
while read x; do
ret=$(echo "$x" | "$@")
$ret && echo $x
done
do_nothing() {
echo > /dev/null
}
pass() {
echo > /dev/null
###############################################
## Useful utility functions
###############################################
isint() {
result_to_bool "echo \"$1\" | grep -Eq '^-?[0-9]+$'"
}
dropw() {
local x
while read x && $(echo "$x" | "$@"); do
pass
done
[[ ! -z $x ]] && { echo $x; cat -; }
isempty() {
result_to_bool "[ -z \"$1\" ]"
}
peek() {
local x
while read x; do
([ $# -eq 0 ] && 1>&2 echo $x || 1>&2 "$@" < <(echo $x))
echo $x
done
isfile() {
result_to_bool "[ -f \"$1\" ]"
}
stripl() {
local arg=$1
cat - | map lambda l . 'ret ${l##'$arg'}'
isnonzerofile() {
result_to_bool "[ -s \"$1\" ]"
}
stripr() {
local arg=$1
cat - | map lambda l . 'ret ${l%%'$arg'}'
isreadable() {
result_to_bool "[ -r \"$1\" ]"
}
strip() {
local arg=$1
cat - | stripl "$arg" | stripr "$arg"
iswritable() {
result_to_bool "[ -w \"$1\" ]"
}
buff() {
local cnt=-1
for x in $@; do
[[ $x = '.' ]] && break
cnt=$(plus $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 | "$@"
}
tup() {
if [[ $# -eq 0 ]]; then
local arg
read arg
tup $arg
else
list "$@" | map lambda x . 'echo ${x/,/u002c}' | join , '(' ')'
fi
}
tupx() {
if [[ $# -eq 1 ]]; then
local arg
read arg
tupx "$1" "$arg"
else
local n=$1
shift
echo "$@" | stripl '(' | stripr ')' | cut -d',' -f${n} | tr ',' '\n' | map lambda x . 'echo ${x/u002c/,}'
fi
}
tupl() {
tupx 1 "$@"
}
tupr() {
tupx 1- "$@" | last
}
zip() {
local list=$*
cat - | while read x; do
y=$(list $list | take 1)
tup $x $y
list=$(list $list | drop 1)
done
}
curry() {
exportfun=$1; shift
fun=$1; shift
params=$*
cmd=$"function $exportfun() {
more_params=\$*;
$fun $params \$more_params;
}"
eval $cmd
}
with_trampoline() {
local f=$1; shift
local args=$@
while [[ $f != 'None' ]]; do
ret=$($f $args)
# echo $ret
f=$(tupl $ret)
args=$(echo $ret | tupx 2- | tr ',' ' ')
done
echo $args
}
res() {
local value=$1
tup "None" $value
}
call() {
local f=$1; shift
local args=$@
tup $f $args
isdir() {
result_to_bool "[ -d \"$1\" ]"
}

View file

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

View file

@ -1,19 +0,0 @@
#! /bin/bash
testCatchIfSuccess() {
assertEquals 1 "$(echo 'expr 2 / 2' | catch lambda cmd status val . '[[ $status -eq 0 ]] && tupl $val || echo 0')"
}
testCatchIfError() {
assertEquals 0 $(echo 'expr 2 / 0' | catch lambda cmd status val . '[[ $status -eq 0 ]] && tupl $val || echo 0')
assertEquals 'cmd=expr 2 / 0,status=2,val=(expr:,division,by,zero)' "$(echo 'expr 2 / 0' | echo 'expr 2 / 0' | LANG=en catch lambda cmd status val . 'echo cmd=$cmd,status=$status,val=$val')"
}
testCatchEdgeCases() {
assertEquals 1 "$(echo 'expr 2 / 2' | catch lambda _ _ val . 'tupl $val')"
assertEquals 'expr 2 / 2' "$(echo 'expr 2 / 2' | catch lambda cmd . 'ret $cmd')"
assertEquals 'expr 2 / 2,0' "$(echo 'expr 2 / 2' | catch lambda cmd status . 'ret $cmd,$status')"
assertEquals 'expr 2 / 0,2' "$(echo 'expr 2 / 0' | catch lambda cmd status . 'ret $cmd,$status')"
}
. ./shunit2-init.sh

View file

@ -1,23 +1,23 @@
#! /bin/bash
testDrop9From10() {
assertEquals 10 $(list {1..10} | drop 9)
assertEquals 10 $(list {1..10} | list_drop 9)
}
testDrop8From10() {
assertEquals "9 10" "$(list {1..10} | drop 8 | unlist)"
assertEquals "9 10" "$(list {1..10} | list_drop 8 | unlist)"
}
testDropAll() {
assertEquals "" "$(list {1..10} | drop 10)"
assertEquals "" "$(list {1..10} | list_drop 10)"
}
testDropMoreThanAvailable() {
assertEquals "" "$(list {1..10} | drop 15)"
assertEquals "" "$(list {1..10} | list_drop 15)"
}
testDropZero() {
assertEquals "1 2 3 4 5 6 7 8 9 10" "$(list {1..10} | drop 0 | unlist)"
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 +1,16 @@
#! /bin/bash
testHeadFromList() {
assertEquals 1 $(list {1..10} | head)
assertEquals 5 $(list 5 6 7 | head)
testLHeadFromList() {
assertEquals 1 $(list {1..10} | list_head)
assertEquals 5 $(list 5 6 7 | list_head)
}
testHeadFromOneElementList() {
assertEquals 1 $(list 1 | head)
testLHeadFromOneElementList() {
assertEquals 1 $(list 1 | list_head)
}
testHeadFromEmptyList() {
assertEquals "" "$(list | head)"
testLHeadFromEmptyList() {
assertEquals "" "$(list | list_head)"
}
. ./shunit2-init.sh

View file

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

View file

@ -1,33 +1,33 @@
#!/bin/bash
testMapEmptyList() {
assertEquals "" "$(list | map lambda x . 'echo $(($x + 1))')"
assertEquals "" "$(list | list_map lambda x . 'echo $(($x + 1))')"
}
testMapEmptyList_ifNoArgumentsInLambda() {
assertEquals "" "$(list | map lambda . 'echo 3')"
assertEquals "" "$(list | list_map lambda . 'echo 3')"
}
testMapOneElementList() {
assertEquals "3" "$(list 2 | map lambda x . 'echo $(($x + 1))')"
assertEquals "3" "$(list 2 | list_map lambda x . 'echo $(($x + 1))')"
}
testMapList() {
assertEquals "2 3 4 5 6" "$(list {1..5} | map lambda x . 'echo $(($x + 1))' | unlist)"
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} | map lambda . 'echo 9' | unlist)"
assertEquals "9 9 9 9 9" "$(list {1..5} | list_map lambda . 'echo 9' | unlist)"
}
testMapList_ifManyArgumentsInLambda() {
list {1..5} | map lambda x y . 'echo $(($x + $y))' 2> /dev/null \
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} | map lambda x . 'seq $x 3' | unlist)"
assertEquals "d e h l l l o o r w" "$(list hello world | map lambda x . 'command fold -w 1 <<< $x' | sort | unlist)"
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

52
test/predicates_test.sh Executable file
View file

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

View file

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

View file

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

View file

@ -1,11 +0,0 @@
#! /bin/bash
testTry() {
assertEquals 1 "$(echo 'expr 2 / 2' | try lambda _ . 'ret 0')"
assertEquals 0 "$(echo 'expr 2 / 0' | try lambda _ . 'ret 0')"
assertEquals 2 "$(echo 'expr 2 / 0' | try lambda status . 'ret $status')"
assertEquals 'already up to date' "$(echo 'echo already up to date' | try lambda _ . 'ret error')"
assertEquals 'error exit 1' "$(try λ _ . 'echo "error"; echo exit 1' < <(echo fgit pull) | unlist)"
}
. ./shunit2-init.sh

View file

@ -8,7 +8,8 @@ testTupIfOneElement() {
assertEquals '(1)' $(tup 1)
assertEquals '(")' $(tup '"')
assertEquals "(')" $(tup "'")
assertEquals "(u002c)" $(tup ",")
assertEquals "(,)" $(tup ",")
assertEquals "(,,)" $(tup ",,")
assertEquals "(()" $(tup "(")
assertEquals "())" $(tup ")")
}
@ -19,40 +20,10 @@ testTupHappyPath() {
assertEquals '(a b,c d e,f)' "$(tup 'a b' 'c d e' 'f')"
}
testTupxHappyPath() {
assertEquals '4' $(tup 4 5 1 4 | tupx 1)
assertEquals '5' $(tup 4 5 1 4 | tupx 2)
assertEquals '1' $(tup 4 5 1 4 | tupx 3)
assertEquals '4' $(tup 4 5 1 4 | tupx 4)
}
testTupxIfEmpty() {
assertEquals '' "$(tup '' | tupx 1)"
assertEquals '' "$(tup '' | tupx 5)"
}
testTupxIfZeroIndex() {
assertEquals '' "$(tup 1 3 | tupx 0 2>/dev/null)"
}
testTupxIfSpecialChars() {
assertEquals ',' "$(tup ',' | tupx 1)"
assertEquals '(' "$(tup '(' | tupx 1)"
assertEquals ')' "$(tup ')' | tupx 1)"
assertEquals '()' "$(tup '()' | tupx 1)"
assertEquals '(' "$(tup '(' ')' | tupx 1)"
assertEquals '(' "$(tup '(' '(' | tupx 1)"
assertEquals ')' "$(tup ')' ')' | tupx 1)"
assertEquals ',' "$(tup 'u002c' | tupx 1)"
}
testTupxRange() {
assertEquals '4 5' "$(tup 4 5 1 4 | tupx 1-2 | unlist)"
assertEquals '4 4' "$(tup 4 5 1 4 | tupx 1,4 | unlist)"
assertEquals '4 5 4' "$(tup 4 5 1 4 | tupx 1,2,4 | unlist)"
}
testTupl() {
assertEquals '4' "$(tup 4 5 | tupl)"
assertEquals '4' "$(tup 4 5 6 | tupl)"