Version 0.2.0: RDB_ICASE, Changelog, --version, angepasste Man-Pages
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
Alle wichtigen Änderungen stehen hier. Das Format folgt
|
||||||
|
[Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die Versionsnummern
|
||||||
|
folgen [Semantic Versioning](https://semver.org/lang/de/). Die Version steht in
|
||||||
|
`lib/rdb/version.rb`; `rdb --version` zeigt sie an.
|
||||||
|
|
||||||
|
## [Unveröffentlicht]
|
||||||
|
|
||||||
|
## [0.2.0] - 2026-10-11
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- `RDB_ICASE=1` ignoriert Groß-/Kleinschreibung bei Spaltennamen. Ein exakter
|
||||||
|
Treffer gewinnt, mehrere Treffer sind ein Fehler; awk-Wörter und
|
||||||
|
Funktionsaufrufe bleiben unberührt.
|
||||||
|
- Man-Pages von `row`, `compute`, `column`, `sorttable`, `jointable`, `rename`,
|
||||||
|
`validate` und `rdb` mit dem Abschnitt „Case of Column Names“.
|
||||||
|
- `rdb man -g`: Man-Page mit groff formatiert, dazu `man/rdb.tmac` mit den
|
||||||
|
MWC-Makros (`.DM`, `.DE`, `.PC` ...).
|
||||||
|
- `rdb --version`, `CHANGELOG.md`.
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- `column` schreibt den Kopf in der Schreibweise der Tabelle, wenn die Spalte
|
||||||
|
existiert.
|
||||||
|
- `demo/ledger` und `demo/chart` verwenden echte Tabs.
|
||||||
|
|
||||||
|
## [0.1.0] - 2026-10-11
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- Erster Nachbau von /rdb in Ruby: ein Programm `bin/rdb` mit Symlinks für alle
|
||||||
|
dokumentierten Befehle (Relational, Text, Konvertierung, Schnellzugriff,
|
||||||
|
Berichte, Terminal, /act), 137 Man-Pages, Demo-Daten, 76 Tests, mise-Setup.
|
||||||
@@ -43,11 +43,19 @@ die meisten Befehle lesen beides.
|
|||||||
`row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie
|
`row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie
|
||||||
Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax.
|
Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax.
|
||||||
|
|
||||||
|
Spaltennamen unterscheiden Groß- und Kleinschreibung. Mit `RDB_ICASE=1` wird
|
||||||
|
sie ignoriert (Details unter „Unterschiede zum Original“):
|
||||||
|
|
||||||
|
```
|
||||||
|
RDB_ICASE=1 compute 'wert = cost * amount' < inventory
|
||||||
|
```
|
||||||
|
|
||||||
## Hilfe
|
## Hilfe
|
||||||
|
|
||||||
```
|
```
|
||||||
rdb alle Befehle
|
rdb alle Befehle
|
||||||
rdb man search die Original-Man-Page als Text (auch Themen: backup, dbase, dashline ...)
|
rdb man search die Original-Man-Page als Text (auch Themen: backup, dbase, dashline ...)
|
||||||
|
rdb --version Versionsnummer (Änderungen siehe CHANGELOG.md)
|
||||||
rdb man -g search dieselbe Seite mit groff formatiert (Beispiele sauber eingerückt)
|
rdb man -g search dieselbe Seite mit groff formatiert (Beispiele sauber eingerückt)
|
||||||
whatis column Beschreibung und Syntax
|
whatis column Beschreibung und Syntax
|
||||||
whatwill total Befehle, die zu einem Stichwort passen
|
whatwill total Befehle, die zu einem Stichwort passen
|
||||||
@@ -104,6 +112,14 @@ er nicht mehr passt (außer mit `-a`). Beide halten die Indizes aktuell.
|
|||||||
Handbuch sind als Tests enthalten (`test/rdb_test.rb`).
|
Handbuch sind als Tests enthalten (`test/rdb_test.rb`).
|
||||||
- Die Indexdateien haben ein eigenes, einfaches Format (das Original ist nicht
|
- Die Indexdateien haben ein eigenes, einfaches Format (das Original ist nicht
|
||||||
dokumentiert). Sie sind nicht mit alten /rdb-Dateien austauschbar.
|
dokumentiert). Sie sind nicht mit alten /rdb-Dateien austauschbar.
|
||||||
|
- Spaltennamen unterscheiden wie im Original Groß- und Kleinschreibung. Mit
|
||||||
|
`RDB_ICASE=1` (z. B. in `mise.toml` unter `[env]`) wird sie ignoriert:
|
||||||
|
ein exakter Treffer gewinnt, mehrere ähnliche sind ein Fehler. In
|
||||||
|
`row`/`compute`/`validate` bleiben awk-Wörter und Funktionsaufrufe unberührt
|
||||||
|
(eine Spalte `Length` verdeckt also nicht `length()`). Die Man-Pages von
|
||||||
|
`row`, `compute`, `column`, `sorttable`, `jointable`, `rename`, `validate` und
|
||||||
|
`rdb` haben dazu den Abschnitt „Case of Column Names“; er ist die einzige
|
||||||
|
Ergänzung gegenüber den Original-Seiten.
|
||||||
- `jointable` braucht keine vorsortierten Tabellen.
|
- `jointable` braucht keine vorsortierten Tabellen.
|
||||||
- `ve` ist ein zeilenorientierter Editor, kein Bildschirmeditor.
|
- `ve` ist ein zeilenorientierter Editor, kein Bildschirmeditor.
|
||||||
- `soundex` nutzt den Standard-Algorithmus. Die Beispielwerte im Handbuch
|
- `soundex` nutzt den Standard-Algorithmus. Die Beispielwerte im Handbuch
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Signal.trap('PIPE', 'SYSTEM_DEFAULT')
|
|||||||
if name == 'rdb'
|
if name == 'rdb'
|
||||||
case args.first
|
case args.first
|
||||||
when nil, '-h', '--help' then name = 'rdb.list'
|
when nil, '-h', '--help' then name = 'rdb.list'
|
||||||
|
when '-v', '--version' then puts "rdb #{Rdb::VERSION}"; exit
|
||||||
when 'install' then name = 'rdb.install'; args.shift
|
when 'install' then name = 'rdb.install'; args.shift
|
||||||
else name = args.shift
|
else name = args.shift
|
||||||
end
|
end
|
||||||
|
|||||||
+16
@@ -7,6 +7,7 @@ require 'open3'
|
|||||||
require 'date'
|
require 'date'
|
||||||
require 'tmpdir'
|
require 'tmpdir'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
require_relative 'rdb/version'
|
||||||
|
|
||||||
module Rdb
|
module Rdb
|
||||||
ROOT = File.expand_path('..', __dir__)
|
ROOT = File.expand_path('..', __dir__)
|
||||||
@@ -16,6 +17,21 @@ module Rdb
|
|||||||
COMMANDS = {}
|
COMMANDS = {}
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
# RDB_ICASE=1 makes column names match without regard to case. An exact
|
||||||
|
# match always wins; several case-insensitive matches are an error.
|
||||||
|
def icase?
|
||||||
|
!%w[0 no false].include?(ENV['RDB_ICASE'].to_s.downcase) && !ENV['RDB_ICASE'].to_s.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def column_index(head, name)
|
||||||
|
exact = head.index(name)
|
||||||
|
return exact if exact || !icase?
|
||||||
|
|
||||||
|
hits = head.each_index.select { |i| head[i].casecmp?(name) }
|
||||||
|
die "column name '#{name}' is ambiguous: #{hits.map { |i| head[i] }.join(', ')}" if hits.size > 1
|
||||||
|
hits.first
|
||||||
|
end
|
||||||
|
|
||||||
def die(msg)
|
def die(msg)
|
||||||
abort "#{File.basename($PROGRAM_NAME)}: #{msg}"
|
abort "#{File.basename($PROGRAM_NAME)}: #{msg}"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ Rdb.register('column', 'Display columns of a table in any order', 'column [ Colu
|
|||||||
t = table_in
|
t = table_in
|
||||||
next t.write if args.empty?
|
next t.write if args.empty?
|
||||||
|
|
||||||
idx = args.map { |a| t.head.index(a) }
|
idx = args.map { |a| Rdb.column_index(t.head, a) }
|
||||||
t.with(head: args, rows: t.rows.map { |r| idx.map { |i| i ? r[i] : '' } }).write
|
head = args.each_with_index.map { |a, n| idx[n] ? t.head[idx[n]] : a }
|
||||||
|
t.with(head: head, rows: t.rows.map { |r| idx.map { |i| i ? r[i] : '' } }).write
|
||||||
end
|
end
|
||||||
Rdb.alias_for('project', 'column')
|
Rdb.alias_for('project', 'column')
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,24 @@ module Rdb
|
|||||||
|
|
||||||
# Replace column names in an awk expression with $N, leaving strings,
|
# Replace column names in an awk expression with $N, leaving strings,
|
||||||
# regexes and other identifiers alone.
|
# regexes and other identifiers alone.
|
||||||
|
AWK_WORDS = %w[BEGIN END NR NF FS OFS ORS RS FNR FILENAME SUBSEP RSTART RLENGTH ENVIRON ARGC ARGV
|
||||||
|
if else while for do in break continue next exit return function delete getline
|
||||||
|
print printf length substr index split sub gsub match sprintf sin cos atan2 exp log
|
||||||
|
sqrt int rand srand tolower toupper system].freeze
|
||||||
|
|
||||||
|
# With RDB_ICASE, a word that is not an awk keyword or function call may
|
||||||
|
# name a column in any case, provided that exactly one column fits.
|
||||||
|
def icase_column(names, expr, i)
|
||||||
|
return unless Rdb.icase?
|
||||||
|
|
||||||
|
word = expr[i..][/\A\w+/].to_s
|
||||||
|
return if word.empty? || AWK_WORDS.include?(word) || expr[i + word.size..].to_s.match?(/\A\s*\(/)
|
||||||
|
|
||||||
|
hits = names.select { |n, _| n.casecmp?(word) }
|
||||||
|
Rdb.die "column name '#{word}' is ambiguous: #{hits.map(&:first).join(', ')}" if hits.size > 1
|
||||||
|
hits.first
|
||||||
|
end
|
||||||
|
|
||||||
def to_awk(expr, head)
|
def to_awk(expr, head)
|
||||||
names = head.each_with_index.sort_by { |n, _| -n.size }
|
names = head.each_with_index.sort_by { |n, _| -n.size }
|
||||||
out = +''
|
out = +''
|
||||||
@@ -59,6 +77,7 @@ module Rdb
|
|||||||
i = j + 1
|
i = j + 1
|
||||||
elsif c.match?(/[A-Za-z_#]/) && (i.zero? || !expr[i - 1].match?(/[\w$]/))
|
elsif c.match?(/[A-Za-z_#]/) && (i.zero? || !expr[i - 1].match?(/[\w$]/))
|
||||||
hit = names.find { |n, _| !n.empty? && expr[i, n.size] == n && !expr[i + n.size].to_s.match?(/\w/) }
|
hit = names.find { |n, _| !n.empty? && expr[i, n.size] == n && !expr[i + n.size].to_s.match?(/\w/) }
|
||||||
|
hit ||= icase_column(names, expr, i)
|
||||||
if hit
|
if hit
|
||||||
out << "$#{hit[1] + 1}"
|
out << "$#{hit[1] + 1}"
|
||||||
i += hit[0].size
|
i += hit[0].size
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ module Rdb
|
|||||||
end
|
end
|
||||||
|
|
||||||
def column(name)
|
def column(name)
|
||||||
@head.index(name) || Rdb.die("#{path}: no column named '#{name}'")
|
Rdb.column_index(@head, name) || Rdb.die("#{path}: no column named '#{name}'")
|
||||||
end
|
end
|
||||||
|
|
||||||
def row_at(offset)
|
def row_at(offset)
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ module Rdb
|
|||||||
end
|
end
|
||||||
|
|
||||||
def index_of(name)
|
def index_of(name)
|
||||||
@head.index(name) || Rdb.die("no column named '#{name}'")
|
Rdb.column_index(@head, name) || Rdb.die("no column named '#{name}'")
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Rdb
|
||||||
|
VERSION = '0.2.0'
|
||||||
|
end
|
||||||
@@ -113,6 +113,22 @@ Phone (111) 222-3333
|
|||||||
Name Chiquita Banana
|
Name Chiquita Banana
|
||||||
Phone 1234
|
Phone 1234
|
||||||
.DE
|
.DE
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
.B
|
.B
|
||||||
project,
|
project,
|
||||||
|
|||||||
@@ -355,6 +355,22 @@ compute 'Value = sprintf ("%7.2f", ( Cost * Amount ))' < inventory
|
|||||||
.DE
|
.DE
|
||||||
.PP
|
.PP
|
||||||
These commands will produce the first table under Examples, above.
|
These commands will produce the first table under Examples, above.
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
COHERENT Lexicon:
|
COHERENT Lexicon:
|
||||||
.B
|
.B
|
||||||
|
|||||||
@@ -393,6 +393,22 @@ before
|
|||||||
.BR chart .
|
.BR chart .
|
||||||
It says that the standard input file
|
It says that the standard input file
|
||||||
will be file 1 or on the left side of the table.
|
will be file 1 or on the left side of the table.
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
.B
|
.B
|
||||||
column,
|
column,
|
||||||
|
|||||||
+16
@@ -10,6 +10,22 @@ prints on the standard output all commands in directory
|
|||||||
.BR $RDB/bin .
|
.BR $RDB/bin .
|
||||||
This command is a shell script, which you should edit if its output
|
This command is a shell script, which you should edit if its output
|
||||||
is not to your liking.
|
is not to your liking.
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
.B
|
.B
|
||||||
act,
|
act,
|
||||||
|
|||||||
@@ -112,6 +112,22 @@ State Costa Rica
|
|||||||
Zip 123456789
|
Zip 123456789
|
||||||
Phone 1234
|
Phone 1234
|
||||||
.DE
|
.DE
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
.B
|
.B
|
||||||
column
|
column
|
||||||
|
|||||||
+16
@@ -175,6 +175,22 @@ and
|
|||||||
.BR compute ,
|
.BR compute ,
|
||||||
read the COHERENT manual's tutorial on
|
read the COHERENT manual's tutorial on
|
||||||
.BR awk .
|
.BR awk .
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
.B
|
.B
|
||||||
compute,
|
compute,
|
||||||
|
|||||||
@@ -165,6 +165,22 @@ People are often confused by
|
|||||||
.B sort
|
.B sort
|
||||||
because it does not behave the way one would expect.
|
because it does not behave the way one would expect.
|
||||||
Study its entry in the COHERENT Lexicon.
|
Study its entry in the COHERENT Lexicon.
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
COHERENT Lexicon:
|
COHERENT Lexicon:
|
||||||
.B
|
.B
|
||||||
|
|||||||
@@ -133,6 +133,22 @@ that is easy to find, such as
|
|||||||
.PP
|
.PP
|
||||||
If you only want to see the error lines, use the command
|
If you only want to see the error lines, use the command
|
||||||
.BR row .
|
.BR row .
|
||||||
|
.SH "Case of Column Names"
|
||||||
|
.I "(Ruby re-creation only.)"
|
||||||
|
Column names are case sensitive, as in the original
|
||||||
|
.BR /rdb .
|
||||||
|
If the environment variable
|
||||||
|
.B RDB_ICASE
|
||||||
|
is set to 1, upper and lower case are ignored when column names are looked up.
|
||||||
|
An exact match always wins;
|
||||||
|
if several columns differ only in case, the command stops with an
|
||||||
|
.I ambiguous
|
||||||
|
error.
|
||||||
|
Names that are also
|
||||||
|
.B awk
|
||||||
|
reserved words or are followed by
|
||||||
|
.B (
|
||||||
|
are never taken for columns.
|
||||||
.SH "See Also"
|
.SH "See Also"
|
||||||
.SH "Logical Conditions"
|
.SH "Logical Conditions"
|
||||||
.B
|
.B
|
||||||
|
|||||||
@@ -478,4 +478,41 @@ class ActTest < RdbCase
|
|||||||
assert_includes out, 'Duplicate Short names in chart'
|
assert_includes out, 'Duplicate Short names in chart'
|
||||||
assert st.success?, err
|
assert st.success?, err
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ICASE = { 'RDB_ICASE' => '1' }.freeze
|
||||||
|
|
||||||
|
def test_column_names_are_case_sensitive_by_default
|
||||||
|
_o, err, st = run3('column', 'cost', stdin: File.read(File.join(@dir, 'inventory')))
|
||||||
|
assert st.success?, err
|
||||||
|
assert_equal %w[cost], _o.lines.first.chomp.split("\t")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_icase_column_and_sorttable
|
||||||
|
out, err, st = run3('column', 'COST', 'item', stdin: File.read(File.join(@dir, 'inventory')), env: ICASE)
|
||||||
|
assert st.success?, err
|
||||||
|
assert_equal %w[Cost Item], out.lines.first.chomp.split("\t")
|
||||||
|
out, = run3('sorttable', '-nr', 'cost', stdin: File.read(File.join(@dir, 'inventory')), env: ICASE)
|
||||||
|
assert_equal 'scales', data(out).first.last
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_icase_compute_and_awk_words
|
||||||
|
src = File.read(File.join(@dir, 'inventory'))
|
||||||
|
out, err, st = run3('compute', 'value = sprintf("%5.2f", cost * AMOUNT)', stdin: src, env: ICASE)
|
||||||
|
assert st.success?, err
|
||||||
|
assert_equal '1312.75', data(out)[5][3].strip
|
||||||
|
# a column called Length must not swallow the length() function
|
||||||
|
t = "Length\tName\n------\t----\n3\tab\n"
|
||||||
|
out, err, st = run3('compute', 'Length = length(name)', stdin: t, env: ICASE)
|
||||||
|
assert st.success?, err
|
||||||
|
assert_equal [%w[2 ab]], data(out)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_icase_ambiguous_column_is_an_error
|
||||||
|
t = "Name\tname\n----\t----\na\tb\n"
|
||||||
|
_o, err, st = run3('column', 'NAME', stdin: t, env: ICASE)
|
||||||
|
refute st.success?
|
||||||
|
assert_match(/ambiguous/, err)
|
||||||
|
out, = run3('column', 'name', stdin: t, env: ICASE)
|
||||||
|
assert_equal [%w[b]], data(out)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user