TESTS: remove unsuitable test case of bitset

Red [
	Title:   "Red series test script"
	Author:  "Nenad Rakocevic & Peter W A Wood"
	File: 	 %series-test.red
	Tabs:	 4
	Rights:  "Copyright (C) 2011-2015 Nenad Rakocevic & Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt"
]

#include  %../../../quick-test/quick-test.red

~~~start-file~~~ "series"

===start-group=== "first, second, third, fourth, fifth"

	--test-- "series-fstff-1"
	  sf1-ser:  [1 2 3 4 5]
	--assert 1 = first sf1-ser
	--assert 2 = second sf1-ser
	--assert 3 = third sf1-ser
	--assert 4 = fourth sf1-ser
	--assert 5 = fifth sf1-ser
	--assert 5 = last sf1-ser

	--test-- "series-fstff-2"
	  sf2-ser:  [1 2 3 4 5]
	--assert 2 = first next sf2-ser

	--test-- "series-fstff-3"
	  sf3-ser:  "12345"
	--assert 49 = first sf3-ser
	--assert 53 = last sf3-ser

	--test-- "series-fstff-4"
	  sf4-ser:  [1 2 3 4 5]
	--assert none = fifth next sf4-ser

	--test-- "series-fstff-5"
	  sf5-ser:  "12345"
	--assert 53 = fifth sf5-ser

	--test-- "series-fstff-6"
	;;  stf6-ser: #{000102}
	;;--assert 0 = first stf6-ser

	--test-- "series-fstff-7"
	--assert 'a = first [a b c d]

	--test-- "series-fstff-8"
	--assert 'a = first first first first first first first first first [[[[[[[[[a]]]]]]]]]

	--test-- "series-fstff-9"
	--assert #"^(00)" = first "^(00)"

	--test-- "series-fstff-10"
	--assert #"^(00)" = first "^(00)a"

	--test-- "series-fstff-11"
	--assert #"^(00)" = second "a^(00)"

	--test-- "series-fstff-12"
	--assert #"^(00)" = second "a^(00)b"

	--test-- "series-fstff-13"
	sf6-ser: make hash! [a b]
	--assert 'a = first sf6-ser
	--assert 'b = last sf6-ser

	--test-- "series-fstff-14"
	sf7-ser: make hash! [1 2 3]
	--assert 2 = first next sf7-ser
	--assert none = fifth next sf7-ser

===end-group===

===start-group=== "next"
  --test-- "series-next-1"
  --assert 2 = first next [1 2 3 4 5]
  --test-- "series-next-2"
  --assert 3 = first next next [1 2 3 4 5]
  --test-- "series-next-3"
  --assert 4 = first next next next [1 2 3 4 5]
  --test-- "series-next-4"
  --assert 5 = first next next next next [1 2 3 4 5]
  --test-- "series-next-5"
  --assert none = first next next next next next [1 2 3 4 5]
  --test-- "series-next-6"
  --assert 50 = first next "12345"
  --test-- "series-next-7"
  --assert 51 = first next next "12345"
  --test-- "series-next-8"
  --assert 52 = first next next next "12345"
  --test-- "series-next-9"
  --assert 53 = first next next next next "12345"
  --test-- "series-next-10"
  --assert none = first next next next next next "12345"
  --test-- "series-next-11"
  --assert #"^(00)" = first next "a^(00)"
  --test-- "series-next-12"
  --assert #"^(00)" = first next "a^(00)b"
===end-group===

===start-group=== "back"
  --test-- "series-back-1"
  --assert 1 = first back next [1 2 3 4 5]
  --test-- "series-back-2"
  --assert 1 = first back back next next [1 2 3 4 5]
  --test-- "series-back-3"
  --assert 1 = first back back back next next next [1 2 3 4 5]
  --test-- "series-back-4"
  --assert 1 = first back back back back next next next next [1 2 3 4 5]
  --test-- "series-back-5"
  --assert 1 = first back back back back back next next next next next [1 2 3 4 5]
  --test-- "series-back-6"
  --assert 49 = first back next "12345"
  --test-- "series-back-7"
  --assert 50 = first back next next "12345"
  --test-- "series-back-8"
  --assert 51 = first back next next next "12345"
  --test-- "series-back-9"
  --assert 52 = first back next next next next "12345"
  --test-- "series-back-10"
  --assert 53 = first back next next next next next "12345"
  --test-- "series-back-11"
  --assert 49 = first back "12345"
  --test-- "series-back-12"
  --assert 1 = first back next make hash! [1 2 3 4 5]
===end-group===

===start-group=== "tail"
  --test-- "series-tail-1"
  --assert 5 = first back tail [1 2 3 4 5]
  --test-- "seried-tail-2"
  --assert none = pick tail [1 2 3 4 5] 1
  --test-- "series-tail-3"
  hs-ser-1: make hash! [1 2 3 4 5]
  --assert 5 = first back tail hs-ser-1
  --test-- "seried-tail-4"
  hs-ser-2: make hash! [1 2 3 4 5]
  --assert none = pick tail hs-ser-2 1
===end-group===

===start-group=== "pick"

  --test-- "series-pick-1"
  --assert none = pick "" 1

  --test-- "series-pick-2"
  --assert none = pick "" 0

  --test-- "series-pick-3"
  --assert none = pick "" 2

  --test-- "series-pick-4"
  --assert 49 = pick "12345" 1

  --test-- "series-pick-5"
  --assert 53 = pick "12345" 5

  --test-- "series-pick-6"
  --assert 1 = pick [1 2 3 4 5] 1

  --test-- "series-pick-7"
  --assert 2 = pick [1 2 3 4 5] 2

  --test-- "series-pick-8"
  --assert 4 = pick [1 2 3 4 5] 4

  --test-- "series-pick-9"
  --assert 5 = pick [1 2 3 4 5] 5

  --test-- "series-pick-10"
  --assert 2 = pick next next next [1 2 3 4 5] -2

  --test-- "series-pick-11"
  --assert 3 = pick next next next [1 2 3 4 5] -1

  --test-- "series-pick-12"
  --assert none = pick next next next [1 2 3 4 5] 0

  --test-- "series-pick-13"
  --assert none = pick "12345" -1

  --test-- "series-pick-14"
    sp14-i: 1
  --assert 1 = pick [1 2 3 4 5] sp14-i

  --test-- "series-pick-15"
    sp15-i: 4
  --assert 4 = pick [1 2 3 4 5] sp15-i

  --test-- "series-pick-16"
    sp16-i: -2
  --assert 2 = pick next next next [1 2 3 4 5] sp16-i

  --test-- "series-pick-17"
    sp17-i: 0
  --assert none = pick next next next [1 2 3 4 5] sp17-i

  --test-- "series-pick-18"
    sp18-i: -1
  --assert none = pick "12345" sp18-i

  --test-- "series-pick-19"
  --assert 5 = pick make hash! [1 2 3 4 5] 5

  --test-- "series-pick-20"
  --assert 2 = pick next next next make hash! [1 2 3 4 5] -2
===end-group===

===start-group=== "select"
	--test-- "series-select-1"
		--assert 2 = select [1 2 3 4 5] 1
	--test-- "series-select-2"
		--assert 5 = select [1 2 3 4 5] 4
	--test-- "series-select-3"
		--assert none = select [1 2 3 4 5] 0
	--test-- "series-select-4"
		--assert none = select [1 2 3 4 5] 5

	--test-- "series-select-5"
		a: [2 3 5 test #"A" a/b 5 "tesT"]
		--assert #"A" = select a 'test

	--test-- "series-select-6"
		list: [a 1 b 2 c 3]
		--assert 2 = list/b

	--test-- "series-select-6"
		--assert 'test = select/skip a 5 2

	--test-- "series-select-7"
		s: "Hello, Red World!"
		--assert #"e" = select s #"r"

	--test-- "series-select-8"
		--assert #"l" = select/last s #"r"

	--test-- "series-select-9"
		--assert #"d" = select/skip s "e" 2

	--test-- "series-select-10"
		--assert none? select s #"!"

	--test-- "series-select-11"
		--assert 5 = select make hash! [1 2 3 4 5] 4

	--test-- "series-select-12"
		hs-sel-1: make hash! [2 3 5 test #"A" a/b 5 "tesT"]
		--assert #"A" = select hs-sel-1 'test

	--test-- "series-select-13"
		list: make hash! [a 1 b 2 c 3]
		--assert 2 = list/b

	--test-- "series-select-14"
		--assert 'test = select/skip hs-sel-1 5 2

	--test-- "series-select-15"
		hs-select-1: make hash! [aBc 1 abc 2 ABc 3]
		--assert 1 = select hs-select-1 'abc
		--assert 2 = select/case hs-select-1 'abc
===end-group===

===start-group=== "append"
  --test-- "series-append-1"
  --assert 6 = last append [1 2 3 4 5] 6
  --test-- "series-append-2"
  --assert 6 = last append [1 2 3 4] [5 6]
  --assert 4 = fourth append [1 2 3 4] [5 6]
  --assert 5 = fifth append [1 2 3 4] [5 6]
  --test-- "series-append-3"
  --assert 55 = last append "12345" "67"
  --test-- "series-append-4"
  --assert 233 = last append "abcde" "é" ;; utf-8 C3 A9
  --test-- "series-append-5"
  --assert 49 = last append "abcdeé" "1" ;; utf-8 C3 A9
  --test-- "series-append-6"
  --assert 10000 = last append "abcde" "✐"
  --test-- "series-append-7"
  --assert 48 = last append "abcde^(2710)" "0"
  --test-- "series-append-8"
  --assert 10000 = last append "abcdeé" "^(2710)"
  --test-- "series-append-9"
  --assert 233 = last append "abcde^(2710)" "é"
  --test-- "series-append-10"
  --assert 65536 = last append "abcde" "^(010000)"
  --test-- "series-append-11"
  --assert 48 = last append "abcde^(010000)" "0"
  --test-- "series-append-12"
  --assert 65536 = last append "abcde^(2710)é" "^(010000)"

  --test-- "series-append-13"
	blk: make block! 1
	append blk 'x/y
	append/only blk  'r/s
	--assert "[x y r/s]" = mold blk

  --test-- "series-append-14"
	blk: [1 2]
	append/dup/part blk [4 5 6] 3 2
	--assert "[1 2 4 5 4 5 4 5]" = mold blk

  --test-- "series-append-15"
	blk: [1 2]
	append/dup/part blk [4 5 6] 2 3
	--assert "[1 2 4 5 6 4 5 6]" = mold blk

  --test-- "series-append-16"
	str: "12"
	append/dup/part str "456" 3 2
	--assert str = "12454545"

  --test-- "series-append-17"
	str: "12"
	append/part/dup str "456" 3 2
	--assert str = "12456456"

  --test-- "series-append-18"
  hs-append-1: make hash! [a 1 b 2]
  --assert 6 = last append hs-append-1 [c 6]
  --assert 6 = select hs-append-1 'c
===end-group===

===start-group=== "series-equal"

  --test-- "series-equal-1"
  --assert [] = []

  --test-- "series-equal-2"
    se2-b: []
  --assert [] = se2-b

  --test-- "series-equal-3"
    se3-b: []
  --assert se3-b = []

  --test-- "series-equal-4"
    se4-b: [1]
  --assert se4-b = [1]

  --test-- "series-equal-5"
    se5-b: ["abcde"]
  --assert se5-b = ["abcde"]

===end-group===

===start-group=== "series-find"

  --test-- "series-find-1"
  --assert 3 = first find [1 2 3 4 5] 3

  --test-- "series-find-2"
  --assert 'a = first find [a b c d e] 'a

  --test-- "series-find-3"
  --assert 'e = first find [a b c d e] 'e

  --test-- "series-find-4"
  --assert none = find [] 'a

  --test-- "series-find-5"
  --assert none = find [1 2 3 4] 'a

  --test-- "series-find-6"
  --assert none = find next [a b c d e] 'a

  --test-- "series-find-7"
  --assert 51 = first find "12345" "3"

  --test-- "series-find-8"
  --assert 51 = first find "12345" "^(33)"

  --test-- "series-find-9"
  --assert 51 = first find "12345" first "^(33)"

  --test-- "series-find-10"
  --assert 51 = first find "12345" #"3"

  --test-- "series-find-11"
  --assert 51 = first find "12345" #"^(33)"

  --test-- "series-find-12"
  --assert #"3" = first find "12345" #"3"

  --test-- "series-find-13"
  --assert #"a" = first find "abcdefghijklmno" #"a"

  --test-- "series-find-14"
  --assert "ghijklmno" = find "abcdefghijklmno" "ghij"

  --test-- "series-find-15"
  --assert #"o" = first find "abcdefghijklmno" #"o"

  --test-- "series-find-16"
  --assert "o" = find "abcdefghijklmno" #"o"

  --test-- "series-find-17"
  --assert #"o" = first find "abcdefghijklmno" "o"

  --test-- "series-find-18"
  --assert "o" = find "abcdefghijklmno" "o"

  --test-- "series-find-19"
  --assert none = find "" #"a"

  --test-- "series-find-20"
  --assert none = find "" #"^(00)"

  --test-- "series-find-21"
  --assert none = find "" ""

  --test-- "series-find-22"
  --assert "^(00)" = find "^(00)" "^(00)"

  --test-- "series-find-23"
  --assert "a^(00)" = find "a^(00)" "a^(00)"

  --test-- "series-find-24"
  --assert "^(00)a" = find "^(00)a" "^(00)a"

  --test-- "series-find-25"
  --assert "^(00)" = find "^(00)" #"^(00)"

  --test-- "series-find-26"
  --assert #"^(00)" = first find "^(00)" #"^(00)"

  --test-- "series-find-27"
  --assert #"é" = first find "abcdeé" #"é"

  --test-- "series-find-28"
  --assert "é" = find "abcdeé" "é"

  --test-- "series-find-29"
  --assert "é" = find append "abcde" "é" "é"

  --test-- "series-find-30"
  --assert 10000 = first find "abcde✐" "✐"

  --test-- "series-find-30a"
  --assert 10000 = first find "abcde✐" #"✐"

  --test-- "series-find-31"
  --assert none = find "012345" 48

  --test-- "series-find-32"
  --assert "^(010000)" = find "abcde^(2710)é^(010000)" "^(010000)"

  --test-- "series-find-33"
  --assert "^(010000)cde^(2710)é" = find "ab^(010000)cde^(2710)é" #"^(010000)"

  --test-- "series-find-34"
  --assert "^(010000)cde^(2710)é" = find "ab^(010000)cde^(2710)é" "^(010000)"

	--test-- "series-find-35"
		a: [2 3 5 test #"A" a/b 5 "tesT"]
		append a datatype!
		--assert 3 = index? find a 5

	--test-- "series-find-36"
		--assert 8 = index? find a "test"

	--test-- "series-find-37"
		--assert none? find a 99

	--test-- "series-find-38"
		--assert none? find/skip a 'test 2

	--test-- "series-find-39"
		--assert 4 = index? find/skip a 'test 3

	--test-- "series-find-40"
		--assert 7 = index? find/last a 5

	--test-- "series-find-41"
		--assert 2 = index? find/reverse skip a 4 3

	--test-- "series-find-42"
		--assert 8 = index? find skip a 3 "test"

	--test-- "series-find-43"
		--assert none? find/last/part a 3 1

	--test-- "series-find-44"
		--assert 2 = index? find/last/part a 3 2

	--test-- "series-find-45"
		--assert none? find/part a 'test 3

	--test-- "series-find-46"
		--assert 4 = index? find/part a 'test 4

	--test-- "series-find-47"
		--assert 2 = index? find a [3 5]

	--test-- "series-find-48"
		--assert 3 = index? find a [5 'test]

	--test-- "series-find-49"
		--assert none? find a 'a/b

	--test-- "series-find-50"
		--assert 6 = index? find/only a 'a/b

	--test-- "series-find-51"
		--assert 2 = index? find/match a 2

	--test-- "series-find-52"
		--assert none? find/match a 3

	--test-- "series-find-53"
		--assert 4 = index? find/match a [2 3 5]

	--test-- "series-find-54"
		--assert none? find/match next a [2 3 5]

	--test-- "series-find-55"
		--assert 4 = index? find/tail a 5

	--test-- "series-find-56"
		--assert 3 = index? find 'a/b/3/d 3

	--test-- "series-find-57"
		--assert 2 = index? find 'a/b/3/d 'b

	--test-- "series-find-58"
		s: "Hello, Red World!"
		--assert 6 = index? find s ","

	--test-- "series-find-59"
		--assert 8 = index? find s "Red"

	--test-- "series-find-60"
		--assert 8 = index? find s "red"

	--test-- "series-find-61"
		--assert 6 = index? find s #","

	--test-- "series-find-62"
		--assert 1 = index? find "^(00)" "^(00)"

	--test-- "series-find-63"
		--assert 5 = index? find/skip s #"o" 2

	--test-- "series-find-64"
		--assert 13 = index? find/skip s #"o" 3

	--test-- "series-find-65"
		--assert 15 = index? find/last s #"l"

	--test-- "series-find-66"
		--assert 13 = index? find/last s "o"

	--test-- "series-find-67"
		--assert none? find/part s #"o" 4

	--test-- "series-find-68"
		--assert 5 = index? find/part s #"o" 5

	--test-- "series-find-69"
		--assert 2 = index? find/match s #"h"

	--test-- "series-find-70"
		--assert 5 = index? find/match s "hell"

	--test-- "series-find-71"
		--assert 5 = index? find/match s "Hell"

	--test-- "series-find-72"
		--assert none? find/match/case s "hell"

	--test-- "series-find-73"
		--assert 5 = index? find/match/case s "Hell"

	--test-- "series-find-74"
		--assert none? find/match next s "hell"

	--test-- "series-find-75"
		--assert 8 = index? find/case s "Red"

	--test-- "series-find-76"
		hs-fd-1: make hash! [2 3 5 test #"A" a/b 5 "tesT"]
		append hs-fd-1 datatype!
		--assert 3 = index? find hs-fd-1 5

	--test-- "series-find-77"
		--assert 8 = index? find hs-fd-1 "test"

	--test-- "series-find-78"
		--assert none? find hs-fd-1 99

	--test-- "series-find-79"
		--assert none? find/skip hs-fd-1 'test 2

	--test-- "series-find-80"
		--assert 4 = index? find/skip hs-fd-1 'test 3

	--test-- "series-find-81"
		--assert 7 = index? find/last hs-fd-1 5

	--test-- "series-find-82"
		--assert 2 = index? find/reverse skip hs-fd-1 4 3

	--test-- "series-find-83"
		--assert 8 = index? find skip hs-fd-1 3 "test"

	--test-- "series-find-84"
		--assert none? find/last/part hs-fd-1 3 1

	--test-- "series-find-85"
		--assert 2 = index? find/last/part hs-fd-1 3 2

	--test-- "series-find-86"
		--assert none? find/part hs-fd-1 'test 3

	--test-- "series-find-87"
		--assert 4 = index? find/part hs-fd-1 'test 4

	--test-- "series-find-88"
		--assert 2 = index? find hs-fd-1 [3 5]

	--test-- "series-find-89"
		--assert 3 = index? find hs-fd-1 [5 'test]

	--test-- "series-find-90"
		--assert none? find hs-fd-1 'a/b

	--test-- "series-find-91"
		--assert 6 = index? find/only hs-fd-1 'a/b

	--test-- "series-find-92"
		--assert 2 = index? find/match hs-fd-1 2

	--test-- "series-find-93"
		--assert none? find/match hs-fd-1 3

	--test-- "series-find-94"
		--assert 4 = index? find/match hs-fd-1 [2 3 5]

	--test-- "series-find-95"
		--assert none? find/match next hs-fd-1 [2 3 5]

	--test-- "series-find-96"
		--assert 4 = index? find/tail hs-fd-1 5

===end-group===

===start-group=== "remove"

	--test-- "remove-blk-1"
		a: [1 2 3]
		--assert [2 3] = remove a
		--assert [2 3] = a

	--test-- "remove-blk-2"
		a: [1 2 3]
		--assert [3] = remove next a
		--assert [1 3] = a

	--test-- "remove-blk-3"
		--assert tail? head remove []

	--test-- "remove-blk-4"
		a: [1 2 3]
		--assert [3] = remove/part a 2
		--assert [3] = a

	--test-- "remove-blk-5"
		a: [1 2 3]
		--assert [1 2 3] = remove/part a a

	--test-- "remove-blk-6"
		a: [1 2 3]
		--assert [2 3] = remove/part a next a
		--assert [2 3] = a

	--test-- "remove-blk-7"
		a: [1 2 3]
		--assert [1 2 3] =  remove/part a 0

	--test-- "remove-hash-1"
		hs-remove-1: make hash! [a 2 3]
		--assert (make hash! [2 3]) = remove hs-remove-1
		--assert none? hs-remove-1/a

	--test-- "remove-hash-2"
		hs-remove-1: make hash! [a 2 3]
		remove next hs-remove-1
		--assert 3 = hs-remove-1/a

	--test-- "remove-hash-3"
		--assert tail? head remove make hash! []

	--test-- "remove-hash-4"
		hs-remove-1: make hash! [a b c 2]
		remove/part hs-remove-1 2
		--assert 2 = hs-remove-1/c

	--test-- "remove-hash-5"
		hs-remove-1: make hash! [a b c 2]
		remove/part next hs-remove-1 2
		--assert 2 = hs-remove-1/a
		--assert none? hs-remove-1/b
		--assert none? hs-remove-1/c

	--test-- "remove-str-1"
		a: "123"
		--assert "23" = remove a
		--assert "23" = a

	--test-- "remove-str-2"
		a: "123"
		--assert "3" = remove next a
		--assert "13" = a

	--test-- "remove-str-3"
		--assert tail? head remove ""

	--test-- "remove-str-4"
		a: "123"
		--assert "3" = remove/part a 2
		--assert "3" = a

	--test-- "remove-str-5"
		a: "123"
		--assert "123" = remove/part a a

	--test-- "remove-str-6"
		a: "123"
		--assert "23"= remove/part a next a
		--assert "23" = a

	--test-- "remove-str-7"
		a: "123"
		--assert "123" = remove/part a 0

	--test-- "remove-str-8"
		a: "str123"
		--assert "" = remove back tail a
		--assert "str12" = head a

===end-group===

===start-group=== "clear"

	--test-- "clear-1"
		c1-b: [1 2 3 4 5]
	--assert [] = clear c1-b

	--test-- "clear-2"
		c2-s: "a"
	--assert "" = clear c2-s

	--test-- "clear-3"
		c3-s: "é"
	--assert "" = clear c2-s

	--test-- "clear-4"
		c4-s: "✐"
	--assert "" = clear c4-s

	--test-- "clear-5"
		c5-s: "^(2710)"
	--assert "" = clear c5-s

	--test-- "clear-6"
		c6-b: [a [b] c]
		clear second c6-b
	--assert [a [] c] = c6-b

	--test-- "clear-7"
		c7-b: [a b c d e f]
		c7-b: next next next c7-b
	--assert [a b c] = head clear c7-b

	--test-- "clear-8"
		c8-b: "123^(2710)"
		c8-b: next next next c8-b
	--assert "123" = head clear c8-b

	--test-- "clear-9"
		c9-b: "^(2710)123"
		c9-b:  next c9-b
		--assert "^(2710)" = head clear c9-b

	--test-- "clear-10"
		c1-h: make hash! [a 1 b 2 c 3 d 4 5]
		clear skip c1-h 4
		--assert 2 = c1-h/b
		--assert none? c1-h/c
===end-group===

===start-group=== "at"

	--test-- "at-1 #issue 501"
		--assert "c" = at tail "abc" -1
		--assert "" = at tail "abc" 0

	--test-- "at-2"
		--assert "bcde" = at "abcde" 2
		--assert "abcde" = at "abcde" 1
		--assert "abcde" = at "abcde" 0
		--assert "abcde" = at "abcde" -1
		--assert "abcde" = at "abcde" -256
		--assert "e" = at "abcde" 5
		--assert "" = at "abcde" 6
		--assert "" = at "abcde" 1028

	--test-- "at-3"
		--assert [b c d e] = at [a b c d e] 2
		--assert [a b c d e] = at [a b c d e] 1
		--assert [a b c d e] = at [a b c d e] 0
		--assert [a b c d e] = at [a b c d e] -1
		--assert [a b c d e] = at [a b c d e] -256
		--assert [e] = at [a b c d e] 5
		--assert [] = at [a b c d e] 6
		--assert [] = at [a b c d e] 1028

	--test-- "at-4"
		hs-at-1: make hash! [a b c d e]
		--assert (next hs-at-1) = at hs-at-1 2
		--assert hs-at-1 = at hs-at-1 1
		--assert hs-at-1 = at hs-at-1 0
		--assert hs-at-1 = at hs-at-1 -1
		--assert (make hash! [e]) = at hs-at-1 5

===end-group===

===start-group=== "replace"

	--test-- "replace-block-1-issue-#667"
		code: [print "Hello"]
		--assert 'print = first replace code "Hello" "Cheers"
		--assert "Cheers" = second code

===end-group===

===start-group=== "max/min"			;-- have some overlap with lesser tests

	--test-- "max1"
		--assert "abe"  = max "abc" "abe"
		--assert "abcd" = max "abc" "abcd"

	--test-- "min1"
		--assert ""		= min "" 	"abcdef"
		--assert "abc"	= min "abc" "abcd"

	--test-- "max2"					;@@ need to add tests for word!, path!
		blk1: [1 1.0 #"a" "ab" %ab/cd [] [2] (1 2)]
		blk2: [1 1.0 #"a" "ab" %ab/cd [] [2] (1 3)]
		--assert blk2 = max blk1 blk2
		blk1: next blk1
		--assert blk2 = max blk1 blk2

===end-group===

===start-group=== "reverse"

	--test-- "reverse-str-1"			;-- 4 bytes code point
		--assert "dc𠃌21ba" = reverse "ab12𠃌cd"	;--  = #"^(E818)"
                                                    	;-- 𠃌 = #"^(200CC)"
	--test-- "reverse-str-2"			;-- 2 bytes code point
		--assert "dc21ba" = reverse "ab12cd"

	--test-- "reverse-str-3"			;-- 1 bytes code point
		--assert "dc21ba" = reverse "ab12cd"

	--test-- "reverse-str-4"
		--assert "1ba2𠃌cd" = reverse/part "ab12𠃌cd" 4

	--test-- "reverse-str-5"
		s: "abcdef"
		p: next next next s
		--assert "cbadef" = reverse/part s p

	--test-- "reverse-file-1"			;-- inherit from string!
		--assert %321cba = reverse/part %abc123 6

	--test-- "reverse-blk-1"
		--assert [a b c d] = reverse [d c b a]

	--test-- "reverse-blk-2"
		--assert [c b [a] d] = reverse/part [[a] b c d] 3

	--test-- "reverse-blk-3"
		blk: [1 [2] a b c ]
		p: next next next blk
		--assert [a [2] 1 b c] = reverse/part blk p

	--test-- "reverse-path-1"			;-- inherit from block!
		p1: first [ab/cd/ef]
		p2: first [ef/cd/ab]
		--assert p2 = reverse p1

	--test-- "reverse-hash-1"
		hash: make hash! [d c b a]
		--assert (make hash! [a b c d]) = reverse hash
		--assert 'c = hash/b

	--test-- "reverse-hash-2"
		hash: make hash! [[a] b c d]
		reverse/part hash 3
		--assert [a] = hash/b

===end-group===

===start-group=== "take"

	--test-- "take-blk-1"
		a: [1 2 3]
		--assert 1 = take a
		--assert [2 3] = a

	--test-- "take-blk-2"
		a: [1 2 3]
		--assert 3 = take/last a
		--assert [1 2] = a

	--test-- "take-blk-3"
		a: [1 2 3]
		--assert 2 = take next a
		--assert [1 3] = a

	--test-- "take-blk-4"
		--assert none = take []

	--test-- "take-blk-5"
		a: [1 2 3]
		--assert [1 2] = take/part a 2
		--assert [3] = a

	--test-- "take-blk-6"
		a: [1 2 3]
		--assert 1 = take/part a next a
		--assert [2 3] = a

	--test-- "take-blk-7"
		a: [1 2 3]
		--assert [2 3] = take/part/last a next a
		--assert [1] = a

	--test-- "take-blk-8"
		a: [1 2 3]
		--assert [] = take/part a 0
		--assert [1 2 3] = a

	--test-- "take-blk-9"
		b: "abc"
		a: reduce [b 2 3]
		--assert b = c: take/deep a
		--assert b <> remove c

	--test-- "take-blk-5"
		a: [1 2 3]
		--assert [1 2 3] = take/part a 22
		--assert [] = a

	--test-- "take-str-1"
		a: "123"
		--assert #"1" = take a
		--assert "23" = a

	--test-- "take-str-2"
		a: "123"
		--assert #"3" = take/last a
		--assert "12" = a

	--test-- "take-str-3"
		a: "123"
		--assert #"2" = take next a
		--assert "13" = a

	--test-- "take-str-4"
		--assert none = take ""

	--test-- "take-str-5"
		a: "123"
		--assert "12" = take/part a 2
		--assert "3" = a

	--test-- "take-str-6"
		a: "123"
		--assert "23" = take/part/last a 2
		--assert "1" = a

	--test-- "take-str-7"
		a: "123"
		--assert "" = take/part a a
		--assert "123" = a

	--test-- "take-str-8"
		a: "123"
		--assert #"1"= take/part a next a
		--assert "23" = a

	--test-- "take-str-9"
		a: "123"
		--assert "23" = take/part/last a next a
		--assert "1"  = a

	--test-- "take-str-10"
		a: "123"
		--assert "123" = take/part a 22
		--assert "" = a

	--test-- "take-hash-1"
		h: make hash! [1 2 3]
		--assert 1 = take h
		--assert none? select h 1
		--assert 3 = select h 2

	--test-- "take-hash-2"
		h: make hash! [1 2 3]
		--assert 3 = take/last h
		--assert none? select h 2

	--test-- "take-hash-3"
		h: make hash! [1 2 3]
		--assert 2 = take next h
		--assert 3 = select h 1

===end-group===

===start-group=== "swap"

	--test-- "swap-str-1"			;-- 4 bytes code point
		a: "1234"
		b: "𠃌"						;-- 𠃌 = #"^(200CC)"
		--assert "𠃌234" = swap a b
		--assert "𠃌234" = a
		--assert "1"	 = b

	--test-- "swap-str-2"			;-- 2 bytes code point
		a: "1234"
		b: "ab"					;--  = #"^(E818)"
		--assert "234" = swap a next b
		--assert "234" = a
		--assert "a1b"	 = b

	--test-- "swap-str-3"			;-- 1 bytes code point
		--assert "a234" = swap "1234" "abc"

	--test-- "swap-str-4"
		--assert "123" = swap "123" ""

	--test-- "swap-blk-1"
		a: [1 2]
		b: [a b]
		--assert [a 2] = swap a b
		--assert [a 2] = a
		--assert [1 b] = b

	--test-- "swap-blk-2"
		a: [1 2]
		b: [a b]
		--assert [a]   = swap next a b
		--assert [1 a] = a
		--assert [2 b] = b

	--test-- "swap-blk-3"
		--assert [1 a] = swap [1 a] []

	--test-- "swap-hash-1"
		a: make hash! [1 2]
		b: make hash! [a b]
		swap a b
		--assert 2 = a/a
		--assert 'b = select b 1
===end-group===

===start-group=== "trim"

	str: " ^(A0) ^-a b  ^- c  ^(2000) "
	mstr: {   a ^-1^/    ab2^-  ^/  ac3  ^/  ^/^/}

	--test-- "trim-str-1"
		--assert "a b  ^- c" = trim copy str

	--test-- "trim-str-2"
		--assert "a ^-1^/ab2^/ac3^/" = trim copy mstr

	--test-- "trim-str-3"
		--assert "a ^-1^/    ab2^-  ^/  ac3  ^/  ^/^/" = trim/head copy mstr

	--test-- "trim-str-4"
		--assert "   a ^-1^/    ab2^-  ^/  ac3" = trim/tail copy mstr

	--test-- "trim-str-5"
		--assert "a ^-1^/    ab2^-  ^/  ac3" = trim/head/tail copy mstr

	--test-- "trim-str-6"
		--assert "a 1 ab2 ac3" = trim/lines copy mstr

	--test-- "trim-str-7"
		--assert "a1ab2ac3" = trim/all copy mstr

	--test-- "trim-str-8"
		--assert "    ^-1^/    2^-  ^/  c3  ^/  ^/^/" = trim/with copy mstr "ab"

	--test-- "trim-str-9"
		--assert "    ^-1^/    b2^-  ^/  c3  ^/  ^/^/" = trim/with copy mstr #"a"

	--test-- "trim-str-10"
		--assert "    ^-1^/    b2^-  ^/  c3  ^/  ^/^/" = trim/with copy mstr 97

	--test-- "trim-block-1"
		--assert [1 2] = trim [#[none] 1 #[none] 2 #[none]]

===end-group===

===start-group=== "sort"

	--test-- "sort-str-1"			;-- 4 bytes code point
		a: "g4C28c𠃌9A15Hf3iEG076eBIdbFaDh"
		--assert "0123456789AaBbCcdDEefFGghHIi𠃌" = sort a

	--test-- "sort-str-2"			;-- 2 bytes code point
		a: "g4C28c大9A15Hf3iEG076eBIdbFaDh"
		--assert "0123456789AaBbCcdDEefFGghHIi大" = sort a

	--test-- "sort-str-3"			;-- 1 bytes code point
		a: "g4C28c9A15Hf3iEG076eBIdbFaDh"
		--assert "0123456789AaBbCcdDEefFGghHIi" = sort a
		--assert "0123456789ABCDEFGHIabcdefghi" = sort/case a
		--assert "ihgfedcbaIHGFEDCBA9876543210" = sort/case/reverse a

	--test-- "sort-str-4"
		a: "4gh2ab1cd3ef"
		--assert "1cd2ab3ef4gh" = sort/skip a 3
		--assert "12abcd3ef4gh" = sort/part a 6
		--assert "34efgh" = sort/part skip a 6 tail a

	--test-- "sort-blk-1"
		a: [bc 799 ab2 42 bb1 321.3 "Mo" "Curly" "Larry" -24 0 321.8]
		--assert ["Curly" "Larry" "Mo" -24 0 42 321.3 321.8 799 ab2 bb1 bc] = sort a
		--assert [bc bb1 ab2 799 321.8 321.3 42 0 -24 "Mo" "Larry" "Curly"] = sort/reverse a

	--test-- "sort-blk-2"
		a: ["Larry" 45 "Curly" 50 "Mo" 42]
		--assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip a 2
		--assert ["Curly" "Larry" 45 50 "Mo" 42] = sort/part a 4
		--assert ["Mo" 42 45 50] = sort/part skip a 2 tail a

	--test-- "sort-blk-3"
		a: ["Larry" 45 "Curly" 50 "Mo" 42]
		--assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 2
		--assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 func [a b][a > b]
		--assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare/all a 2 func [a b][a/2 > b/2]

	--test-- "sort-blk-4"
		o1: context [a: 2 i: "a"]
		o2: context [a: 1 i: "b"]
		o3: context [a: 1 i: "c"]
		o4: context [a: 1 i: "d"]
		o5: context [a: 1 i: "e"]
		o6: context [a: 1 i: "f"]
		o7: context [a: 3 i: "g"]
		o8: context [a: 3 i: "h"]
		a: reduce [o1 o2 o3 o8 o4 o5 o6 o7]
		res: reduce [o2 o3 o4 o5 o6 o1 o8 o7]
		--assert res = sort/compare/stable a func [a b][a/a - b/a]
===end-group===

===start-group=== "path access"

	--test-- "path-blk-1 : issue #939"
		pb1-b: [#"x" #"y"]
		--assert #"y" = pb1-b/(#"x")

	--test-- "path-blk-2"
		pb2-b: [#"x" #"y"]
		pb2-c: #"x"
		--assert #"y" = pb2-b/:pb2-c

	--test-- "path-str-1"
		pb1-s: "xy"
		--assert #"y" = pb1-s/(#"x")

	--test-- "path-str-2"
		ps2-s: "xy"
		ps2-c: #"x"
		--assert #"y" = ps2-s/:ps2-c

	--test-- "path-str-3"
		ps3-s: "xy"
		ps3-ss: "x"
		--assert #"y" = ps3-s/:ps3-ss

===end-group===

===start-group=== "set operations"

	--test-- "set-op-blk"
		a: [1 3 2 4]
		b: [3 4 5 4 6]
		--assert [3 4 5 6]		= unique b
		--assert [1 3 2 4 5 6]	= union a b
		--assert [3 4]			= intersect a b
		--assert [1 2 5 6]		= difference a b
		--assert [1 2]			= exclude a b
		--assert [5 6]			= exclude b a

	--test-- "set-op-str"
		a: "CBAD"
		b: "EDCCF"
		--assert "EDCF"		= unique b
		--assert "CBADEF"	= union a b
		--assert "CD"		= intersect a b
		--assert "BAEF"		= difference a b
		--assert "BA"		= exclude a b
		--assert "EF"		= exclude b a

	--test-- "set-op-bitset"
		a: make bitset! [1 2 3 4]
		b: make bitset! [4 5 23]
		--assert "make bitset! #{7C0001}" = mold union a b
		--assert "make bitset! #{080000}" = mold intersect a b
		--assert "make bitset! #{740001}" = mold difference a b
		--assert "make bitset! #{700000}" = mold exclude a b
		--assert "make bitset! #{040001}" = mold exclude b a

===end-group===

~~~end-file~~~

Red [
	Title:   "Red series test script"
	Author:  "Nenad Rakocevic & Peter W A Wood"
	File: 	 %series-test.red
	Tabs:	 4
	Rights:  "Copyright (C) 2011-2015 Nenad Rakocevic & Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/red/red/blob/origin/BSD-3-License.txt"
]

#include  %../../../quick-test/quick-test.red

~~~start-file~~~ "series"

===start-group=== "first, second, third, fourth, fifth"

	--test-- "series-fstff-1"
	  sf1-ser:  [1 2 3 4 5]
	--assert 1 = first sf1-ser
	--assert 2 = second sf1-ser
	--assert 3 = third sf1-ser
	--assert 4 = fourth sf1-ser
	--assert 5 = fifth sf1-ser
	--assert 5 = last sf1-ser

	--test-- "series-fstff-2"
	  sf2-ser:  [1 2 3 4 5]
	--assert 2 = first next sf2-ser

	--test-- "series-fstff-3"
	  sf3-ser:  "12345"
	--assert 49 = first sf3-ser
	--assert 53 = last sf3-ser

	--test-- "series-fstff-4"
	  sf4-ser:  [1 2 3 4 5]
	--assert none = fifth next sf4-ser

	--test-- "series-fstff-5"
	  sf5-ser:  "12345"
	--assert 53 = fifth sf5-ser

	--test-- "series-fstff-6"
	;;  stf6-ser: #{000102}
	;;--assert 0 = first stf6-ser

	--test-- "series-fstff-7"
	--assert 'a = first [a b c d]

	--test-- "series-fstff-8"
	--assert 'a = first first first first first first first first first [[[[[[[[[a]]]]]]]]]

	--test-- "series-fstff-9"
	--assert #"^(00)" = first "^(00)"

	--test-- "series-fstff-10"
	--assert #"^(00)" = first "^(00)a"

	--test-- "series-fstff-11"
	--assert #"^(00)" = second "a^(00)"

	--test-- "series-fstff-12"
	--assert #"^(00)" = second "a^(00)b"

	--test-- "series-fstff-13"
	sf6-ser: make hash! [a b]
	--assert 'a = first sf6-ser
	--assert 'b = last sf6-ser

	--test-- "series-fstff-14"
	sf7-ser: make hash! [1 2 3]
	--assert 2 = first next sf7-ser
	--assert none = fifth next sf7-ser

===end-group===

===start-group=== "next"
  --test-- "series-next-1"
  --assert 2 = first next [1 2 3 4 5]
  --test-- "series-next-2"
  --assert 3 = first next next [1 2 3 4 5]
  --test-- "series-next-3"
  --assert 4 = first next next next [1 2 3 4 5]
  --test-- "series-next-4"
  --assert 5 = first next next next next [1 2 3 4 5]
  --test-- "series-next-5"
  --assert none = first next next next next next [1 2 3 4 5]
  --test-- "series-next-6"
  --assert 50 = first next "12345"
  --test-- "series-next-7"
  --assert 51 = first next next "12345"
  --test-- "series-next-8"
  --assert 52 = first next next next "12345"
  --test-- "series-next-9"
  --assert 53 = first next next next next "12345"
  --test-- "series-next-10"
  --assert none = first next next next next next "12345"
  --test-- "series-next-11"
  --assert #"^(00)" = first next "a^(00)"
  --test-- "series-next-12"
  --assert #"^(00)" = first next "a^(00)b"
===end-group===

===start-group=== "back"
  --test-- "series-back-1"
  --assert 1 = first back next [1 2 3 4 5]
  --test-- "series-back-2"
  --assert 1 = first back back next next [1 2 3 4 5]
  --test-- "series-back-3"
  --assert 1 = first back back back next next next [1 2 3 4 5]
  --test-- "series-back-4"
  --assert 1 = first back back back back next next next next [1 2 3 4 5]
  --test-- "series-back-5"
  --assert 1 = first back back back back back next next next next next [1 2 3 4 5]
  --test-- "series-back-6"
  --assert 49 = first back next "12345"
  --test-- "series-back-7"
  --assert 50 = first back next next "12345"
  --test-- "series-back-8"
  --assert 51 = first back next next next "12345"
  --test-- "series-back-9"
  --assert 52 = first back next next next next "12345"
  --test-- "series-back-10"
  --assert 53 = first back next next next next next "12345"
  --test-- "series-back-11"
  --assert 49 = first back "12345"
  --test-- "series-back-12"
  --assert 1 = first back next make hash! [1 2 3 4 5]
===end-group===

===start-group=== "tail"
  --test-- "series-tail-1"
  --assert 5 = first back tail [1 2 3 4 5]
  --test-- "seried-tail-2"
  --assert none = pick tail [1 2 3 4 5] 1
  --test-- "series-tail-3"
  hs-ser-1: make hash! [1 2 3 4 5]
  --assert 5 = first back tail hs-ser-1
  --test-- "seried-tail-4"
  hs-ser-2: make hash! [1 2 3 4 5]
  --assert none = pick tail hs-ser-2 1
===end-group===

===start-group=== "pick"

  --test-- "series-pick-1"
  --assert none = pick "" 1

  --test-- "series-pick-2"
  --assert none = pick "" 0

  --test-- "series-pick-3"
  --assert none = pick "" 2

  --test-- "series-pick-4"
  --assert 49 = pick "12345" 1

  --test-- "series-pick-5"
  --assert 53 = pick "12345" 5

  --test-- "series-pick-6"
  --assert 1 = pick [1 2 3 4 5] 1

  --test-- "series-pick-7"
  --assert 2 = pick [1 2 3 4 5] 2

  --test-- "series-pick-8"
  --assert 4 = pick [1 2 3 4 5] 4

  --test-- "series-pick-9"
  --assert 5 = pick [1 2 3 4 5] 5

  --test-- "series-pick-10"
  --assert 2 = pick next next next [1 2 3 4 5] -2

  --test-- "series-pick-11"
  --assert 3 = pick next next next [1 2 3 4 5] -1

  --test-- "series-pick-12"
  --assert none = pick next next next [1 2 3 4 5] 0

  --test-- "series-pick-13"
  --assert none = pick "12345" -1

  --test-- "series-pick-14"
    sp14-i: 1
  --assert 1 = pick [1 2 3 4 5] sp14-i

  --test-- "series-pick-15"
    sp15-i: 4
  --assert 4 = pick [1 2 3 4 5] sp15-i

  --test-- "series-pick-16"
    sp16-i: -2
  --assert 2 = pick next next next [1 2 3 4 5] sp16-i

  --test-- "series-pick-17"
    sp17-i: 0
  --assert none = pick next next next [1 2 3 4 5] sp17-i

  --test-- "series-pick-18"
    sp18-i: -1
  --assert none = pick "12345" sp18-i

  --test-- "series-pick-19"
  --assert 5 = pick make hash! [1 2 3 4 5] 5

  --test-- "series-pick-20"
  --assert 2 = pick next next next make hash! [1 2 3 4 5] -2
===end-group===

===start-group=== "select"
	--test-- "series-select-1"
		--assert 2 = select [1 2 3 4 5] 1
	--test-- "series-select-2"
		--assert 5 = select [1 2 3 4 5] 4
	--test-- "series-select-3"
		--assert none = select [1 2 3 4 5] 0
	--test-- "series-select-4"
		--assert none = select [1 2 3 4 5] 5

	--test-- "series-select-5"
		a: [2 3 5 test #"A" a/b 5 "tesT"]
		--assert #"A" = select a 'test

	--test-- "series-select-6"
		list: [a 1 b 2 c 3]
		--assert 2 = list/b

	--test-- "series-select-6"
		--assert 'test = select/skip a 5 2

	--test-- "series-select-7"
		s: "Hello, Red World!"
		--assert #"e" = select s #"r"

	--test-- "series-select-8"
		--assert #"l" = select/last s #"r"

	--test-- "series-select-9"
		--assert #"d" = select/skip s "e" 2

	--test-- "series-select-10"
		--assert none? select s #"!"

	--test-- "series-select-11"
		--assert 5 = select make hash! [1 2 3 4 5] 4

	--test-- "series-select-12"
		hs-sel-1: make hash! [2 3 5 test #"A" a/b 5 "tesT"]
		--assert #"A" = select hs-sel-1 'test

	--test-- "series-select-13"
		list: make hash! [a 1 b 2 c 3]
		--assert 2 = list/b

	--test-- "series-select-14"
		--assert 'test = select/skip hs-sel-1 5 2

	--test-- "series-select-15"
		hs-select-1: make hash! [aBc 1 abc 2 ABc 3]
		--assert 1 = select hs-select-1 'abc
		--assert 2 = select/case hs-select-1 'abc
===end-group===

===start-group=== "append"
  --test-- "series-append-1"
  --assert 6 = last append [1 2 3 4 5] 6
  --test-- "series-append-2"
  --assert 6 = last append [1 2 3 4] [5 6]
  --assert 4 = fourth append [1 2 3 4] [5 6]
  --assert 5 = fifth append [1 2 3 4] [5 6]
  --test-- "series-append-3"
  --assert 55 = last append "12345" "67"
  --test-- "series-append-4"
  --assert 233 = last append "abcde" "é" ;; utf-8 C3 A9
  --test-- "series-append-5"
  --assert 49 = last append "abcdeé" "1" ;; utf-8 C3 A9
  --test-- "series-append-6"
  --assert 10000 = last append "abcde" "✐"
  --test-- "series-append-7"
  --assert 48 = last append "abcde^(2710)" "0"
  --test-- "series-append-8"
  --assert 10000 = last append "abcdeé" "^(2710)"
  --test-- "series-append-9"
  --assert 233 = last append "abcde^(2710)" "é"
  --test-- "series-append-10"
  --assert 65536 = last append "abcde" "^(010000)"
  --test-- "series-append-11"
  --assert 48 = last append "abcde^(010000)" "0"
  --test-- "series-append-12"
  --assert 65536 = last append "abcde^(2710)é" "^(010000)"

  --test-- "series-append-13"
	blk: make block! 1
	append blk 'x/y
	append/only blk  'r/s
	--assert "[x y r/s]" = mold blk

  --test-- "series-append-14"
	blk: [1 2]
	append/dup/part blk [4 5 6] 3 2
	--assert "[1 2 4 5 4 5 4 5]" = mold blk

  --test-- "series-append-15"
	blk: [1 2]
	append/dup/part blk [4 5 6] 2 3
	--assert "[1 2 4 5 6 4 5 6]" = mold blk

  --test-- "series-append-16"
	str: "12"
	append/dup/part str "456" 3 2
	--assert str = "12454545"

  --test-- "series-append-17"
	str: "12"
	append/part/dup str "456" 3 2
	--assert str = "12456456"

  --test-- "series-append-18"
  hs-append-1: make hash! [a 1 b 2]
  --assert 6 = last append hs-append-1 [c 6]
  --assert 6 = select hs-append-1 'c
===end-group===

===start-group=== "series-equal"

  --test-- "series-equal-1"
  --assert [] = []

  --test-- "series-equal-2"
    se2-b: []
  --assert [] = se2-b

  --test-- "series-equal-3"
    se3-b: []
  --assert se3-b = []

  --test-- "series-equal-4"
    se4-b: [1]
  --assert se4-b = [1]

  --test-- "series-equal-5"
    se5-b: ["abcde"]
  --assert se5-b = ["abcde"]

===end-group===

===start-group=== "series-find"

  --test-- "series-find-1"
  --assert 3 = first find [1 2 3 4 5] 3

  --test-- "series-find-2"
  --assert 'a = first find [a b c d e] 'a

  --test-- "series-find-3"
  --assert 'e = first find [a b c d e] 'e

  --test-- "series-find-4"
  --assert none = find [] 'a

  --test-- "series-find-5"
  --assert none = find [1 2 3 4] 'a

  --test-- "series-find-6"
  --assert none = find next [a b c d e] 'a

  --test-- "series-find-7"
  --assert 51 = first find "12345" "3"

  --test-- "series-find-8"
  --assert 51 = first find "12345" "^(33)"

  --test-- "series-find-9"
  --assert 51 = first find "12345" first "^(33)"

  --test-- "series-find-10"
  --assert 51 = first find "12345" #"3"

  --test-- "series-find-11"
  --assert 51 = first find "12345" #"^(33)"

  --test-- "series-find-12"
  --assert #"3" = first find "12345" #"3"

  --test-- "series-find-13"
  --assert #"a" = first find "abcdefghijklmno" #"a"

  --test-- "series-find-14"
  --assert "ghijklmno" = find "abcdefghijklmno" "ghij"

  --test-- "series-find-15"
  --assert #"o" = first find "abcdefghijklmno" #"o"

  --test-- "series-find-16"
  --assert "o" = find "abcdefghijklmno" #"o"

  --test-- "series-find-17"
  --assert #"o" = first find "abcdefghijklmno" "o"

  --test-- "series-find-18"
  --assert "o" = find "abcdefghijklmno" "o"

  --test-- "series-find-19"
  --assert none = find "" #"a"

  --test-- "series-find-20"
  --assert none = find "" #"^(00)"

  --test-- "series-find-21"
  --assert none = find "" ""

  --test-- "series-find-22"
  --assert "^(00)" = find "^(00)" "^(00)"

  --test-- "series-find-23"
  --assert "a^(00)" = find "a^(00)" "a^(00)"

  --test-- "series-find-24"
  --assert "^(00)a" = find "^(00)a" "^(00)a"

  --test-- "series-find-25"
  --assert "^(00)" = find "^(00)" #"^(00)"

  --test-- "series-find-26"
  --assert #"^(00)" = first find "^(00)" #"^(00)"

  --test-- "series-find-27"
  --assert #"é" = first find "abcdeé" #"é"

  --test-- "series-find-28"
  --assert "é" = find "abcdeé" "é"

  --test-- "series-find-29"
  --assert "é" = find append "abcde" "é" "é"

  --test-- "series-find-30"
  --assert 10000 = first find "abcde✐" "✐"

  --test-- "series-find-30a"
  --assert 10000 = first find "abcde✐" #"✐"

  --test-- "series-find-31"
  --assert none = find "012345" 48

  --test-- "series-find-32"
  --assert "^(010000)" = find "abcde^(2710)é^(010000)" "^(010000)"

  --test-- "series-find-33"
  --assert "^(010000)cde^(2710)é" = find "ab^(010000)cde^(2710)é" #"^(010000)"

  --test-- "series-find-34"
  --assert "^(010000)cde^(2710)é" = find "ab^(010000)cde^(2710)é" "^(010000)"

	--test-- "series-find-35"
		a: [2 3 5 test #"A" a/b 5 "tesT"]
		append a datatype!
		--assert 3 = index? find a 5

	--test-- "series-find-36"
		--assert 8 = index? find a "test"

	--test-- "series-find-37"
		--assert none? find a 99

	--test-- "series-find-38"
		--assert none? find/skip a 'test 2

	--test-- "series-find-39"
		--assert 4 = index? find/skip a 'test 3

	--test-- "series-find-40"
		--assert 7 = index? find/last a 5

	--test-- "series-find-41"
		--assert 2 = index? find/reverse skip a 4 3

	--test-- "series-find-42"
		--assert 8 = index? find skip a 3 "test"

	--test-- "series-find-43"
		--assert none? find/last/part a 3 1

	--test-- "series-find-44"
		--assert 2 = index? find/last/part a 3 2

	--test-- "series-find-45"
		--assert none? find/part a 'test 3

	--test-- "series-find-46"
		--assert 4 = index? find/part a 'test 4

	--test-- "series-find-47"
		--assert 2 = index? find a [3 5]

	--test-- "series-find-48"
		--assert 3 = index? find a [5 'test]

	--test-- "series-find-49"
		--assert none? find a 'a/b

	--test-- "series-find-50"
		--assert 6 = index? find/only a 'a/b

	--test-- "series-find-51"
		--assert 2 = index? find/match a 2

	--test-- "series-find-52"
		--assert none? find/match a 3

	--test-- "series-find-53"
		--assert 4 = index? find/match a [2 3 5]

	--test-- "series-find-54"
		--assert none? find/match next a [2 3 5]

	--test-- "series-find-55"
		--assert 4 = index? find/tail a 5

	--test-- "series-find-56"
		--assert 3 = index? find 'a/b/3/d 3

	--test-- "series-find-57"
		--assert 2 = index? find 'a/b/3/d 'b

	--test-- "series-find-58"
		s: "Hello, Red World!"
		--assert 6 = index? find s ","

	--test-- "series-find-59"
		--assert 8 = index? find s "Red"

	--test-- "series-find-60"
		--assert 8 = index? find s "red"

	--test-- "series-find-61"
		--assert 6 = index? find s #","

	--test-- "series-find-62"
		--assert 1 = index? find "^(00)" "^(00)"

	--test-- "series-find-63"
		--assert 5 = index? find/skip s #"o" 2

	--test-- "series-find-64"
		--assert 13 = index? find/skip s #"o" 3

	--test-- "series-find-65"
		--assert 15 = index? find/last s #"l"

	--test-- "series-find-66"
		--assert 13 = index? find/last s "o"

	--test-- "series-find-67"
		--assert none? find/part s #"o" 4

	--test-- "series-find-68"
		--assert 5 = index? find/part s #"o" 5

	--test-- "series-find-69"
		--assert 2 = index? find/match s #"h"

	--test-- "series-find-70"
		--assert 5 = index? find/match s "hell"

	--test-- "series-find-71"
		--assert 5 = index? find/match s "Hell"

	--test-- "series-find-72"
		--assert none? find/match/case s "hell"

	--test-- "series-find-73"
		--assert 5 = index? find/match/case s "Hell"

	--test-- "series-find-74"
		--assert none? find/match next s "hell"

	--test-- "series-find-75"
		--assert 8 = index? find/case s "Red"

	--test-- "series-find-76"
		hs-fd-1: make hash! [2 3 5 test #"A" a/b 5 "tesT"]
		append hs-fd-1 datatype!
		--assert 3 = index? find hs-fd-1 5

	--test-- "series-find-77"
		--assert 8 = index? find hs-fd-1 "test"

	--test-- "series-find-78"
		--assert none? find hs-fd-1 99

	--test-- "series-find-79"
		--assert none? find/skip hs-fd-1 'test 2

	--test-- "series-find-80"
		--assert 4 = index? find/skip hs-fd-1 'test 3

	--test-- "series-find-81"
		--assert 7 = index? find/last hs-fd-1 5

	--test-- "series-find-82"
		--assert 2 = index? find/reverse skip hs-fd-1 4 3

	--test-- "series-find-83"
		--assert 8 = index? find skip hs-fd-1 3 "test"

	--test-- "series-find-84"
		--assert none? find/last/part hs-fd-1 3 1

	--test-- "series-find-85"
		--assert 2 = index? find/last/part hs-fd-1 3 2

	--test-- "series-find-86"
		--assert none? find/part hs-fd-1 'test 3

	--test-- "series-find-87"
		--assert 4 = index? find/part hs-fd-1 'test 4

	--test-- "series-find-88"
		--assert 2 = index? find hs-fd-1 [3 5]

	--test-- "series-find-89"
		--assert 3 = index? find hs-fd-1 [5 'test]

	--test-- "series-find-90"
		--assert none? find hs-fd-1 'a/b

	--test-- "series-find-91"
		--assert 6 = index? find/only hs-fd-1 'a/b

	--test-- "series-find-92"
		--assert 2 = index? find/match hs-fd-1 2

	--test-- "series-find-93"
		--assert none? find/match hs-fd-1 3

	--test-- "series-find-94"
		--assert 4 = index? find/match hs-fd-1 [2 3 5]

	--test-- "series-find-95"
		--assert none? find/match next hs-fd-1 [2 3 5]

	--test-- "series-find-96"
		--assert 4 = index? find/tail hs-fd-1 5

===end-group===

===start-group=== "remove"

	--test-- "remove-blk-1"
		a: [1 2 3]
		--assert [2 3] = remove a
		--assert [2 3] = a

	--test-- "remove-blk-2"
		a: [1 2 3]
		--assert [3] = remove next a
		--assert [1 3] = a

	--test-- "remove-blk-3"
		--assert tail? head remove []

	--test-- "remove-blk-4"
		a: [1 2 3]
		--assert [3] = remove/part a 2
		--assert [3] = a

	--test-- "remove-blk-5"
		a: [1 2 3]
		--assert [1 2 3] = remove/part a a

	--test-- "remove-blk-6"
		a: [1 2 3]
		--assert [2 3] = remove/part a next a
		--assert [2 3] = a

	--test-- "remove-blk-7"
		a: [1 2 3]
		--assert [1 2 3] =  remove/part a 0

	--test-- "remove-hash-1"
		hs-remove-1: make hash! [a 2 3]
		--assert (make hash! [2 3]) = remove hs-remove-1
		--assert none? hs-remove-1/a

	--test-- "remove-hash-2"
		hs-remove-1: make hash! [a 2 3]
		remove next hs-remove-1
		--assert 3 = hs-remove-1/a

	--test-- "remove-hash-3"
		--assert tail? head remove make hash! []

	--test-- "remove-hash-4"
		hs-remove-1: make hash! [a b c 2]
		remove/part hs-remove-1 2
		--assert 2 = hs-remove-1/c

	--test-- "remove-hash-5"
		hs-remove-1: make hash! [a b c 2]
		remove/part next hs-remove-1 2
		--assert 2 = hs-remove-1/a
		--assert none? hs-remove-1/b
		--assert none? hs-remove-1/c

	--test-- "remove-str-1"
		a: "123"
		--assert "23" = remove a
		--assert "23" = a

	--test-- "remove-str-2"
		a: "123"
		--assert "3" = remove next a
		--assert "13" = a

	--test-- "remove-str-3"
		--assert tail? head remove ""

	--test-- "remove-str-4"
		a: "123"
		--assert "3" = remove/part a 2
		--assert "3" = a

	--test-- "remove-str-5"
		a: "123"
		--assert "123" = remove/part a a

	--test-- "remove-str-6"
		a: "123"
		--assert "23"= remove/part a next a
		--assert "23" = a

	--test-- "remove-str-7"
		a: "123"
		--assert "123" = remove/part a 0

	--test-- "remove-str-8"
		a: "str123"
		--assert "" = remove back tail a
		--assert "str12" = head a

===end-group===

===start-group=== "clear"

	--test-- "clear-1"
		c1-b: [1 2 3 4 5]
	--assert [] = clear c1-b

	--test-- "clear-2"
		c2-s: "a"
	--assert "" = clear c2-s

	--test-- "clear-3"
		c3-s: "é"
	--assert "" = clear c2-s

	--test-- "clear-4"
		c4-s: "✐"
	--assert "" = clear c4-s

	--test-- "clear-5"
		c5-s: "^(2710)"
	--assert "" = clear c5-s

	--test-- "clear-6"
		c6-b: [a [b] c]
		clear second c6-b
	--assert [a [] c] = c6-b

	--test-- "clear-7"
		c7-b: [a b c d e f]
		c7-b: next next next c7-b
	--assert [a b c] = head clear c7-b

	--test-- "clear-8"
		c8-b: "123^(2710)"
		c8-b: next next next c8-b
	--assert "123" = head clear c8-b

	--test-- "clear-9"
		c9-b: "^(2710)123"
		c9-b:  next c9-b
		--assert "^(2710)" = head clear c9-b

	--test-- "clear-10"
		c1-h: make hash! [a 1 b 2 c 3 d 4 5]
		clear skip c1-h 4
		--assert 2 = c1-h/b
		--assert none? c1-h/c
===end-group===

===start-group=== "at"

	--test-- "at-1 #issue 501"
		--assert "c" = at tail "abc" -1
		--assert "" = at tail "abc" 0

	--test-- "at-2"
		--assert "bcde" = at "abcde" 2
		--assert "abcde" = at "abcde" 1
		--assert "abcde" = at "abcde" 0
		--assert "abcde" = at "abcde" -1
		--assert "abcde" = at "abcde" -256
		--assert "e" = at "abcde" 5
		--assert "" = at "abcde" 6
		--assert "" = at "abcde" 1028

	--test-- "at-3"
		--assert [b c d e] = at [a b c d e] 2
		--assert [a b c d e] = at [a b c d e] 1
		--assert [a b c d e] = at [a b c d e] 0
		--assert [a b c d e] = at [a b c d e] -1
		--assert [a b c d e] = at [a b c d e] -256
		--assert [e] = at [a b c d e] 5
		--assert [] = at [a b c d e] 6
		--assert [] = at [a b c d e] 1028

	--test-- "at-4"
		hs-at-1: make hash! [a b c d e]
		--assert (next hs-at-1) = at hs-at-1 2
		--assert hs-at-1 = at hs-at-1 1
		--assert hs-at-1 = at hs-at-1 0
		--assert hs-at-1 = at hs-at-1 -1
		--assert (make hash! [e]) = at hs-at-1 5

===end-group===

===start-group=== "replace"

	--test-- "replace-block-1-issue-#667"
		code: [print "Hello"]
		--assert 'print = first replace code "Hello" "Cheers"
		--assert "Cheers" = second code

===end-group===

===start-group=== "max/min"			;-- have some overlap with lesser tests

	--test-- "max1"
		--assert "abe"  = max "abc" "abe"
		--assert "abcd" = max "abc" "abcd"

	--test-- "min1"
		--assert ""		= min "" 	"abcdef"
		--assert "abc"	= min "abc" "abcd"

	--test-- "max2"					;@@ need to add tests for word!, path!
		blk1: [1 1.0 #"a" "ab" %ab/cd [] [2] (1 2)]
		blk2: [1 1.0 #"a" "ab" %ab/cd [] [2] (1 3)]
		--assert blk2 = max blk1 blk2
		blk1: next blk1
		--assert blk2 = max blk1 blk2

===end-group===

===start-group=== "reverse"

	--test-- "reverse-str-1"			;-- 4 bytes code point
		--assert "dc𠃌21ba" = reverse "ab12𠃌cd"	;--  = #"^(E818)"
                                                    	;-- 𠃌 = #"^(200CC)"
	--test-- "reverse-str-2"			;-- 2 bytes code point
		--assert "dc21ba" = reverse "ab12cd"

	--test-- "reverse-str-3"			;-- 1 bytes code point
		--assert "dc21ba" = reverse "ab12cd"

	--test-- "reverse-str-4"
		--assert "1ba2𠃌cd" = reverse/part "ab12𠃌cd" 4

	--test-- "reverse-str-5"
		s: "abcdef"
		p: next next next s
		--assert "cbadef" = reverse/part s p

	--test-- "reverse-file-1"			;-- inherit from string!
		--assert %321cba = reverse/part %abc123 6

	--test-- "reverse-blk-1"
		--assert [a b c d] = reverse [d c b a]

	--test-- "reverse-blk-2"
		--assert [c b [a] d] = reverse/part [[a] b c d] 3

	--test-- "reverse-blk-3"
		blk: [1 [2] a b c ]
		p: next next next blk
		--assert [a [2] 1 b c] = reverse/part blk p

	--test-- "reverse-path-1"			;-- inherit from block!
		p1: first [ab/cd/ef]
		p2: first [ef/cd/ab]
		--assert p2 = reverse p1

	--test-- "reverse-hash-1"
		hash: make hash! [d c b a]
		--assert (make hash! [a b c d]) = reverse hash
		--assert 'c = hash/b

	--test-- "reverse-hash-2"
		hash: make hash! [[a] b c d]
		reverse/part hash 3
		--assert [a] = hash/b

===end-group===

===start-group=== "take"

	--test-- "take-blk-1"
		a: [1 2 3]
		--assert 1 = take a
		--assert [2 3] = a

	--test-- "take-blk-2"
		a: [1 2 3]
		--assert 3 = take/last a
		--assert [1 2] = a

	--test-- "take-blk-3"
		a: [1 2 3]
		--assert 2 = take next a
		--assert [1 3] = a

	--test-- "take-blk-4"
		--assert none = take []

	--test-- "take-blk-5"
		a: [1 2 3]
		--assert [1 2] = take/part a 2
		--assert [3] = a

	--test-- "take-blk-6"
		a: [1 2 3]
		--assert 1 = take/part a next a
		--assert [2 3] = a

	--test-- "take-blk-7"
		a: [1 2 3]
		--assert [2 3] = take/part/last a next a
		--assert [1] = a

	--test-- "take-blk-8"
		a: [1 2 3]
		--assert [] = take/part a 0
		--assert [1 2 3] = a

	--test-- "take-blk-9"
		b: "abc"
		a: reduce [b 2 3]
		--assert b = c: take/deep a
		--assert b <> remove c

	--test-- "take-blk-5"
		a: [1 2 3]
		--assert [1 2 3] = take/part a 22
		--assert [] = a

	--test-- "take-str-1"
		a: "123"
		--assert #"1" = take a
		--assert "23" = a

	--test-- "take-str-2"
		a: "123"
		--assert #"3" = take/last a
		--assert "12" = a

	--test-- "take-str-3"
		a: "123"
		--assert #"2" = take next a
		--assert "13" = a

	--test-- "take-str-4"
		--assert none = take ""

	--test-- "take-str-5"
		a: "123"
		--assert "12" = take/part a 2
		--assert "3" = a

	--test-- "take-str-6"
		a: "123"
		--assert "23" = take/part/last a 2
		--assert "1" = a

	--test-- "take-str-7"
		a: "123"
		--assert "" = take/part a a
		--assert "123" = a

	--test-- "take-str-8"
		a: "123"
		--assert #"1"= take/part a next a
		--assert "23" = a

	--test-- "take-str-9"
		a: "123"
		--assert "23" = take/part/last a next a
		--assert "1"  = a

	--test-- "take-str-10"
		a: "123"
		--assert "123" = take/part a 22
		--assert "" = a

	--test-- "take-hash-1"
		h: make hash! [1 2 3]
		--assert 1 = take h
		--assert none? select h 1
		--assert 3 = select h 2

	--test-- "take-hash-2"
		h: make hash! [1 2 3]
		--assert 3 = take/last h
		--assert none? select h 2

	--test-- "take-hash-3"
		h: make hash! [1 2 3]
		--assert 2 = take next h
		--assert 3 = select h 1

===end-group===

===start-group=== "swap"

	--test-- "swap-str-1"			;-- 4 bytes code point
		a: "1234"
		b: "𠃌"						;-- 𠃌 = #"^(200CC)"
		--assert "𠃌234" = swap a b
		--assert "𠃌234" = a
		--assert "1"	 = b

	--test-- "swap-str-2"			;-- 2 bytes code point
		a: "1234"
		b: "ab"					;--  = #"^(E818)"
		--assert "234" = swap a next b
		--assert "234" = a
		--assert "a1b"	 = b

	--test-- "swap-str-3"			;-- 1 bytes code point
		--assert "a234" = swap "1234" "abc"

	--test-- "swap-str-4"
		--assert "123" = swap "123" ""

	--test-- "swap-blk-1"
		a: [1 2]
		b: [a b]
		--assert [a 2] = swap a b
		--assert [a 2] = a
		--assert [1 b] = b

	--test-- "swap-blk-2"
		a: [1 2]
		b: [a b]
		--assert [a]   = swap next a b
		--assert [1 a] = a
		--assert [2 b] = b

	--test-- "swap-blk-3"
		--assert [1 a] = swap [1 a] []

	--test-- "swap-hash-1"
		a: make hash! [1 2]
		b: make hash! [a b]
		swap a b
		--assert 2 = a/a
		--assert 'b = select b 1
===end-group===

===start-group=== "trim"

	str: " ^(A0) ^-a b  ^- c  ^(2000) "
	mstr: {   a ^-1^/    ab2^-  ^/  ac3  ^/  ^/^/}

	--test-- "trim-str-1"
		--assert "a b  ^- c" = trim copy str

	--test-- "trim-str-2"
		--assert "a ^-1^/ab2^/ac3^/" = trim copy mstr

	--test-- "trim-str-3"
		--assert "a ^-1^/    ab2^-  ^/  ac3  ^/  ^/^/" = trim/head copy mstr

	--test-- "trim-str-4"
		--assert "   a ^-1^/    ab2^-  ^/  ac3" = trim/tail copy mstr

	--test-- "trim-str-5"
		--assert "a ^-1^/    ab2^-  ^/  ac3" = trim/head/tail copy mstr

	--test-- "trim-str-6"
		--assert "a 1 ab2 ac3" = trim/lines copy mstr

	--test-- "trim-str-7"
		--assert "a1ab2ac3" = trim/all copy mstr

	--test-- "trim-str-8"
		--assert "    ^-1^/    2^-  ^/  c3  ^/  ^/^/" = trim/with copy mstr "ab"

	--test-- "trim-str-9"
		--assert "    ^-1^/    b2^-  ^/  c3  ^/  ^/^/" = trim/with copy mstr #"a"

	--test-- "trim-str-10"
		--assert "    ^-1^/    b2^-  ^/  c3  ^/  ^/^/" = trim/with copy mstr 97

	--test-- "trim-block-1"
		--assert [1 2] = trim [#[none] 1 #[none] 2 #[none]]

===end-group===

===start-group=== "sort"

	--test-- "sort-str-1"			;-- 4 bytes code point
		a: "g4C28c𠃌9A15Hf3iEG076eBIdbFaDh"
		--assert "0123456789AaBbCcdDEefFGghHIi𠃌" = sort a

	--test-- "sort-str-2"			;-- 2 bytes code point
		a: "g4C28c大9A15Hf3iEG076eBIdbFaDh"
		--assert "0123456789AaBbCcdDEefFGghHIi大" = sort a

	--test-- "sort-str-3"			;-- 1 bytes code point
		a: "g4C28c9A15Hf3iEG076eBIdbFaDh"
		--assert "0123456789AaBbCcdDEefFGghHIi" = sort a
		--assert "0123456789ABCDEFGHIabcdefghi" = sort/case a
		--assert "ihgfedcbaIHGFEDCBA9876543210" = sort/case/reverse a

	--test-- "sort-str-4"
		a: "4gh2ab1cd3ef"
		--assert "1cd2ab3ef4gh" = sort/skip a 3
		--assert "12abcd3ef4gh" = sort/part a 6
		--assert "34efgh" = sort/part skip a 6 tail a

	--test-- "sort-blk-1"
		a: [bc 799 ab2 42 bb1 321.3 "Mo" "Curly" "Larry" -24 0 321.8]
		--assert ["Curly" "Larry" "Mo" -24 0 42 321.3 321.8 799 ab2 bb1 bc] = sort a
		--assert [bc bb1 ab2 799 321.8 321.3 42 0 -24 "Mo" "Larry" "Curly"] = sort/reverse a

	--test-- "sort-blk-2"
		a: ["Larry" 45 "Curly" 50 "Mo" 42]
		--assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip a 2
		--assert ["Curly" "Larry" 45 50 "Mo" 42] = sort/part a 4
		--assert ["Mo" 42 45 50] = sort/part skip a 2 tail a

	--test-- "sort-blk-3"
		a: ["Larry" 45 "Curly" 50 "Mo" 42]
		--assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 2
		--assert ["Mo" 42 "Larry" 45 "Curly" 50] = sort/skip/compare a 2 func [a b][a > b]
		--assert ["Curly" 50 "Larry" 45 "Mo" 42] = sort/skip/compare/all a 2 func [a b][a/2 > b/2]

	--test-- "sort-blk-4"
		o1: context [a: 2 i: "a"]
		o2: context [a: 1 i: "b"]
		o3: context [a: 1 i: "c"]
		o4: context [a: 1 i: "d"]
		o5: context [a: 1 i: "e"]
		o6: context [a: 1 i: "f"]
		o7: context [a: 3 i: "g"]
		o8: context [a: 3 i: "h"]
		a: reduce [o1 o2 o3 o8 o4 o5 o6 o7]
		res: reduce [o2 o3 o4 o5 o6 o1 o8 o7]
		--assert res = sort/compare/stable a func [a b][a/a - b/a]
===end-group===

===start-group=== "path access"

	--test-- "path-blk-1 : issue #939"
		pb1-b: [#"x" #"y"]
		--assert #"y" = pb1-b/(#"x")

	--test-- "path-blk-2"
		pb2-b: [#"x" #"y"]
		pb2-c: #"x"
		--assert #"y" = pb2-b/:pb2-c

	--test-- "path-str-1"
		pb1-s: "xy"
		--assert #"y" = pb1-s/(#"x")

	--test-- "path-str-2"
		ps2-s: "xy"
		ps2-c: #"x"
		--assert #"y" = ps2-s/:ps2-c

	--test-- "path-str-3"
		ps3-s: "xy"
		ps3-ss: "x"
		--assert #"y" = ps3-s/:ps3-ss

===end-group===

===start-group=== "set operations"

	--test-- "set-op-blk"
		a: [1 3 2 4]
		b: [3 4 5 4 6]
		--assert [3 4 5 6]		= unique b
		--assert [1 3 2 4 5 6]	= union a b
		--assert [3 4]			= intersect a b
		--assert [1 2 5 6]		= difference a b
		--assert [1 2]			= exclude a b
		--assert [5 6]			= exclude b a

	--test-- "set-op-str"
		a: "CBAD"
		b: "EDCCF"
		--assert "EDCF"		= unique b
		--assert "CBADEF"	= union a b
		--assert "CD"		= intersect a b
		--assert "BAEF"		= difference a b
		--assert "BA"		= exclude a b
		--assert "EF"		= exclude b a

	--test-- "set-op-bitset"
		a: make bitset! [1 2 3 4]
		b: make bitset! [4 5 23]
		--assert b		= unique b
		--assert "make bitset! #{7C0001}" = mold union a b
		--assert "make bitset! #{080000}" = mold intersect a b
		--assert "make bitset! #{740001}" = mold difference a b
		--assert "make bitset! #{700000}" = mold exclude a b
		--assert "make bitset! #{040001}" = mold exclude b a

===end-group===

~~~end-file~~~


FEAT: enhanced Tab completion for console

Red [
	Title:	"INPUT prototype for Unix platforms"
	Author: "Nenad Rakocevic"
	File: 	%input.red
	Tabs: 	4
	Rights: "Copyright (C) 2014 Nenad Rakocevic. All rights reserved."
	License: {
		Distributed under the Boost Software License, Version 1.0.
		See https://github.com/dockimbel/Red/blob/master/BSL-License.txt
	}
	Notes: {
		Freely inspired by linenoise fork from msteveb:
		https://github.com/msteveb/linenoise/blob/master/linenoise.c
	}
]

complete-from-path: func [
	str [string!]
	/local s result word w1 ptr words first? sys-word
][
	result: make block! 4
	first?: yes
	s: ptr: str
	while [ptr: find str #"/"][
		word: to word! copy/part str ptr
		either first? [
			if value? word [
				w1: get word
				first?: no
			]
		][
			w1: get in w1 word
		]
		str: either object? w1 [next ptr][""]
	]
	if any [function? w1 action? w1 native? w1 routine? w1] [
		word: find/last/tail s #"/"
		words: make block! 4
		foreach w spec-of w1 [
			if refinement? w [append words w]
		]
	]
	if object? w1 [
		word: str
		words: words-of w1
	]
	if words [
		foreach w words [
			sys-word: form w
			if any [empty? word find/match sys-word word] [
				append result sys-word
			]
		]
	]

	if 1 = length? result [
		poke result 1 append copy/part s word result/1
	]
	result
]

default-input-completer: func [
	str  [string!]
	/local word ptr result sys-word delim? len insert? start end
][
	result: make block! 4
	delimiters: [#" " #"[" #"(" #":" #"'"]
	delim?: no
	insert?: not tail? str
	len: (index? str) - 1
	end: str
	ptr: str: head str
	foreach d delimiters [
		word: find/last/tail/part str d len
		if all [word (index? ptr) < (index? word)] [ptr: word]
	]
	either head? ptr [start: str][start: ptr delim?: yes]
	word: copy/part start end
	unless empty? word [
		either all [
			#"/" <> word/1
			ptr: find word #"/"
			#" " <> pick ptr -1
		][
			result: complete-from-path word
		][
			foreach w system/words [
				if value? w [
					sys-word: mold w
					if find/match sys-word word [
						append result sys-word
					]
				]
			]
		]
	]
	if 1 = length? result [
		either word = result/1 [
			clear result
		][
			either any [insert? delim?] [
				str: append copy/part str start result/1
				poke result 1 tail str
				if insert? [append str end]
			][
				poke result 1 tail result/1
			]
		]
	]
	result
]

#system [
	terminal: context [

		#enum special-key! [
			KEY_UNSET:		 -1
			KEY_NONE:		  0
			KEY_UP:			-20
			KEY_DOWN:		-21
			KEY_RIGHT:		-22
			KEY_LEFT:		-23
			KEY_END:		-24
			KEY_HOME:		-25
			KEY_INSERT:		-26
			KEY_DELETE:		-27
			KEY_PAGE_UP:	-28
			KEY_PAGE_DOWN:	-29
			KEY_ESC:		-30
		]

		#define KEY_CTRL_A		1
		#define KEY_CTRL_B		2
		#define KEY_CTRL_C		3
		#define KEY_CTRL_D		4
		#define KEY_CTRL_E		5
		#define KEY_CTRL_F		6
		#define KEY_CTRL_H		8
		#define KEY_TAB			9
		#define KEY_CTRL_K		11
		#define KEY_CTRL_L		12
		#define KEY_ENTER		13
		#define KEY_CTRL_N		14
		#define KEY_CTRL_P		16
		#define KEY_CTRL_T		20
		#define KEY_CTRL_U		21
		#define KEY_CTRL_W		23
		#define KEY_ESCAPE		27
		#define KEY_BACKSPACE	127

		#include %wcwidth.reds

		#either OS = 'Windows [
			#include %win32.reds
		][
			#include %POSIX.reds
		]

		buffer:		declare byte-ptr!
		pbuffer:	declare byte-ptr!
		input-line: declare red-string!
		saved-line:	declare red-string!
		prompt:		declare	red-string!
		history:	declare red-block!
		buf-size:	128
		columns:	-1
		rows:		-1
		output?:	yes

		string/rs-make-at as cell! saved-line 1

		widechar?: func [
			str			[red-string!]
			return:		[logic!]
			/local
				cp		[integer!]
				unit	[integer!]
				s		[series!]
				offset	[byte-ptr!]
		][
			s: GET_BUFFER(str)
			unit: GET_UNIT(s)
			offset: (as byte-ptr! s/offset) + (str/head << (unit >> 1))
			cp: 0
			if offset < as byte-ptr! s/tail [cp: string/get-char offset unit]
			cp > FFh
		]

		on-resize: does [
			get-window-size
			refresh
		]

		complete-line: func [
			str			[red-string!]
			return:		[integer!]
			/local
				line	[red-string!]
				result	[red-block!]
				num		[integer!]
				str2	[red-string!]
				head	[integer!]
		][
			#call [default-input-completer str]
			result: as red-block! stack/arguments
			num: block/rs-length? result
			unless zero? num [
				head: str/head
				str/head: 0
				string/copy str saved-line stack/arguments yes stack/arguments
				saved-line/head: head
				line: input-line
				string/rs-reset line

				either num = 1 [
					str2: as red-string! block/rs-head result
					head: str2/head
					str2/head: 0
					string/concatenate line str2 -1 0 yes no
					line/head: head
				][
					until [
						string/concatenate line as red-string! block/rs-head result -1 0 yes no
						string/append-char GET_BUFFER(line) 32
						block/rs-next result
						block/rs-tail? result
					]
					line/head: string/get-length line yes
				]
				refresh
			]
			num
		]

		add-history: func [
			str			[red-string!]
			/local
				saved	[integer!]
		][
			str/head: 0
			unless zero? string/rs-length? str [
				block/rs-append history as red-value! str		;TBD Don't add duplicated lines.
			]
		]

		fetch-history: does [
			string/rs-reset input-line
			string/concatenate input-line as red-string! block/rs-head history -1 0 yes no
			input-line/head: string/get-length input-line yes
		]

		init-buffer: func [
			str			[red-string!]
			prompt		[red-string!]
			/local
				unit	[integer!]
				s		[series!]
				size	[integer!]
		][
			s: GET_BUFFER(str)
			unit: GET_UNIT(s)
			if unit < 2 [unit: 2]			;-- always treat string as widechar string
			size: (string/get-length str yes) << (unit >> 1)
			size: size + (string/get-length prompt yes) << (unit >> 1)
			if size > buf-size [
				buf-size: size
				free buffer
				buffer: allocate size
			]
			pbuffer: buffer
		]

		emit-red-string: func [
			str			[red-string!]
			size		[integer!]
			head-as-tail? [logic!]
			return: 	[integer!]
			/local
				series	[series!]
				offset	[byte-ptr!]
				tail	[byte-ptr!]
				unit	[integer!]
				cp		[integer!]
				bytes	[integer!]
				cnt		[integer!]
				x		[integer!]
				w		[integer!]
		][
			x:		0
			w:		0
			cnt:	0
			bytes:	0
			series: GET_BUFFER(str)
			unit: 	GET_UNIT(series)
			offset: (as byte-ptr! series/offset) + (str/head << (unit >> 1))
			tail:   as byte-ptr! series/tail
			if head-as-tail? [
				tail: offset
				offset: as byte-ptr! series/offset
			]
			until [
				while [
					all [offset < tail cnt < size]
				][
					cp: string/get-char offset unit
					w: wcwidth? cp
					cnt: switch w [
						1  [cnt + 1]
						2  [either size - cnt = 1 [x: 2 cnt + 3][cnt + 2]]	;-- reach screen edge, handle wide char
						default [0]
					]
					emit-red-char cp
					offset: offset + unit
				]
				bytes: bytes + cnt
				size: columns - x
				x: 0
				cnt: 0
				offset >= tail
			]
			bytes
		]

		refresh: func [
			/local
				line   [red-string!]
				offset [integer!]
				bytes  [integer!]
				psize  [integer!]
		][
			line: input-line

			either output? [					;-- erase down to the bottom of the screen
				reset-cursor-pos
				erase-to-bottom
			][
				#if OS <> 'Windows [reset-cursor-pos][0]
			]
			init-buffer line prompt
			bytes: emit-red-string prompt columns no

			psize: bytes // columns
			offset: bytes + (emit-red-string line columns - psize yes)	;-- output until reach cursor posistion

			psize: offset // columns
			bytes: offset + (emit-red-string line columns - psize no)	;-- continue until reach tail

			either output? [
				output-to-screen
			][
				#if OS <> 'Windows [
					if all [
						bytes > columns
						positive? (bytes // columns)
					][
						psize: bytes / columns
						emit-string-int "^[[" psize  #"B"
					]
				][0]
			]
			set-cursor-pos line offset bytes
		]

		edit: func [
			prompt-str [red-string!]
			/local
				line   [red-string!]
				head   [integer!]
				c	   [integer!]
				n	   [integer!]
		][
			line: input-line
			copy-cell as red-value! prompt-str as red-value! prompt
			history/head: block/rs-length? history		;@@ set history list to tail (temporary)

			get-window-size
			unless zero? string/get-length saved-line yes [
				head: saved-line/head
				saved-line/head: 0
				string/concatenate line saved-line -1 0 yes no
				line/head: head
			]
			refresh

			while [true][
				output?: yes
				c: fd-read
				n: 0

				if c = KEY_TAB [
					n: complete-line line
					if n > 1 [
						string/rs-reset line
						exit
					]
					if zero? n [
						c: 32							;-- convert TAB to SPACE
					]
				]

				#if OS <> 'Windows [if c = 27 [c: check-special]]

				switch c [
					KEY_ENTER [
						add-history line
						string/rs-reset saved-line
						exit
					]
					KEY_CTRL_H
					KEY_BACKSPACE [
						unless zero? line/head [
							line/head: line/head - 1
							string/remove-char line line/head
							if string/rs-tail? line [output?: no]
							refresh
							unless output? [erase-to-bottom]
						]
					]
					KEY_CTRL_B
					KEY_LEFT [
						unless zero? line/head [
							line/head: line/head - 1
							output?: no
							refresh
						]
					]
					KEY_CTRL_F
					KEY_RIGHT [
						if 0 < string/rs-length? line [
							line/head: line/head + 1
							output?: no
							refresh
						]
					]
					KEY_CTRL_P
					KEY_UP [
						unless zero? history/head [
							history/head: history/head - 1
							fetch-history
							line/head: string/get-length line yes
							refresh
						]
					]
					KEY_CTRL_N
					KEY_DOWN [
						unless block/rs-tail? history [
							history/head: history/head + 1
							either block/rs-tail? history [
								string/rs-reset line
							][
								fetch-history
							]
							refresh
						]
					]
					KEY_CTRL_A
					KEY_HOME [
						line/head: 0
						refresh
					]
					KEY_CTRL_E
					KEY_END [
						line/head: string/get-length line yes
						refresh
					]
					KEY_DELETE [
						unless string/rs-tail? line [
							string/remove-char line line/head
							refresh
						]
					]
					KEY_CTRL_C
					KEY_CTRL_D [
						string/rs-reset line
						string/append-char GET_BUFFER(line) as-integer #"q"
						exit
					]
					KEY_ESCAPE [
						string/append-char GET_BUFFER(line) c
						exit
					]
					default [
						if c > 31 [
							either string/rs-tail? line [
								string/append-char GET_BUFFER(line) c
								#if OS = 'Windows [					;-- optimize for Windows
									pbuffer: buffer
									emit-red-char c
									output-to-screen
									pbuffer: buffer
									output?: no
								]
							][
								string/insert-char GET_BUFFER(line) line/head c
							]
							line/head: line/head + 1
							refresh
						]
					]
				]
			]
			line/head: 0
		]
	]
]

set-buffer-history: routine [line [string!] hist [block!]][
	terminal/init line hist
]

read-input: routine [prompt [string!]][
	terminal/edit prompt
	terminal/restore
	print-line ""
]

ask: function [
	question [string!]
	return:  [string!]
][
	buffer: make string! 1
	set-buffer-history buffer head system/console/history
	read-input question
	buffer
]

input: does [ask ""]

Red [
	Title:	"INPUT prototype for Unix platforms"
	Author: "Nenad Rakocevic"
	File: 	%input.red
	Tabs: 	4
	Rights: "Copyright (C) 2014 Nenad Rakocevic. All rights reserved."
	License: {
		Distributed under the Boost Software License, Version 1.0.
		See https://github.com/dockimbel/Red/blob/master/BSL-License.txt
	}
	Notes: {
		Freely inspired by linenoise fork from msteveb:
		https://github.com/msteveb/linenoise/blob/master/linenoise.c
	}
]

complete-from-path: func [
	str [string!]
	/local s result word w1 ptr words first? sys-word
][
	result: make block! 4
	first?: yes
	s: ptr: str
	while [ptr: find str #"/"][
		word: to word! copy/part str ptr
		either first? [
			if value? word [
				w1: get word
				first?: no
			]
		][
			w1: get in w1 word
		]
		str: either object? w1 [next ptr][""]
	]
	if any [function? w1 action? w1 native? w1 routine? w1] [
		word: find/last/tail s #"/"
		words: make block! 4
		foreach w spec-of w1 [
			if refinement? w [append words w]
		]
	]
	if object? w1 [
		word: str
		words: words-of w1
	]
	if words [
		foreach w words [
			sys-word: form w
			if any [empty? word find/match sys-word word] [
				append result sys-word
			]
		]
	]

	if 1 = length? result [
		poke result 1 append copy/part s word result/1
	]
	result
]

default-input-completer: func [
	str [string!]
	/local word ptr result sys-word delim?
][
	result: make block! 4
	delimiters: [#" " #"[" #"(" #":" #"'"]
	delim?: no
	ptr: str: head str
	foreach d delimiters [
		word: find/last/tail str d
		if all [word (index? ptr) < (index? word)] [ptr: word]
	]
	either head? ptr [word: str][word: ptr delim?: yes]
	unless empty? word [
		either all [
			#"/" <> word/1
			ptr: find word #"/"
			#" " <> pick ptr -1
		][
			result: complete-from-path word
		][
			foreach w system/words [
				if value? w [
					sys-word: mold w
					if find/match sys-word word [
						append result sys-word
					]
				]
			]
		]
	]
	if 1 = length? result [
		either word = result/1 [
			clear result
		][
			if delim? [
				poke result 1 append copy/part str word result/1
			]
		]
	]
	result
]

#system [
	terminal: context [

		#enum special-key! [
			KEY_UNSET:		 -1
			KEY_NONE:		  0
			KEY_UP:			-20
			KEY_DOWN:		-21
			KEY_RIGHT:		-22
			KEY_LEFT:		-23
			KEY_END:		-24
			KEY_HOME:		-25
			KEY_INSERT:		-26
			KEY_DELETE:		-27
			KEY_PAGE_UP:	-28
			KEY_PAGE_DOWN:	-29
			KEY_ESC:		-30
		]

		#define KEY_CTRL_A		1
		#define KEY_CTRL_B		2
		#define KEY_CTRL_C		3
		#define KEY_CTRL_D		4
		#define KEY_CTRL_E		5
		#define KEY_CTRL_F		6
		#define KEY_CTRL_H		8
		#define KEY_TAB			9
		#define KEY_CTRL_K		11
		#define KEY_CTRL_L		12
		#define KEY_ENTER		13
		#define KEY_CTRL_N		14
		#define KEY_CTRL_P		16
		#define KEY_CTRL_T		20
		#define KEY_CTRL_U		21
		#define KEY_CTRL_W		23
		#define KEY_ESCAPE		27
		#define KEY_BACKSPACE	127

		#include %wcwidth.reds

		#either OS = 'Windows [
			#include %win32.reds
		][
			#include %POSIX.reds
		]

		buffer:		declare byte-ptr!
		pbuffer:	declare byte-ptr!
		input-line: declare red-string!
		saved-line:	declare red-string!
		prompt:		declare	red-string!
		history:	declare red-block!
		buf-size:	128
		columns:	-1
		rows:		-1
		output?:	yes

		string/rs-make-at as cell! saved-line 1

		widechar?: func [
			str			[red-string!]
			return:		[logic!]
			/local
				cp		[integer!]
				unit	[integer!]
				s		[series!]
				offset	[byte-ptr!]
		][
			s: GET_BUFFER(str)
			unit: GET_UNIT(s)
			offset: (as byte-ptr! s/offset) + (str/head << (unit >> 1))
			cp: 0
			if offset < as byte-ptr! s/tail [cp: string/get-char offset unit]
			cp > FFh
		]

		on-resize: does [
			get-window-size
			refresh
		]

		complete-line: func [
			str			[red-string!]
			return:		[integer!]
			/local
				line	[red-string!]
				result	[red-block!]
				num		[integer!]
		][
			#call [default-input-completer str]
			result: as red-block! stack/arguments
			num: block/rs-length? result
			unless zero? num [
				line: input-line
				if num > 1 [
					str/head: 0
					string/copy str saved-line stack/arguments yes stack/arguments
				]

				string/rs-reset line
				until [
					string/concatenate line as red-string! block/rs-head result -1 0 yes no
					unless num = 1 [string/append-char GET_BUFFER(line) 32]
					block/rs-next result
					block/rs-tail? result
				]

				line/head: string/get-length line yes
				refresh
			]
			num
		]

		add-history: func [
			str			[red-string!]
			/local
				saved	[integer!]
		][
			str/head: 0
			unless zero? string/rs-length? str [
				block/rs-append history as red-value! str		;TBD Don't add duplicated lines.
			]
		]

		fetch-history: does [
			string/rs-reset input-line
			string/concatenate input-line as red-string! block/rs-head history -1 0 yes no
			input-line/head: string/get-length input-line yes
		]

		init-buffer: func [
			str			[red-string!]
			prompt		[red-string!]
			/local
				unit	[integer!]
				s		[series!]
				size	[integer!]
		][
			s: GET_BUFFER(str)
			unit: GET_UNIT(s)
			if unit < 2 [unit: 2]			;-- always treat string as widechar string
			size: (string/get-length str yes) << (unit >> 1)
			size: size + (string/get-length prompt yes) << (unit >> 1)
			if size > buf-size [
				buf-size: size
				free buffer
				buffer: allocate size
			]
			pbuffer: buffer
		]

		emit-red-string: func [
			str			[red-string!]
			size		[integer!]
			head-as-tail? [logic!]
			return: 	[integer!]
			/local
				series	[series!]
				offset	[byte-ptr!]
				tail	[byte-ptr!]
				unit	[integer!]
				cp		[integer!]
				bytes	[integer!]
				cnt		[integer!]
				x		[integer!]
				w		[integer!]
		][
			x:		0
			w:		0
			cnt:	0
			bytes:	0
			series: GET_BUFFER(str)
			unit: 	GET_UNIT(series)
			offset: (as byte-ptr! series/offset) + (str/head << (unit >> 1))
			tail:   as byte-ptr! series/tail
			if head-as-tail? [
				tail: offset
				offset: as byte-ptr! series/offset
			]
			until [
				while [
					all [offset < tail cnt < size]
				][
					cp: string/get-char offset unit
					w: wcwidth? cp
					cnt: switch w [
						1  [cnt + 1]
						2  [either size - cnt = 1 [x: 2 cnt + 3][cnt + 2]]	;-- reach screen edge, handle wide char
						default [0]
					]
					emit-red-char cp
					offset: offset + unit
				]
				bytes: bytes + cnt
				size: columns - x
				x: 0
				cnt: 0
				offset >= tail
			]
			bytes
		]

		refresh: func [
			/local
				line   [red-string!]
				offset [integer!]
				bytes  [integer!]
				psize  [integer!]
		][
			line: input-line

			either output? [					;-- erase down to the bottom of the screen
				reset-cursor-pos
				erase-to-bottom
			][
				#if OS <> 'Windows [reset-cursor-pos][0]
			]
			init-buffer line prompt
			bytes: emit-red-string prompt columns no

			psize: bytes // columns
			offset: bytes + (emit-red-string line columns - psize yes)	;-- output until reach cursor posistion

			psize: offset // columns
			bytes: offset + (emit-red-string line columns - psize no)	;-- continue until reach tail

			either output? [
				output-to-screen
			][
				#if OS <> 'Windows [
					if all [
						bytes > columns
						positive? (bytes // columns)
					][
						psize: bytes / columns
						emit-string-int "^[[" psize  #"B"
					]
				][0]
			]
			set-cursor-pos line offset bytes
		]

		edit: func [
			prompt-str [red-string!]
			/local
				line   [red-string!]
				c	   [integer!]
				n	   [integer!]
		][
			line: input-line
			copy-cell as red-value! prompt-str as red-value! prompt
			history/head: block/rs-length? history		;@@ set history list to tail (temporary)

			get-window-size
			unless zero? string/rs-length? saved-line [
				string/concatenate line saved-line -1 0 yes no
				line/head: string/get-length line yes
			]
			refresh

			while [true][
				output?: yes
				c: fd-read
				n: 0

				if c = KEY_TAB [
					n: complete-line line
					if n > 1 [
						string/rs-reset line
						exit
					]
					if zero? n [
						c: 32							;-- convert TAB to SPACE
					]
				]

				#if OS <> 'Windows [if c = 27 [c: check-special]]

				switch c [
					KEY_ENTER [
						add-history line
						string/rs-reset saved-line
						exit
					]
					KEY_CTRL_H
					KEY_BACKSPACE [
						unless zero? line/head [
							line/head: line/head - 1
							string/remove-char line line/head
							if string/rs-tail? line [output?: no]
							refresh
							unless output? [erase-to-bottom]
						]
					]
					KEY_CTRL_B
					KEY_LEFT [
						unless zero? line/head [
							line/head: line/head - 1
							output?: no
							refresh
						]
					]
					KEY_CTRL_F
					KEY_RIGHT [
						if 0 < string/rs-length? line [
							line/head: line/head + 1
							output?: no
							refresh
						]
					]
					KEY_CTRL_P
					KEY_UP [
						unless zero? history/head [
							history/head: history/head - 1
							fetch-history
							line/head: string/get-length line yes
							refresh
						]
					]
					KEY_CTRL_N
					KEY_DOWN [
						unless block/rs-tail? history [
							history/head: history/head + 1
							either block/rs-tail? history [
								string/rs-reset line
							][
								fetch-history
							]
							refresh
						]
					]
					KEY_CTRL_A
					KEY_HOME [
						line/head: 0
						refresh
					]
					KEY_CTRL_E
					KEY_END [
						line/head: string/get-length line yes
						refresh
					]
					KEY_DELETE [
						unless string/rs-tail? line [
							string/remove-char line line/head
							refresh
						]
					]
					KEY_CTRL_C
					KEY_CTRL_D [
						string/rs-reset line
						string/append-char GET_BUFFER(line) as-integer #"q"
						exit
					]
					KEY_ESCAPE [
						string/append-char GET_BUFFER(line) c
						exit
					]
					default [
						if c > 31 [
							either string/rs-tail? line [
								string/append-char GET_BUFFER(line) c
								#if OS = 'Windows [					;-- optimize for Windows
									pbuffer: buffer
									emit-red-char c
									output-to-screen
									pbuffer: buffer
									output?: no
								]
							][
								string/insert-char GET_BUFFER(line) line/head c
							]
							line/head: line/head + 1
							refresh
						]
					]
				]
			]
			line/head: 0
		]
	]
]

set-buffer-history: routine [line [string!] hist [block!]][
	terminal/init line hist
]

read-input: routine [prompt [string!]][
	terminal/edit prompt
	terminal/restore
	print-line ""
]

ask: function [
	question [string!]
	return:  [string!]
][
	buffer: make string! 1
	set-buffer-history buffer head system/console/history
	read-input question
	buffer
]

input: does [ask ""]


reformatted letter from authors

reformatted letter from authors

git-svn-id: 50a8ad97cae5d6ab203d2d535a9b32cd3858a8ac@342 c04ce798-636b-4ca8-9149-0f9336831111

h1. Getting Started

*Dear build -monkey- -master- artist,*

We created CruiseControl.rb so that you can kick ass.

We want you to have basic continuous integration up and running 10 minutes after reading this page.
After that, we want you to find that the tool looks good, does what you expect, and basically just
works. Finally, when you need to do something unusual, we want you to be surprised by how easy that was, too.

In short, we want you to *love* CruiseControl.rb.

Very truly yours,

CruiseControl.rb team

ThoughtWorks

P.S. We also want to know if we somehow fall short of these goals.

h1. Basics

CruiseControl.rb has two parts: a builder and a dashboard.

*Builder* is a daemon process that polls source control every once in a while for new revisions.

When someone performs a check in, the builder:

# detects it
# updates its own copy of the project
# runs the build
# notifies interested parties about the build's outcome

*Dashboard* is a web application that helps to monitor the status of project builds and troubleshoot failures.

Each installation of CruiseControl.rb may have multiple projects and multiple builders (one per project). There may
also be multiple installations of CruiseControl.rb per computer.

h1. Prerequisites

* "Ruby":http://www.ruby-lang.org/en/ 1.8.4 or later
* "Subversion":http://subversion.tigris.org/ client 1.3.2 or later
* svn and ruby executables must both be in the PATH.

h1. Assumptions and limitations

* CruiseControl.rb currently only works with Subversion.
* Dashboard and all builders need to run on the same computer.

h1. Installation

Follow these directions or watch our "5 minute install":screencasts.html screencast.

1. "Download":download.html and unpack CruiseControl.rb

  p(def). (below, we will refer to the place where you unpack it as [cruise])

2. From [cruise], run ./cruise add your_project --url [URL of your_project Subversion trunk].

  p(def). Optionally, you can specify username and password by adding  --username [your_user] --password
    [your_password] to the command.

  p(def). This creates a directory for your_project's builds at
    [cruise]/builds/your_project/, and checks out your_project from subversion URL specified to
    [cruise]/builds/your_project/work/.

  p(def hint). Hint: Rakefile of your_project should be in [cruise]/builds/your_project/work/ directory, not anywhere under
    it. A common mistake is to specify in --url option the root of project's SVN repository instead of the trunk.
    Rakefile then ends up in [cruise]/builds/your_project/work/trunk/ and CruiseControl.rb does not see it there.

3. From [cruise], run ./cruise start.

  p(def hint). Hint: This starts cruise on port 3333, if you want to run your server on a different port, just type
    ./cruise start -p [port]

4. Browse to "http://localhost:3333":http://localhost:3333.

  p(def). All going well, weather permitting, you will see a page with CruiseControl.rb logo. This is the dashboard, and it
    should display your project.  If it's passing, you're done - though you should double check it's doing what it should be
    by clicking on the project name and looking at the build log for the last build.  If it's failing or otherwise misbehaving, go
    on to step 5.

5. Go to [cruise]/builds/your_project/work/ and make the build pass.

  p(def). For a regular Rails app, this involves creating a test database, editing database.yml to connect to that
    database, performing rake RAILS_ENV=test db:migrate, running rake test and making
    sure that it passes.

6. Press the "build now" button on the "Dashboard":http://localhost:3333 to rebuild your project

  p(def). This should build your_project and place build outputs into [cruise]/builds/your_project/build-[revision-number]/

  p(def hint). Hint: Monitor log/your_project_builder.log for any signs of trouble. Try to check in a change to
    your_project and see if the builder can detect and build it.  Check your_project status in the dashboard.

  p(def hint). Hint: ./cruise help displays a list of commands, ./cruise help [command]
    displays options available for each command.

Next step: read the "manual":manual.html


correct typo: attributs => attributes

correct typo: attributs => attributes

Red [
	Title:	"Console help functions"
	Author:	["Ingo Hohmann" "Nenad Rakocevic"]
	File:	%help.red
	Tabs:	4
	Rights:	"Copyright (C) 2014 Ingo Hohmann, Nenad Rakocevic. All rights reserved."
	License: {
		Distributed under the Boost Software License, Version 1.0.
		See https://github.com/dockimbel/Red/blob/master/BSL-License.txt
	}
]

help: func [
	"Get help for functions"
	'word [any-type!] "Word you are looking for"
	/local func-name desc spec tab tab4 tab8 type start attributes info fun w ref block
][
	tab: tab4: "    "
	tab8: "        "

	case [
		unset? :word [								;-- HELP with no arguments
			print {Use HELP or ? to see built-in info:

    help insert
    ? insert

To see all words of a specific datatype:

    ? native!
    ? function!
    ? datatype!

Other debug functions:

    ?? - display a variable and its value
    probe - print a value (molded)
    source func - show source code of func
    what - show a list of known functions
}
		]
		datatype? get :word [						;-- HELP <datatype!>
			type: get :word
			foreach w system/words [
				if type = type? get w [
					either any [function? get w native? get w action? get w][
						prin [tab w]
						spec: spec-of get w

						either any [
							string? desc: spec/1
							string? desc: spec/2					;-- attributes block case
						][
							print ["^-=> " desc]
						][
							prin lf
						]
					][
						print [tab :w "^-: " mold get w]
					]
				]
			]
		]
		'else [
			func-name: :word

			argument-rule: [
				set word [word! | lit-word! | get-word!]
				(prin [tab mold word])
				opt [set type block!  (prin [#" " mold type])]
				opt [set info string! (prin [" =>" append form info dot])]
				(prin lf)
			]

			either all [
				word? func-name
				fun: get func-name
				any [action? :fun function? :fun native? :fun]
			][
		;		print ["^/" func-name "is of type" type? :fun newline]
				prin ["^/USAGE:^/" tab func-name]

				parse spec-of :fun [
					start: any [						;-- 1st pass
						/local to end
						| set w word! (prin [" " w])
						| set w [lit-word! | refinement!] (prin [" " mold w])
						| skip
					]

					:start								;-- 2nd pass
					opt [set attributes block! (prin ["^/^/ATTRIBUTES:^/" tab mold attributes])]
					opt [set info string! (print ["^/^/DESCRIPTION:^/" tab append form info dot])]

					(print "^/ARGUMENTS:")
					any [argument-rule (prin lf)]

					(print "REFINEMENTS:")
					any [
						/local [
							to ahead set-word! 'return set block block!
							(print ["^/RETURN:^/" mold block])
							| to end
						]
						| [
							set ref refinement! (prin [tab mold ref])
							opt [set info string! (prin [" =>" append form info dot])]
							(tab: tab8 prin lf)
							any [argument-rule]
							(tab: tab4)
						]
					]
				]
			][
				print [
					func-name "is of type"
					mold type? either word? :func-name [:fun][:func-name]
					"^/No more help available."
				]
			]
		]
	]
	exit												;-- return unset value
]

?: :help

what: function [
	"Lists all functions, or words of a given type"
][
	foreach w system/words [
		if any [function? get w native? get w action? get w][
			prin w
			spec: spec-of get w

			either any [
				string? desc: spec/1
				string? desc: spec/2					;-- attributes block case
			][
				print [tab "=> " desc]
			][
				prin lf
			]
		]
	]
	exit												;-- return unset value
]

source: function [
	"Print the source of a function"
	'func-name [any-word!] "The name of the function"
][
	print either function? get func-name [
		[append mold func-name #":" mold get func-name]
	][
		["Sorry," func-name "is a" type? :func-name "so no source is available"]
	]
]

Red [
	Title:	"Console help functions"
	Author:	["Ingo Hohmann" "Nenad Rakocevic"]
	File:	%help.red
	Tabs:	4
	Rights:	"Copyright (C) 2014 Ingo Hohmann, Nenad Rakocevic. All rights reserved."
	License: {
		Distributed under the Boost Software License, Version 1.0.
		See https://github.com/dockimbel/Red/blob/master/BSL-License.txt
	}
]

help: func [
	"Get help for functions"
	'word [any-type!] "Word you are looking for"
	/local func-name desc spec tab tab4 tab8 type start attributs info fun w ref block
][
	tab: tab4: "    "
	tab8: "        "

	case [
		unset? :word [								;-- HELP with no arguments
			print {Use HELP or ? to see built-in info:

    help insert
    ? insert

To see all words of a specific datatype:

    ? native!
    ? function!
    ? datatype!

Other debug functions:

    ?? - display a variable and its value
    probe - print a value (molded)
    source func - show source code of func
    what - show a list of known functions
}
		]
		datatype? get :word [						;-- HELP <datatype!>
			type: get :word
			foreach w system/words [
				if type = type? get w [
					either any [function? get w native? get w action? get w][
						prin [tab w]
						spec: spec-of get w

						either any [
							string? desc: spec/1
							string? desc: spec/2					;-- attributs block case
						][
							print ["^-=> " desc]
						][
							prin lf
						]
					][
						print [tab :w "^-: " mold get w]
					]
				]
			]
		]
		'else [
			func-name: :word

			argument-rule: [
				set word [word! | lit-word! | get-word!]
				(prin [tab mold word])
				opt [set type block!  (prin [#" " mold type])]
				opt [set info string! (prin [" =>" append form info dot])]
				(prin lf)
			]

			either all [
				word? func-name
				fun: get func-name
				any [action? :fun function? :fun native? :fun]
			][
		;		print ["^/" func-name "is of type" type? :fun newline]
				prin ["^/USAGE:^/" tab func-name]

				parse spec-of :fun [
					start: any [						;-- 1st pass
						/local to end
						| set w word! (prin [" " w])
						| set w [lit-word! | refinement!] (prin [" " mold w])
						| skip
					]

					:start								;-- 2nd pass
					opt [set attributs block! (prin ["^/^/ATTRIBUTS:^/" tab mold attributs])]
					opt [set info string! (print ["^/^/DESCRIPTION:^/" tab append form info dot])]

					(print "^/ARGUMENTS:")
					any [argument-rule (prin lf)]

					(print "REFINEMENTS:")
					any [
						/local [
							to ahead set-word! 'return set block block!
							(print ["^/RETURN:^/" mold block])
							| to end
						]
						| [
							set ref refinement! (prin [tab mold ref])
							opt [set info string! (prin [" =>" append form info dot])]
							(tab: tab8 prin lf)
							any [argument-rule]
							(tab: tab4)
						]
					]
				]
			][
				print [
					func-name "is of type"
					mold type? either word? :func-name [:fun][:func-name]
					"^/No more help available."
				]
			]
		]
	]
	exit												;-- return unset value
]

?: :help

what: function [
	"Lists all functions, or words of a given type"
][
	foreach w system/words [
		if any [function? get w native? get w action? get w][
			prin w
			spec: spec-of get w

			either any [
				string? desc: spec/1
				string? desc: spec/2					;-- attributs block case
			][
				print [tab "=> " desc]
			][
				prin lf
			]
		]
	]
	exit												;-- return unset value
]

source: function [
	"Print the source of a function"
	'func-name [any-word!] "The name of the function"
][
	print either function? get func-name [
		[append mold func-name #":" mold get func-name]
	][
		["Sorry," func-name "is a" type? :func-name "so no source is available"]
	]
]


TESTS: adds CATCH/NAME tests with block argument.

Red [
  Title:   "Red CATCH/THROW test script"
  Author:  "Nenad Rakocevic"
  File:    %throw-test.reds
  Tabs:    4
  Rights:  "Copyright (C) 2011-2012 Nenad Rakocevic. All rights reserved."
  License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include  %../../../quick-test/quick-test.red

~~~start-file~~~ "catch/throw"

===start-group=== "Anonymous THROW"

	--test-- "an1" --assert 1  = catch [throw 1 --assert no]
	--test-- "an2" --assert 2  = catch [if true [throw 2 --assert no] --assert no]
	--test-- "an3" --assert 3  = catch [loop 1 [throw 3 --assert no] --assert no]
	--test-- "an4" --assert 4  = catch [while [true][throw 4 --assert no] --assert no]
	--test-- "an5" --assert 5  = catch [until [throw 5 --assert no] --assert no]
	--test-- "an6" --assert 6  = catch [6]
	--test-- "an7" --assert 7  = catch [4 + 3]
	--test-- "an8" --assert 8  = catch [do [throw 8 --assert no] --assert no]

	--test-- "an9"
		f: does [throw 9 --assert no]
		--assert 9 = catch [f]

	--test-- "an10"
		f: does [throw 10 --assert no]
		g: does [f --assert no]
		--assert 10 = catch [g]

	--test-- "an11" --assert 11 = catch [parse "1" [(throw 11 --assert no)] --assert no]

===end-group===

===start-group=== "Named THROW"

	--test-- "name1" --assert 1  = catch [throw/name 1 'a --assert no]
	--test-- "name2" --assert 2  = catch/name [if true [throw/name 2 'a --assert no] --assert no] 'a
	--test-- "name3" --assert 3  = catch/name [loop 1 [throw/name 3 'b --assert no] --assert no] 'b
	--test-- "name4" --assert 4  = catch/name [while [true][throw/name 4 'c --assert no] --assert no] 'c
	--test-- "name5" --assert 5  = catch/name [until [throw/name 5 'd --assert no] --assert no] 'd
	--test-- "name6" --assert 6  = catch/name [do [throw/name 6 'e --assert no] --assert no] 'e

	--test-- "name7"
		f: does [throw/name 7 'i --assert no]
		--assert 7 = catch/name [f] 'i

	--test-- "name8"
		f: does [throw/name 10 'j --assert no]
		g: does [f --assert no]
		--assert 10 = catch/name [g] 'j

	--test-- "name9"
		--assert 1 = catch/name [
			catch/name [throw/name 1 'hello	--assert no] 'world
			--assert no
		] 'hello

	--test-- "name10"
		--assert 123 = catch/name [
			--assert 2 = catch [throw/name 2 'hello --assert no]
			123
		] 'hello

	--test-- "name11"
		--assert 1 = catch [
			catch/name [throw/name 1 'hello	--assert no] 'world
			--assert yes
		]

	--test-- "name31" --assert 1  = catch [throw/name 1 'a --assert no]
	--test-- "name32" --assert 2  = catch/name [if true [throw/name 2 'a --assert no] --assert no] [a b]
	--test-- "name33" --assert 3  = catch/name [loop 1 [throw/name 3 'b --assert no] --assert no] [a b]
	--test-- "name34" --assert 4  = catch/name [while [true][throw/name 4 'c --assert no] --assert no] [a c]
	--test-- "name35" --assert 5  = catch/name [until [throw/name 5 'd --assert no] --assert no] [d]
	--test-- "name36" --assert 6  = catch/name [do [throw/name 6 'e --assert no] --assert no] [e d]

  	--test-- "name37"
  		f: does [throw/name 7 'i --assert no]
  		--assert 7 = catch/name [f][i]

  	--test-- "name38"
  		f: does [throw/name 10 'j --assert no]
  		g: does [f --assert no]
  		--assert 10 = catch/name [g][i j]

  	--test-- "name39"
  		--assert 1 = catch/name [
  			catch/name [throw/name 1 'hello	--assert no] 'world
  			--assert no
  		][hello]

  	--test-- "name40"
  		--assert 123 = catch/name [
  			--assert 2 = catch [throw/name 2 'hello --assert no]
  			123
  		][hi hello]

  	--test-- "name41"
  		--assert 1 = catch [
  			catch/name [throw/name 1 'hello	--assert no][world]
  			--assert yes
		]

===end-group===

~~~end-file~~~

Red [
  Title:   "Red CATCH/THROW test script"
  Author:  "Nenad Rakocevic"
  File: 	 %throw-test.reds
  Tabs:    4
  Rights:  "Copyright (C) 2011-2012 Nenad Rakocevic. All rights reserved."
  License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include  %../../../quick-test/quick-test.red

~~~start-file~~~ "catch/throw"

===start-group=== "Anonymous THROW"

	--test-- "an1" --assert 1  = catch [throw 1 --assert no]
	--test-- "an2" --assert 2  = catch [if true [throw 2 --assert no] --assert no]
	--test-- "an3" --assert 3  = catch [loop 1 [throw 3 --assert no] --assert no]
	--test-- "an4" --assert 4  = catch [while [true][throw 4 --assert no] --assert no]
	--test-- "an5" --assert 5  = catch [until [throw 5 --assert no] --assert no]
	--test-- "an6" --assert 6  = catch [6]
	--test-- "an7" --assert 7  = catch [4 + 3]
	--test-- "an8" --assert 8  = catch [do [throw 8 --assert no] --assert no]

	--test-- "an9"
		f: does [throw 9 --assert no]
		--assert 9 = catch [f]

	--test-- "an10"
		f: does [throw 10 --assert no]
		g: does [f --assert no]
		--assert 10 = catch [g]

	--test-- "an11" --assert 11 = catch [parse "1" [(throw 11 --assert no)] --assert no]

===end-group===

===start-group=== "Named THROW"

	--test-- "name1" --assert 1  = catch [throw/name 1 'a --assert no]
	--test-- "name2" --assert 2  = catch/name [if true [throw/name 2 'a --assert no] --assert no] 'a
	--test-- "name3" --assert 3  = catch/name [loop 1 [throw/name 3 'b --assert no] --assert no] 'b
	--test-- "name4" --assert 4  = catch/name [while [true][throw/name 4 'c --assert no] --assert no] 'c
	--test-- "name5" --assert 5  = catch/name [until [throw/name 5 'd --assert no] --assert no] 'd
	--test-- "name6" --assert 6  = catch/name [do [throw/name 6 'e --assert no] --assert no] 'e

	--test-- "name7"
		f: does [throw/name 7 'i --assert no]
		--assert 7 = catch/name [f] 'i

	--test-- "name8"
		f: does [throw/name 10 'j --assert no]
		g: does [f --assert no]
		--assert 10 = catch/name [g] 'j

	--test-- "name9"
		--assert 1 = catch/name [
			catch/name [throw/name 1 'hello	--assert no] 'world
			--assert no
		] 'hello

	--test-- "name10"
		--assert 123 = catch/name [
			--assert 2 = catch [throw/name 2 'hello --assert no]
			123
		] 'hello

	--test-- "name9"
		--assert 1 = catch [
			catch/name [throw/name 1 'hello	--assert no] 'world
			--assert yes
		]

===end-group===

~~~end-file~~~


FIX: set path on vector! does not support char! datatype