view tests/farray-alist.t @ 723:a97ec3f07bdb

farray.sh: REFACTOR: More flexible metadata retrieval. Using an array or alist variable name or token value (with prefix) is now supported in every function. This is possible because the value prefixes contain questin marks (?) which are not allowed in shell variable names. This again is a major precondition for recursive data structures (arrays/alists in arrays/alists).
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 05 Oct 2024 21:55:55 +0200
parents b2757e72b517
children 3adb26525b19
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
  $ 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_destroy LIST
  $ ( falist_destroy LIST )
  ERROR: object `LIST' not created properly: token empty
  [1]

  $ check_no_alist_artifacts


Clear
=====

  $ falist_create LIST
  $ falist_istrue LIST
  [1]
  $ falist_set LIST K1 V1
  $ falist_istrue LIST
  $ falist_set LIST K2 V2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2'
  $ 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)

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


Get / Set / Contains
====================

  $ falist_create LIST
  $ falist_set LIST K1 V1
  $ falist_set LIST K2 V2
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  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:     `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_contains 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]
  $ _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:     `K1' -> `V1'
  DEBUG:     `K2' -> `V2 2'
  DEBUG:     `K3' -> `" 111222333" \'444555 '
  DEBUG:     `K4' -> `V4'
  $ falist_destroy LIST
  $ check_no_alist_artifacts


Iteration
=========

ITERATE (manual indexing)

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

Iteration by indexing key and values separately

  $ _i=1
  > while falist_tryget_key_at_index _k LIST ${_i}; do
  >     # cannot fail under "normal" circumstances
  >     falist_tryget_value_at_index _v LIST ${_i}
  >     printf "  KEY: \`%s', VAL: \`%s'\\n" "${_k}" "${_v}"
  >     _i=$((_i + 1))
  > done
    KEY: `K1', VAL: `V1'
    KEY: `K2', VAL: `V2 2'
    KEY: `K3', VAL: `" 111222333" \'444555 '

ITERATE (manual indexing over items)

  $ _i=1
  > while falist_tryget_item_at_index _k _v LIST ${_i}; do
  >     printf "  KEY: \`%s', VAL: \`%s'\\n" "${_k}" "${_v}"
  >     _i=$((_i + 1))
  > done
    KEY: `K1', VAL: `V1'
    KEY: `K2', VAL: `V2 2'
    KEY: `K3', VAL: `" 111222333" \'444555 '

ITERATE (for each, by name)

  $ falist_for_each LIST $'printf "EACH: %s key \\`%s\\\', value \\`%s\\\' at idx %d\\n"'   # `
  EACH: LIST key `K1', value `V1' at idx 1
  EACH: LIST key `K2', value `V2 2' at idx 2
  EACH: LIST key `K3', value `" 111222333" \'444555 ' at idx 3

ITERATE (for each, by value)

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

  $ falist_clear LIST
  $ falist_destroy LIST
  $ falist_destroy LIST
  ERROR: object `LIST' not created properly: token empty
  [1]

  $ check_no_alist_artifacts


Valid and Invalid Indices

  $ falist_create LIST
  $ falist_set LIST 'KEY 1' 'VAL 1'
  $ falist_set LIST 'KEY 2' 'VAL 2'
  $ falist_set LIST 'KEY 3' 'VAL 3'

  $ (falist_tryget_item_at_index _k _v LIST "")
  ERROR: missing index
  [70]

  $ (falist_tryget_item_at_index _k _v LIST)
  ERROR: missing index
  [70]

  $ falist_tryget_item_at_index _k _v LIST 4
  [1]

  $ falist_tryget_item_at_index _k _v LIST 0
  $ printf '%s:%s' "$_k" "$_v"
  KEY 3:VAL 3 (no-eol)

  $ falist_tryget_item_at_index _k _v LIST -2
  $ printf '%s:%s' "$_k" "$_v"
  KEY 1:VAL 1 (no-eol)

  $ falist_tryget_item_at_index _k _v LIST -3
  [1]

  $ falist_destroy LIST
  $ check_no_alist_artifacts


Deletion of keys
================

  $ falist_create LIST
  $ falist_set LIST 'key 1' 'value 1'
  $ falist_set LIST 'key 2' 'value 2'
  $ falist_set LIST 'key 3' 'value 3'
  $ falist_set LIST 'key 4' 'value 4'
  $ falist_set LIST 'key 5' 'value 5'
  $ falist_trydel LIST 'key 1'
  $ falist_trydel LIST 'key 5'
  $ falist_trydel LIST 'key 3'
  $ falist_debug LIST
  DEBUG: alist `LIST' has length 2
  DEBUG:     `key 2' -> `value 2'
  DEBUG:     `key 4' -> `value 4'
  $ falist_trydel LIST "non-existing key"
  [1]
  $ falist_print_length LIST
  2 (no-eol)
  $ falist_get _var LIST 'key 2'
  $ printf '%s' "$_var"
  value 2 (no-eol)
  $ falist_get _var LIST 'key 4'
  $ printf '%s' "$_var"
  value 4 (no-eol)

  $ falist_destroy LIST

  $ check_no_alist_artifacts


Compare
=======

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

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

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

  $ falist_create LIST4 K1 V1 K2 V2-4
  $ falist_debug LIST4
  DEBUG: alist `LIST4' has length 2
  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_destroy LIST1
  $ falist_destroy LIST2
  $ falist_destroy LIST3
  $ falist_destroy LIST4

  $ check_no_alist_artifacts


Updating
========

  $ falist_create ARR "Key 1" "Value 1" "Key 2" 'Value 2 '\'''
  $ falist_create UPDATE1 "Key 1" "Value 1" "Key 2" 'Value 2 '\'''
  $ falist_create UPDATE2 "Key 2" 'Value 2 (Updated) '\''' "Key 3" "Value 3"
  $ falist_create EMPTY

  $ falist_are_equal_with_order ARR UPDATE1
  $ falist_are_equal_with_order ARR UPDATE2
  [1]

  $ falist_update ARR UPDATE1
  $ falist_are_equal_with_order ARR UPDATE1

  $ falist_update ARR UPDATE2
  $ falist_debug ARR
  DEBUG: alist `ARR' has length 3
  DEBUG:     `Key 1' -> `Value 1'
  DEBUG:     `Key 2' -> `Value 2 (Updated) ''
  DEBUG:     `Key 3' -> `Value 3'

Updating an into an empty alist is just a copy

  $ falist_update EMPTY UPDATE1
  $ falist_debug EMPTY
  DEBUG: alist `EMPTY' has length 2
  DEBUG:     `Key 1' -> `Value 1'
  DEBUG:     `Key 2' -> `Value 2 ''
  $ falist_debug UPDATE1
  DEBUG: alist `UPDATE1' has length 2
  DEBUG:     `Key 1' -> `Value 1'
  DEBUG:     `Key 2' -> `Value 2 ''

  $ falist_destroy ARR
  $ falist_destroy UPDATE1
  $ falist_destroy UPDATE2
  $ falist_destroy EMPTY

  $ 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:   its contents:
  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:   its contents:
  DEBUG:     1: `Key 1'
  DEBUG:     2: `Key 2'
  $ falist_values VALUES LIST
  $ farray_debug VALUES
  DEBUG: array `VALUES' has length 2
  DEBUG:   its contents:
  DEBUG:     1: `Value 1'
  DEBUG:     2: `Value 2 ''

  $ falist_destroy LIST
  $ farray_destroy KEYS
  $ farray_destroy VALUES
  $ farray_destroy ITEMS

  $ check_no_alist_artifacts


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

  $ falist_create LIST
  $ (farray_append LIST value)
  ERROR: object `LIST' is not an array
  [70]
  $ falist_destroy 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_destroy LIST
  $ check_no_alist_artifacts


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

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