view tests/farray-alist.t @ 758:7ead30e3b2f9

farray.sh: Check for typos in local variable names or missing "local" declarations for variables
author Franz Glasner <fzglas.hg@dom66.de>
date Sun, 20 Oct 2024 14:43:50 +0200
parents 33df05108ba1
children 03350d2a2af6
line wrap: on
line source

Basic tests of farray.sh's falist_XXX functions

Shell is /bin/sh.


Setup
=====

  $ set -u
  $ . "${TESTDIR}/testsetup.sh"
  $ _p_datadir="${TESTDIR}/../share/local-bsdtools"
  $ . "${_p_datadir}/farray.sh"


Basic Creation and Destruction
==============================

Create an empty alist

  $ falist_create LIST
Has some initial global variables set
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=0 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='0;0' (re)
  _farr_KV_[a-f0-9]+__=0 (re)
  [1]

  $ falist_length _i LIST
  $ echo "$_i"
  0
  $ test "${_i}" -eq 0
  $ falist_print_length LIST
  0 (no-eol)

  $ falist_istrue LIST
  [1]
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 0

  $ falist_release LIST
  $ ( falist_release LIST )
  ERROR: object `LIST' not created properly: token empty
  [1]

  $ check_no_alist_artifacts

  $ falist_create LIST
  $ falist_clear LIST
  $ falist_istrue LIST
  [1]
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 0
  $ falist_release LIST
  $ ( falist_release LIST )
  ERROR: object `LIST' not created properly: token empty
  [1]
  $ check_no_alist_artifacts


Creation and Destruction with one Item
======================================

Create an alist with one item

  $ falist_create LIST K1 V1
  $ falist_length _i LIST
  $ echo "$_i"
  1
  $ test "${_i}" -eq 1
  $ falist_print_length LIST
  1 (no-eol)

  $ falist_istrue LIST
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  $ falist_release LIST
  $ ( falist_release LIST )
  ERROR: object `LIST' not created properly: token empty
  [1]

  $ check_no_alist_artifacts

One Item that replaces the first item

  $ falist_create LIST K1 V1 K1 "V1 1"
  $ falist_length _i LIST
  $ echo "$_i"
  1
  $ test "${_i}" -eq 1
  $ falist_print_length LIST
  1 (no-eol)

  $ falist_istrue LIST
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1 1'
  $ falist_release LIST
  $ ( falist_release LIST )
  ERROR: object `LIST' not created properly: token empty
  [1]

  $ check_no_alist_artifacts


Creation and Destruction with more Items
========================================

Create an alist with two items

  $ falist_create LIST K1 V1 K2 V2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2'

  $ falist_release LIST

  $ check_no_alist_artifacts

Create with inverse insertion order

  $ falist_create LIST K2 V2 K1 V1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2'
  DEBUG:     `K1' -> `V1'

  $ falist_release LIST

Insert at the beginning


  $ falist_create LIST K2 V2 K1 V1 K0 V0
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 3
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2'
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K0' -> `V0'

Replace: beginning

  $ falist_set $LIST K2 $'V2 \' \\ "$abc'
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 3
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2 ' \ "$abc'
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K0' -> `V0'

Replace: mid

  $ falist_set $LIST K1 'V1 1'
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 3
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2 ' \ "$abc'
  DEBUG:     `K1' -> `V1 1'
  DEBUG:     `K0' -> `V0'

Replace: end

  $ falist_set $LIST K0 'V0 1'
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 3
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2 ' \ "$abc'
  DEBUG:     `K1' -> `V1 1'
  DEBUG:     `K0' -> `V0 1'

Insert in the midele again

  $ falist_set LIST K1-1 'V1-1'
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2 ' \ "$abc'
  DEBUG:     `K1' -> `V1 1'
  DEBUG:     `K0' -> `V0 1'
  DEBUG:     `K1-1' -> `V1-1'

Clear resets to initial values

  $ falist_clear LIST
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=0 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='0;0' (re)
  _farr_KV_[a-f0-9]+__=0 (re)
  [1]

  $ falist_print_length LIST
  0 (no-eol)
  $ falist_release LIST
  $ check_no_alist_artifacts


Clear
=====

  $ falist_create LIST
  $ falist_istrue LIST
  [1]
  $ falist_set LIST K2 V2
  $ falist_istrue LIST
  $ falist_set LIST K1 V1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2'
  DEBUG:     `K1' -> `V1'
  $ falist_length _i LIST
  $ echo "$_i"
  2
  $ falist_print_length LIST
  2 (no-eol)

  $ falist_clear LIST
  $ falist_length _i LIST
  $ echo "$_i"
  0
  $ falist_istrue LIST
  [1]
  $ falist_print_length LIST
  0 (no-eol)

Clear resets to initial values

  $ falist_clear LIST
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=0 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='0;0' (re)
  _farr_KV_[a-f0-9]+__=0 (re)
  [1]
  $ falist_istrue LIST
  [1]
  $ falist_release LIST
  $ falist_istrue LIST
  ERROR: object `LIST' not created properly: token empty
  [1]
  $ check_no_alist_artifacts


Optimized Adding
================

  $ falist_create LIST
  $ falist_add LIST k1 v1
  $ falist_add LIST k2 v2
Would violate order requirements
  $ ( falist_add LIST k0 v0 )
  ERROR: falist_add() would violate key order
  [70]
  $ ( falist_add LIST k2 v2-2 )
  ERROR: falist_add() would violate key order
  [70]
  $ falist_add $LIST k3 $'" 111222333" \\\'444555666 '    # '
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 3
  DEBUG:   the items:
  DEBUG:     `k1' -> `v1'
  DEBUG:     `k2' -> `v2'
  DEBUG:     `k3' -> `" 111222333" \'444555666 '
  $ falist_add $LIST k4 'v4 1' k5 v5
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 5
  DEBUG:   the items:
  DEBUG:     `k1' -> `v1'
  DEBUG:     `k2' -> `v2'
  DEBUG:     `k3' -> `" 111222333" \'444555666 '
  DEBUG:     `k4' -> `v4 1'
  DEBUG:     `k5' -> `v5'
  $ falist_release LIST
  $ check_no_alist_artifacts


Iteration
=========

  $ falist_create LIST
  $ falist_set LIST K1 V1
  $ falist_set LIST K2 "V2 2"
  $ falist_set LIST K3 $'" 111222333" \\\'444555 '    # '

Consistency check of storage cookies

  $ _c="$(falist_cookie_first LIST)"
  $ echo $_c
  1/0;2@[a-f0-9]+ (re)
  $ _cnull="$(falist_cookie_prev "${_c}")"
  $ echo "${_cnull}"
  0/0;0@[a-f0-9]+ (re)
  $ _c2="$(falist_cookie_next "$_c")"
  $ echo "${_c2}"
  2/1;3@[a-f0-9]+ (re)
  $ _c3="$(falist_cookie_prev "${_c2}")"
  $ test "${_c}" = "${_c3}"
  $ _c=$(falist_cookie_last LIST)
  $ echo $_c
  3/2;0@[a-f0-9]+ (re)
  $ _cnull="$(falist_cookie_next "${_c}")"
  $ echo "${_cnull}"
  0/0;0@[a-f0-9]+ (re)

MANUAL (by cookie, forward in insertion order)

  $ _pos="$(falist_cookie_first LIST)"
  > while falist_tryget_item_at _k _v "$_pos"; do
  >   printf $'%s -> `%s\'\\n' "$_k" "$_v"
  >   _pos="$(falist_cookie_next "$_pos")"
  > done
  K1 -> `V1'
  K2 -> `V2 2'
  K3 -> `" 111222333" \'444555 '

MANUAL (by cookie, reversed insertion order)

  $ _pos="$(falist_cookie_last LIST)"
  > while falist_tryget_item_at _k _v "$_pos"; do
  >   printf $'`%s\' <- %s\\n' "$_v" "$_k"
  >   _pos="$(falist_cookie_prev "$_pos")"
  > done
  `" 111222333" \'444555 ' <- K3
  `V2 2' <- K2
  `V1' <- K1

MANUAL values (by cookie, forward in insertion order)

  $ _pos="$(falist_cookie_first LIST)"
  > while falist_tryget_value_at _v "$_pos"; do
  >   printf $'`%s\'\\n' "$_v"
  >   _pos="$(falist_cookie_next "$_pos")"
  > done
  `V1'
  `V2 2'
  `" 111222333" \'444555 '


MANUAL keys (by cookie, reversed insertion order)

  $ _pos="$(falist_cookie_last LIST)"
  > while falist_tryget_key_at _k "$_pos"; do
  >   printf '%s\n' "$_k"
  >   _pos="$(falist_cookie_prev "$_pos")"
  > done
  K3
  K2
  K1

ITERATE (for each, by name)

  $ falist_for_each LIST $'printf "EACH: %s key \\`%s\\\', value \\`%s\\\' at cookie %s\\n"'   # `
  EACH: LIST key `K1', value `V1' at cookie 1/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  EACH: LIST key `K2', value `V2 2' at cookie 2/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  EACH: LIST key `K3', value `" 111222333" \\'444555 ' at cookie 3/[0-9]+;[0-9]+@[a-f0-9]+ (re)

ITERATE (for each, by value)

  $ falist_for_each "$LIST" $'printf "EACH: %s key \\`%s\\\', value \\`%s\\\' at cookie %s\\n"'   # `
  EACH: _farr_KV\[\?,\?\]:[a-f0-9]+ key `K1', value `V1' at cookie 1/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  EACH: _farr_KV\[\?,\?\]:[a-f0-9]+ key `K2', value `V2 2' at cookie 2/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  EACH: _farr_KV\[\?,\?\]:[a-f0-9]+ key `K3', value `" 111222333" \\'444555 ' at cookie 3/[0-9]+;[0-9]+@[a-f0-9]+ (re)

  $ falist_clear LIST

  $ falist_release LIST
  $ falist_release LIST
  ERROR: object `LIST' not created properly: token empty
  [1]
  $ check_no_alist_artifacts


Deleting
========

  $ falist_create LIST
  $ (falist_trydel LIST foo)
  [1]

  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1
  $ (falist_trydel LIST foo)
  [1]
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  $ falist_istrue LIST
  $ falist_trydel LIST K1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 0
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=0 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='0;0' (re)
  _farr_KV_[a-f0-9]+__=0 (re)
  [1]
  $ (falist_istrue LIST)
  [1]
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2'
  $ falist_trydel LIST K2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 0
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  $ falist_trydel LIST K1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 0
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2 K3 V3
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2'
  DEBUG:     `K3' -> `V3'
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2 K3 V3
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K3' -> `V3'
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2 K3 V3
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K3
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2'
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2 K3 V3
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K2
  $ falist_trydel LIST K1
  $ falist_trydel LIST K3
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 0
Check that the binary search list is cleaned up
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=0 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='0;0' (re)
  _farr_KV_[a-f0-9]+__=0 (re)
  [1]
  $ falist_release LIST
  $ check_no_alist_artifacts

  $ falist_create LIST K1 V1 K2 V2 K3 V3
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K2
Skipping tombstones
  $ (falist_trydel LIST K2)
  [1]
  $ falist_trydel LIST K3
  $ (falist_trydel LIST K3)
  [1]
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
Check that the binary search list is cleaned up properly: just the first
storage entries are left
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=1 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='1;1' (re)
  _farr_KV_[a-f0-9]+__=1 (re)
  _farr_Kb_[a-f0-9]+_1='1;V@K1' (re)
  _farr_Ks_[a-f0-9]+_1='0;0@K1' (re)
  _farr_Vs_[a-f0-9]+_1=V1 (re)
  [1]
Can re-add K2 now again
  $ falist_add LIST K2 'V2 2'
  $ falist_release LIST
  $ check_no_alist_artifacts

Try this with reversed insertion order also

  $ falist_create LIST K3 V3 K2 V2 K1 V1
  $ falist_find _var LIST K3
Cookie has structure <storage-ptr>/<storage-prev-ptr>;<storage-next-ptr>@<object-token>
  $ echo "$_var"
  1/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  $ falist_contains LIST K3
  $ falist_find _var LIST K2
  $ echo "$_var"
  2/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  $ falist_contains LIST K2
  $ falist_find _var LIST K1
  $ echo "$_var"
  3/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  $ falist_contains LIST K1
  $ (falist_trydel LIST foo)
  [1]
  $ falist_trydel LIST K2
Skipping tombstones
  $ (falist_trydel LIST K2)
  [1]
  $ falist_trydel LIST K3
  $ (falist_trydel LIST K3)
  [1]
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
Check that the binary search list is cleaned up properly: just the first
storage entries are left
  $ check_no_alist_artifacts
  _farr_KV_[a-f0-9]+_B=1 (re)
  _farr_KV_[a-f0-9]+_C=1 (re)
  _farr_KV_[a-f0-9]+_P='3;3' (re)
  _farr_KV_[a-f0-9]+__=1 (re)
  _farr_Kb_[a-f0-9]+_1='3;V@K1' (re)
  _farr_Ks_[a-f0-9]+_3='0;0@K1' (re)
  _farr_Vs_[a-f0-9]+_3=V1 (re)
  [1]
Can re-add K2 now again
  $ falist_add LIST K2 'V2 2'
  $ falist_find _var LIST K2
  $ falist_contains LIST K2
But K3 is tombstoned/deleted
  $ (falist_find _var LIST K3)
  [1]
  $ (falist_contains LIST K3)
  [1]
  $ farray_create ARRAY
  $ falist_keys ARRAY LIST
  $ farray_debug ARRAY
  DEBUG: array `ARRAY' has length 2
  DEBUG:   the items:
  DEBUG:     1: `K1'
  DEBUG:     2: `K2'
  $ farray_release ARRAY
  $ farray_create ARRAY
  $ falist_values ARRAY LIST
  $ farray_debug ARRAY
  DEBUG: array `ARRAY' has length 2
  DEBUG:   the items:
  DEBUG:     1: `V1'
  DEBUG:     2: `V2 2'
  $ farray_release ARRAY
  $ farray_create ARRAY
  $ falist_items ARRAY LIST
  $ farray_debug ARRAY
  DEBUG: array `ARRAY' has length 4
  DEBUG:   the items:
  DEBUG:     1: `K1'
  DEBUG:     2: `V1'
  DEBUG:     3: `K2'
  DEBUG:     4: `V2 2'
  $ farray_release ARRAY
  $ falist_release LIST
  $ check_no_alist_artifacts
  $ check_no_array_artifacts


Get / Set / Contains / Find Index
=================================

  $ falist_create LIST
  $ falist_set LIST K1 V1
  $ falist_set LIST K2 V2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2'
  $ falist_length _i LIST
  $ echo "$_i"
  2
  $ falist_print_length LIST
  2 (no-eol)

  $ falist_set LIST K2 "V2 2"
  $ falist_set_unique LIST K2 "V2 duplicate"
  [1]
  $ falist_set LIST K3 $'" 111222333" \\\'444555 '    # '
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 3
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2 2'
  DEBUG:     `K3' -> `" 111222333" \'444555 '
  $ falist_length _i LIST
  $ echo "$_i"
  3
  $ falist_print_length LIST
  3 (no-eol)

  $ falist_contains LIST K1
  $ falist_find cookie LIST K1
  $ echo "$cookie"
  1/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  $ falist_contains LIST K
  [1]
  $ falist_find cookie LIST K
  [1]
  $ falist_get _var LIST K2
  $ echo "$_var"
  V2 2
  $ falist_tryget _var LIST K1
  $ echo "$_var"
  V1
  $ falist_tryget _i LIST K
  [1]

  $ falist_get _var LIST K2 _cookie
  $ echo "$_var"
  V2 2
  $ echo "$_cookie"
  2/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  $ falist_tryget _var LIST K1 _cookie
  $ echo "$_var"
  V1
  $ echo "$_cookie"
  1/[0-9]+;[0-9]+@[a-f0-9]+ (re)
  $ falist_tryget _i LIST K _cookie
  [1]
  $ _var="$(falist_print_length NON_EXISTING_LIST)"
  ERROR: object `NON_EXISTING_LIST' not created properly: token empty
  $ echo "${_var}"
  -1
  $ falist_set_unique LIST K4 "V4"
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2 2'
  DEBUG:     `K3' -> `" 111222333" \'444555 '
  DEBUG:     `K4' -> `V4'
  $ falist_release LIST
  $ check_no_alist_artifacts


Items / Keys / Values
=====================

  $ farray_create KEYS
  $ farray_create VALUES
  $ farray_create ITEMS
  $ falist_create LIST "Key 1" "Value 1" "Key 2" 'Value 2 '\'''
  $ falist_items ITEMS LIST
  $ farray_debug ITEMS
  DEBUG: array `ITEMS' has length 4
  DEBUG:   the items:
  DEBUG:     1: `Key 1'
  DEBUG:     2: `Value 1'
  DEBUG:     3: `Key 2'
  DEBUG:     4: `Value 2 ''
  $ falist_keys KEYS LIST
  $ farray_debug KEYS
  DEBUG: array `KEYS' has length 2
  DEBUG:   the items:
  DEBUG:     1: `Key 1'
  DEBUG:     2: `Key 2'
  $ falist_values VALUES LIST
  $ farray_debug VALUES
  DEBUG: array `VALUES' has length 2
  DEBUG:   the items:
  DEBUG:     1: `Value 1'
  DEBUG:     2: `Value 2 ''

  $ falist_release LIST
  $ farray_release KEYS
  $ farray_release VALUES
  $ farray_release ITEMS

  $ check_no_alist_artifacts


Compare
=======

  $ falist_create LIST1 K1 V1 K2 V2
  $ falist_debug LIST1
  DEBUG: alist `LIST1' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2'

  $ falist_create LIST2 K2 V2 K1 V1
  $ falist_debug LIST2
  DEBUG: alist `LIST2' has length 2
  DEBUG:   the items:
  DEBUG:     `K2' -> `V2'
  DEBUG:     `K1' -> `V1'

  $ falist_create LIST3 K1 V1 K2 V2
  $ falist_debug LIST3
  DEBUG: alist `LIST3' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2'

  $ falist_create LIST4 K1 V1 K2 V2-4
  $ falist_debug LIST4
  DEBUG: alist `LIST4' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2-4'

  $ falist_are_equal LIST1 LIST2
  $ falist_are_equal LIST1 LIST4
  [1]
  $ falist_are_equal_with_order LIST1 LIST2
  [1]
  $ falist_are_equal_with_order LIST1 LIST3

  $ falist_clear LIST2
  $ falist_are_equal LIST1 LIST2
  [1]

  $ falist_clear LIST3
  $ falist_are_equal_with_order LIST2 LIST3

  $ falist_release LIST1
  $ falist_release LIST2
  $ falist_release LIST3
  $ falist_release LIST4

  $ check_no_alist_artifacts


Updating
========

Just replace existing items

  $ falist_create LIST k2 v2 k4 v4 k6 v6 k8 v8
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `k2' -> `v2'
  DEBUG:     `k4' -> `v4'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8'

  $ falist_create UPDATE1 k2 v2-2 k4 v4-2 k8 v8-2
  $ falist_update LIST UPDATE1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `k2' -> `v2-2'
  DEBUG:     `k4' -> `v4-2'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8-2'

  $ falist_release LIST
  $ falist_release UPDATE1
  $ check_no_alist_artifacts


Handle previously deleted items also

  $ falist_create LIST k2 v2 k4 v4 k6 v6 k8 v8
  $ falist_trydel LIST k2
  $ falist_create UPDATE1 k2 v2-2 k4 v4-2 k8 v8-2
  $ falist_update LIST UPDATE1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `k4' -> `v4-2'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8-2'
  DEBUG:     `k2' -> `v2-2'

  $ falist_release LIST
  $ falist_release UPDATE1
  $ check_no_alist_artifacts

  $ falist_create LIST k2 v2 k4 v4 k6 v6 k8 v8
  $ falist_trydel LIST k4
  $ falist_create UPDATE1 k2 v2-2 k4 v4-2 k8 v8-2
  $ falist_update LIST UPDATE1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `k2' -> `v2-2'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8-2'
  DEBUG:     `k4' -> `v4-2'

  $ falist_release LIST
  $ falist_release UPDATE1
  $ check_no_alist_artifacts


Just appending

  $ falist_create LIST k2 v2 k4 v4 k6 v6 k8 v8
  $ falist_create UPDATE1 k9 v9 k91 v91
  $ falist_update LIST UPDATE1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 6
  DEBUG:   the items:
  DEBUG:     `k2' -> `v2'
  DEBUG:     `k4' -> `v4'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8'
  DEBUG:     `k9' -> `v9'
  DEBUG:     `k91' -> `v91'

  $ falist_release LIST
  $ falist_release UPDATE1
  $ check_no_alist_artifacts


Append after deletion

  $ falist_create LIST k2 v2 k4 v4 k6 v6 k8 v8
  $ falist_trydel LIST k8
  $ falist_create UPDATE1 k2 v2-2 k4 v4-2 k8 v8-2
  $ falist_update LIST UPDATE1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 4
  DEBUG:   the items:
  DEBUG:     `k2' -> `v2-2'
  DEBUG:     `k4' -> `v4-2'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8-2'

  $ falist_release LIST
  $ falist_release UPDATE1
  $ check_no_alist_artifacts

Insertions

  $ falist_create LIST k2 v2 k4 v4 k6 v6 k8 v8
  $ falist_create UPDATE1 k1 v1 k3 v3 k7 v7
  $ falist_update LIST UPDATE1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 7
  DEBUG:   the items:
  DEBUG:     `k2' -> `v2'
  DEBUG:     `k4' -> `v4'
  DEBUG:     `k6' -> `v6'
  DEBUG:     `k8' -> `v8'
  DEBUG:     `k1' -> `v1'
  DEBUG:     `k3' -> `v3'
  DEBUG:     `k7' -> `v7'

  $ falist_release LIST
  $ falist_release UPDATE1
  $ check_no_alist_artifacts


Cross Type Checks
=================

  $ falist_create LIST
  $ (farray_append LIST value)
  ERROR: object `LIST' is not an array
  [70]
  $ falist_release LIST
  $ check_no_alist_artifacts


Other Type Checks
=================

  $ falist_type
  unknown (no-eol)
  $ falist_type __UNKNOWN_VARIABLE__
  unknown (no-eol)
  $ testvar='foo'
  $ falist_type testvar
  value (no-eol)
  $ testvar=''
  $ falist_type testvar
  null (no-eol)
  $ falist_isalist testvar
  [1]
  $ falist_create LIST
  $ falist_type LIST
  alist (no-eol)
  $ falist_isalist LIST
  $ falist_release LIST
  $ check_no_alist_artifacts


Generic Destruction
===================

  $ falist_create LIST k1 v2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 1
  DEBUG:   the items:
  DEBUG:     `k1' -> `v2'
  $ _farr_release_object "$LIST"
  $ check_no_alist_artifacts
  $ (_farr_release_object "$LIST")
  ERROR: falist `_farr_KV\[\?,\?\]:([a-f0-9]+)' not created properly: no object for token `\1' (re)
  [1]
  $ LIST=''
  $ _farr_release_object "$LIST"
  $ check_no_alist_artifacts


Complex Debug
=============

  $ falist_create LIST
  $ falist_set LIST K1 V1
  $ falist_create ITEM1 K11 V11 K22 V22
  $ falist_set LIST K2 "$ITEM1"
  $ falist_release ITEM1
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:   the items:
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> >>>
      DEBUG: alist with token `[a-f0-9]+' has length 2 (re)
      DEBUG:   the items:
      DEBUG:     `K11' -> `V11'
      DEBUG:     `K22' -> `V22'
  $ falist_release LIST
  $ check_no_alist_artifacts


No Locals
=========

  $ check_no_local_artifacts