mirror of
https://github.com/objectionary/eo.git
synced 2024-10-26 20:30:44 +03:00
feat(#3251): added text and sscanf to eo-runtime
This commit is contained in:
parent
0927a50ebf
commit
b248cfd4af
@ -25,7 +25,4 @@
|
||||
# package name contains capital letter and such names are conventional.
|
||||
---
|
||||
exclude_paths:
|
||||
- "eo-runtime/src/test/java/EOorg/EOeolang/EOtxt/EOsprintfTest.java"
|
||||
- "eo-runtime/src/test/java/EOorg/EOeolang/EOtxt/package-info.java"
|
||||
- "eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsprintf.java"
|
||||
- "eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/package-info.java"
|
||||
- "eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsscanf.java"
|
||||
|
@ -32,12 +32,6 @@
|
||||
[as-bytes] > string
|
||||
as-bytes > @
|
||||
|
||||
# Is true if both objects are equal.
|
||||
[x] > eq
|
||||
eq. > @
|
||||
^.as-bytes
|
||||
x.as-bytes
|
||||
|
||||
# Get the length of it.
|
||||
[] > length /int
|
||||
|
||||
|
35
eo-runtime/src/main/eo/org/eolang/txt/sscanf.eo
Normal file
35
eo-runtime/src/main/eo/org/eolang/txt/sscanf.eo
Normal file
@ -0,0 +1,35 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2016-2024 Objectionary.com
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
+architect yegor256@gmail.com
|
||||
+home https://github.com/objectionary/eo
|
||||
+package org.eolang.txt
|
||||
+rt jvm org.eolang:eo-runtime:0.0.0
|
||||
+rt node eo2js-runtime:0.0.0
|
||||
+version 0.0.0
|
||||
|
||||
# Reads formatted input from a string.
|
||||
# This object has two free attributes:
|
||||
# 1. `format` - is a formatter string (e.g. "Hello, %s!")
|
||||
# 2. `read` - is a string where data exists (e.g. "Hello, John!")
|
||||
# returns a `tuple` of formatted values (e.g. * "John").
|
||||
[format read] > sscanf /tuple
|
452
eo-runtime/src/main/eo/org/eolang/txt/text.eo
Normal file
452
eo-runtime/src/main/eo/org/eolang/txt/text.eo
Normal file
@ -0,0 +1,452 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2016-2024 Objectionary.com
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
+alias org.eolang.structs.list
|
||||
+alias org.eolang.structs.bytes-as-array
|
||||
+alias org.eolang.txt.sprintf
|
||||
+alias org.eolang.txt.sscanf
|
||||
+architect yegor256@gmail.com
|
||||
+home https://github.com/objectionary/eo
|
||||
+package org.eolang.txt
|
||||
+rt jvm org.eolang:eo-runtime:0.0.0
|
||||
+rt node eo2js-runtime:0.0.0
|
||||
+version 0.0.0
|
||||
|
||||
# Text.
|
||||
[origin] > text
|
||||
origin > @
|
||||
|
||||
# Takes a piece of a `text` as another `text`.
|
||||
# Here `start` must be an integer index to start slicing from,
|
||||
# `len` must be an integer which shows how much symbols should be sliced.
|
||||
[start len] > slice
|
||||
text > @
|
||||
^.origin.slice start len
|
||||
|
||||
# Returns `text` trimmed from left side.
|
||||
[] > trimmed-left
|
||||
^.origin.length > len!
|
||||
if. > @
|
||||
0.eq len
|
||||
^
|
||||
^.slice
|
||||
first-non-space-index 0 > idx!
|
||||
(int len).minus (int idx)
|
||||
|
||||
[index] > first-non-space-index
|
||||
^.^.origin.slice index 1 > char!
|
||||
if. > @
|
||||
^.len.eq index
|
||||
index
|
||||
if.
|
||||
" ".eq char
|
||||
^.first-non-space-index
|
||||
index.plus 1
|
||||
index
|
||||
|
||||
# Returns `text` trimmed from right side.
|
||||
[] > trimmed-right
|
||||
^.origin.length > len!
|
||||
if. > @
|
||||
0.eq len
|
||||
^
|
||||
^.slice
|
||||
0
|
||||
first-non-space-index
|
||||
(int len).plus -1
|
||||
|
||||
[index] > first-non-space-index
|
||||
^.^.origin.slice index 1 > char!
|
||||
if. > @
|
||||
-1.eq index
|
||||
0
|
||||
if.
|
||||
" ".eq char
|
||||
^.first-non-space-index
|
||||
index.plus -1
|
||||
index.plus 1
|
||||
|
||||
# Returns `text` trimmed from both sides.
|
||||
[] > trimmed
|
||||
if. > @
|
||||
0.eq ^.length
|
||||
^
|
||||
trimmed-right.
|
||||
trimmed-left.
|
||||
^
|
||||
|
||||
# Joins `items`, which is a `tuple` of strings, using current `string`
|
||||
# as a delimiter.
|
||||
[items] > joined
|
||||
^.origin > delimiter!
|
||||
items.length > len!
|
||||
text > @
|
||||
if.
|
||||
0.eq len
|
||||
""
|
||||
if.
|
||||
1.eq len
|
||||
items.at 0 > first
|
||||
as-string.
|
||||
concat.
|
||||
first.as-bytes
|
||||
with-delimiter "".as-bytes 1
|
||||
|
||||
[acc index] > with-delimiter
|
||||
if. > @
|
||||
^.len.eq index
|
||||
acc
|
||||
^.with-delimiter
|
||||
acc.concat
|
||||
^.delimiter.concat
|
||||
^.items.at index
|
||||
index.plus 1
|
||||
|
||||
# Returns `text` repeated `times` times.
|
||||
# If `times` < 0 - an error is returned.
|
||||
# If `times` == 0 - an original text is returned.
|
||||
[times] > repeated
|
||||
^.origin.as-bytes > bts!
|
||||
if. > @
|
||||
0.gt
|
||||
times > amount!
|
||||
error
|
||||
sprintf
|
||||
"Can't repeat text %d times"
|
||||
* amount
|
||||
text
|
||||
if.
|
||||
0.eq amount
|
||||
""
|
||||
as-string.
|
||||
rec-repeated bts 1
|
||||
|
||||
[accum index] > rec-repeated
|
||||
if. > @
|
||||
^.amount.eq index
|
||||
accum
|
||||
^.rec-repeated
|
||||
accum.concat ^.bts
|
||||
index.plus 1
|
||||
|
||||
# Checks if current `text` contains given `substring`.
|
||||
[substring] > contains
|
||||
not. > @
|
||||
eq.
|
||||
-1
|
||||
^.index-of substring
|
||||
|
||||
# Checks that current `text` ends with given `substring`.
|
||||
[substring] > ends-with
|
||||
eq. > @
|
||||
^.index-of
|
||||
substring > substr!
|
||||
^.length.minus substr.size
|
||||
|
||||
# Checks that current `text` starts with given `substring`.
|
||||
[substring] > starts-with
|
||||
eq. > @
|
||||
0
|
||||
^.index-of substring
|
||||
|
||||
# Returns index of `substring` in current `text`.
|
||||
# If no `substring` was found, it returns -1
|
||||
[substring] > index-of
|
||||
^.origin.length > self-len!
|
||||
size. > sub-len!
|
||||
substring > substr!
|
||||
(int self-len).minus (int sub-len) > end!
|
||||
if. > @
|
||||
or.
|
||||
(int sub-len).gt self-len
|
||||
and.
|
||||
sub-len.eq self-len
|
||||
(substr.eq ^.origin).not
|
||||
-1
|
||||
rec-index-of-substr 0
|
||||
|
||||
[idx] > rec-index-of-substr
|
||||
if. > @
|
||||
^.end.eq idx
|
||||
if.
|
||||
eq. > contains
|
||||
^.substr
|
||||
^.^.slice idx ^.sub-len
|
||||
idx
|
||||
-1
|
||||
if.
|
||||
contains
|
||||
idx
|
||||
^.rec-index-of-substr
|
||||
idx.plus 1
|
||||
|
||||
# Returns last index of `substring` in current `text`.
|
||||
# If no element was found, it returns -1.
|
||||
[substring] > last-index-of
|
||||
^.origin.length > self-len!
|
||||
size. > sub-len!
|
||||
substring > substr!
|
||||
if. > @
|
||||
or.
|
||||
(int sub-len).gt self-len
|
||||
and.
|
||||
sub-len.eq self-len
|
||||
(substr.eq ^.origin).not
|
||||
-1
|
||||
rec-index-of-substr
|
||||
(int self-len).minus (int sub-len)
|
||||
|
||||
[idx] > rec-index-of-substr
|
||||
if. > @
|
||||
0.eq idx
|
||||
if.
|
||||
eq. > contains
|
||||
^.substr
|
||||
^.^.slice idx ^.sub-len
|
||||
idx
|
||||
-1
|
||||
if.
|
||||
contains
|
||||
idx
|
||||
^.rec-index-of-substr
|
||||
idx.plus -1
|
||||
|
||||
# Returns `text` in upper case.
|
||||
[] > up-cased
|
||||
ascii "z" > ascii-z!
|
||||
minus. > distance
|
||||
int
|
||||
ascii "a" > ascii-a!
|
||||
ascii "A"
|
||||
text > @
|
||||
as-string.
|
||||
reduced.
|
||||
list
|
||||
bytes-as-array
|
||||
^.origin.as-bytes
|
||||
--
|
||||
[accum byte] >>
|
||||
^.ascii byte > ascii-bte
|
||||
accum.concat > @
|
||||
if.
|
||||
and.
|
||||
ascii-bte.lte ^.ascii-z
|
||||
ascii-bte.gte ^.ascii-a
|
||||
slice.
|
||||
as-bytes.
|
||||
ascii-bte.minus ^.distance
|
||||
7
|
||||
1
|
||||
byte
|
||||
|
||||
[char] > ascii
|
||||
as-int. > @
|
||||
concat.
|
||||
00-00-00-00-00-00-00
|
||||
char.as-bytes
|
||||
|
||||
# Returns `text` in lower case.
|
||||
[] > low-cased
|
||||
^.up-cased.ascii "Z" > ascii-z
|
||||
^.up-cased.ascii "A" > ascii-a
|
||||
text > @
|
||||
as-string.
|
||||
reduced.
|
||||
list
|
||||
bytes-as-array
|
||||
^.origin.as-bytes
|
||||
--
|
||||
[accum byte] >>
|
||||
^.^.up-cased.ascii byte > ascii-bte
|
||||
accum.concat > @
|
||||
if.
|
||||
and.
|
||||
ascii-bte.lte ^.ascii-z
|
||||
ascii-bte.gte ^.ascii-a
|
||||
slice.
|
||||
as-bytes.
|
||||
ascii-bte.plus ^.^.up-cased.distance
|
||||
7
|
||||
1
|
||||
byte
|
||||
|
||||
# Retrieve symbol by given index as `text`.
|
||||
# If 0 > index >= ^.length - the error will be returned.
|
||||
[i] > at
|
||||
^.length > len!
|
||||
if. > index!
|
||||
0.gt
|
||||
i > idx!
|
||||
(int len).plus idx
|
||||
idx
|
||||
if. > @
|
||||
or.
|
||||
0.gt index
|
||||
(int index).gte len
|
||||
error
|
||||
sprintf
|
||||
"Given index %d is out of text bounds"
|
||||
* index
|
||||
^.slice index 1
|
||||
|
||||
# Returns text where all regexp
|
||||
# target changed to replacement.
|
||||
# @todo #3251:30min Implement text.replaced object. This object was an atom in
|
||||
# eo-strings. Maybe there's a way to implement it in pure EO. Don't remember to
|
||||
# write some tests when object is implemented.
|
||||
^ > [target replacement] > replaced
|
||||
|
||||
# Returns the original `text` as `int`.
|
||||
[] > as-int
|
||||
if. > @
|
||||
eq.
|
||||
0
|
||||
length.
|
||||
sscanf "%d" ^.origin > scanned
|
||||
error
|
||||
sprintf
|
||||
"Can't convert text %s to int"
|
||||
* ^.origin
|
||||
scanned.tail
|
||||
|
||||
# Returns the original `text` as `float`.
|
||||
[] > as-float
|
||||
if. > @
|
||||
eq.
|
||||
0
|
||||
length.
|
||||
sscanf "%f" ^.origin > scanned
|
||||
error
|
||||
sprintf
|
||||
"Can't convert text %s to float"
|
||||
* ^.origin
|
||||
scanned.tail
|
||||
|
||||
# Returns a `list` of `strings`, separated by a given `delimiter`.
|
||||
[delimiter] > split
|
||||
delimiter > delim!
|
||||
^.origin.as-bytes > self-as-bytes
|
||||
self-as-bytes.size > len!
|
||||
list > @
|
||||
if.
|
||||
len.eq 0
|
||||
*
|
||||
rec-split * 0 0
|
||||
|
||||
[accum start current] > rec-split
|
||||
if. > @
|
||||
^.len.eq current
|
||||
accum.with > with-substr
|
||||
^.self-as-bytes.slice
|
||||
start
|
||||
current.minus start
|
||||
if.
|
||||
eq.
|
||||
^.delim
|
||||
^.self-as-bytes.slice current 1
|
||||
^.rec-split
|
||||
with-substr
|
||||
current.plus 1
|
||||
current.plus 1
|
||||
^.rec-split
|
||||
accum
|
||||
start
|
||||
current.plus 1
|
||||
|
||||
# Check that all signs in string are numbers or letters.
|
||||
# Works only for english letters
|
||||
[] > is-alphabetic
|
||||
reduced. > @
|
||||
list
|
||||
bytes-as-array
|
||||
^.low-cased.as-bytes
|
||||
true
|
||||
[accum byte] >>
|
||||
and. > @
|
||||
accum
|
||||
^.int-is-alphabetic
|
||||
concat.
|
||||
00-00-00-00-00-00-00
|
||||
byte
|
||||
|
||||
[bte] > int-is-alphabetic
|
||||
or. > @
|
||||
and.
|
||||
48.lte bte
|
||||
57.gte bte
|
||||
and.
|
||||
97.lte bte
|
||||
122.gte bte
|
||||
|
||||
# Check that all signs in string are letters.
|
||||
# Works only for english letters.
|
||||
[] > is-alpha
|
||||
reduced. > @
|
||||
list
|
||||
bytes-as-array
|
||||
^.low-cased.as-bytes
|
||||
true
|
||||
[accum byte] >>
|
||||
and. > @
|
||||
accum
|
||||
^.int-is-alpha
|
||||
concat.
|
||||
00-00-00-00-00-00-00
|
||||
byte
|
||||
|
||||
[bte] > int-is-alpha
|
||||
and. > @
|
||||
97.lte bte
|
||||
122.gte bte
|
||||
|
||||
# Check that all signs in string are ASCII characters.
|
||||
[] > is-ascii
|
||||
reduced. > @
|
||||
list
|
||||
bytes-as-array
|
||||
^.origin.as-bytes
|
||||
true
|
||||
[accum byte] >>
|
||||
and. > @
|
||||
accum
|
||||
^.int-is-ascii
|
||||
concat.
|
||||
00-00-00-00-00-00-00
|
||||
byte
|
||||
|
||||
[bte] > int-is-ascii
|
||||
and. > @
|
||||
0.lte bte
|
||||
127.gte bte
|
||||
|
||||
# Returns concatenation of all `other` strings.
|
||||
# Here `other` must be a `tuple` of `strings`.
|
||||
[others] > chained
|
||||
if. > @
|
||||
0.eq others.length
|
||||
^
|
||||
text
|
||||
as-string.
|
||||
reduced.
|
||||
list others
|
||||
^.origin.as-bytes
|
||||
accum.concat str.as-bytes > [accum str]
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2024 Objectionary.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @checkstyle PackageNameCheck (4 lines)
|
||||
*/
|
||||
package EOorg.EOeolang;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.eolang.Atom;
|
||||
import org.eolang.Data;
|
||||
import org.eolang.Param;
|
||||
import org.eolang.PhDefault;
|
||||
import org.eolang.Phi;
|
||||
import org.eolang.Versionized;
|
||||
import org.eolang.XmirObject;
|
||||
|
||||
/**
|
||||
* AS-BYTES.
|
||||
*
|
||||
* @since 1.0
|
||||
* @checkstyle TypeNameCheck (5 lines)
|
||||
*/
|
||||
@Versionized
|
||||
@XmirObject(oname = "string.as-bytes")
|
||||
public final class EOstring$EOas_bytes extends PhDefault implements Atom {
|
||||
@Override
|
||||
public Phi lambda() {
|
||||
return new Data.ToPhi(
|
||||
new Param(this).strong(String.class).getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
}
|
||||
}
|
@ -28,9 +28,12 @@
|
||||
package EOorg.EOeolang.EOtxt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.Function;
|
||||
import org.eolang.AtVoid;
|
||||
import org.eolang.Atom;
|
||||
import org.eolang.Data;
|
||||
@ -43,12 +46,29 @@ import org.eolang.XmirObject;
|
||||
|
||||
/**
|
||||
* Sprintf.
|
||||
*
|
||||
* @since 0.39.0
|
||||
* @checkstyle TypeNameCheck (5 lines)
|
||||
*/
|
||||
@XmirObject(oname = "sprintf")
|
||||
public final class EOsprintf extends PhDefault implements Atom {
|
||||
/**
|
||||
* Character conversion.
|
||||
* @checkstyle IndentationCheck (15 lines)
|
||||
*/
|
||||
private static final Map<Character, Function<Dataized, Object>> CONVERSION =
|
||||
new HashMap<Character, Function<Dataized, Object>>(5) {{
|
||||
put('s', element -> element.take(String.class));
|
||||
put('d', element -> element.take(Long.class));
|
||||
put('f', element -> element.take(Double.class));
|
||||
put('x', element -> EOsprintf.bytesToHex(element.take()));
|
||||
put('b', element -> element.take(Boolean.class));
|
||||
}};
|
||||
|
||||
/**
|
||||
* Percent sign.
|
||||
*/
|
||||
private static final char PERCENT = '%';
|
||||
|
||||
/**
|
||||
* Ctor.
|
||||
*/
|
||||
@ -67,7 +87,7 @@ public final class EOsprintf extends PhDefault implements Atom {
|
||||
String pattern = format;
|
||||
long index = 0;
|
||||
while (true) {
|
||||
final int idx = pattern.indexOf('%');
|
||||
final int idx = pattern.indexOf(EOsprintf.PERCENT);
|
||||
if (idx == -1) {
|
||||
break;
|
||||
}
|
||||
@ -76,16 +96,20 @@ public final class EOsprintf extends PhDefault implements Atom {
|
||||
String.format(
|
||||
"The amount of arguments %d does not match the amount of format occurrences %d",
|
||||
length,
|
||||
EOsprintf.percents(format)
|
||||
EOsprintf.formats(format)
|
||||
)
|
||||
);
|
||||
}
|
||||
final char sym = pattern.charAt(idx + 1);
|
||||
final Phi taken = retriever.copy();
|
||||
taken.put(0, new Data.ToPhi(index));
|
||||
arguments.add(EOsprintf.formatted(sym, new Dataized(taken)));
|
||||
pattern = pattern.substring(idx + 1);
|
||||
++index;
|
||||
if (sym != EOsprintf.PERCENT) {
|
||||
final Phi taken = retriever.copy();
|
||||
taken.put(0, new Data.ToPhi(index));
|
||||
arguments.add(EOsprintf.formatted(sym, new Dataized(taken)));
|
||||
++index;
|
||||
pattern = pattern.substring(idx + 2);
|
||||
} else {
|
||||
pattern = pattern.substring(idx + 1);
|
||||
}
|
||||
}
|
||||
return new ToPhi(
|
||||
String.format(
|
||||
@ -116,44 +140,30 @@ public final class EOsprintf extends PhDefault implements Atom {
|
||||
* @return Formatted object
|
||||
*/
|
||||
private static Object formatted(final char symbol, final Dataized element) {
|
||||
final Object result;
|
||||
switch (symbol) {
|
||||
case 's':
|
||||
result = element.take(String.class);
|
||||
break;
|
||||
case 'd':
|
||||
result = element.take(Long.class);
|
||||
break;
|
||||
case 'f':
|
||||
result = element.take(Double.class);
|
||||
break;
|
||||
case 'x':
|
||||
result = EOsprintf.bytesToHex(element.take());
|
||||
break;
|
||||
case 'b':
|
||||
result = element.take(Boolean.class);
|
||||
break;
|
||||
default:
|
||||
throw new ExFailure(
|
||||
String.format(
|
||||
"The format %c is unsupported, only %s formats can be used",
|
||||
symbol,
|
||||
"%s, %d, %f, %x, %b"
|
||||
)
|
||||
);
|
||||
if (!EOsprintf.CONVERSION.containsKey(symbol)) {
|
||||
throw new ExFailure(
|
||||
String.format(
|
||||
"The format %c is unsupported, only %s formats can be used",
|
||||
symbol, "%s, %d, %f, %x, %b"
|
||||
)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
return EOsprintf.CONVERSION.get(symbol).apply(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count amount of '%' char occurrences.
|
||||
* Count amount of format occurrences.
|
||||
* @param str Given string
|
||||
* @return Amount of '%' in string
|
||||
* @return Amount of formats in string
|
||||
*/
|
||||
private static int percents(final String str) {
|
||||
private static int formats(final String str) {
|
||||
int count = 0;
|
||||
for (int idx = 0; idx < str.length(); ++idx) {
|
||||
if (str.charAt(idx) == '%') {
|
||||
if (
|
||||
str.charAt(idx) == EOsprintf.PERCENT
|
||||
&& idx + 1 != str.length()
|
||||
&& EOsprintf.CONVERSION.containsKey(str.charAt(idx + 1))
|
||||
) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
154
eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsscanf.java
Normal file
154
eo-runtime/src/main/java/EOorg/EOeolang/EOtxt/EOsscanf.java
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2024 Objectionary.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @checkstyle PackageNameCheck (4 lines)
|
||||
*/
|
||||
package EOorg.EOeolang.EOtxt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.eolang.AtVoid;
|
||||
import org.eolang.Atom;
|
||||
import org.eolang.Data;
|
||||
import org.eolang.ExFailure;
|
||||
import org.eolang.Param;
|
||||
import org.eolang.PhDefault;
|
||||
import org.eolang.Phi;
|
||||
import org.eolang.XmirObject;
|
||||
|
||||
/**
|
||||
* Sscanf.
|
||||
* @since 0.39
|
||||
* @checkstyle TypeNameCheck (5 lines)
|
||||
*/
|
||||
@XmirObject(oname = "sscanf")
|
||||
public final class EOsscanf extends PhDefault implements Atom {
|
||||
/**
|
||||
* Character conversion.
|
||||
* @checkstyle IndentationCheck (10 lines)
|
||||
*/
|
||||
private static final Map<Character, Function<String, Phi>> CONVERSION =
|
||||
new HashMap<Character, Function<String, Phi>>(3) {{
|
||||
put('s', ToPhi::new);
|
||||
put('d', str -> new Data.ToPhi(Long.parseLong(str)));
|
||||
put('f', str -> new Data.ToPhi(Double.parseDouble(str)));
|
||||
}};
|
||||
|
||||
/**
|
||||
* Percent sign.
|
||||
*/
|
||||
private static final char PERCENT = '%';
|
||||
|
||||
/**
|
||||
* Ctor.
|
||||
* @checkstyle CyclomaticComplexityCheck (75 lines)
|
||||
* @checkstyle NestedIfDepthCheck (75 lines)
|
||||
*/
|
||||
public EOsscanf() {
|
||||
this.add("format", new AtVoid("format"));
|
||||
this.add("read", new AtVoid("read"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Phi lambda() throws Exception {
|
||||
final String format = new Param(this, "format").strong(String.class);
|
||||
final List<Phi> output = new ArrayList<>(0);
|
||||
final StringBuilder regex = new StringBuilder();
|
||||
boolean literal = false;
|
||||
for (int idx = 0; idx < format.length(); ++idx) {
|
||||
final char sym = format.charAt(idx);
|
||||
if (sym == EOsscanf.PERCENT) {
|
||||
if (literal) {
|
||||
regex.append(EOsscanf.PERCENT);
|
||||
literal = false;
|
||||
} else {
|
||||
literal = true;
|
||||
}
|
||||
} else {
|
||||
if (literal) {
|
||||
switch (sym) {
|
||||
case 'd':
|
||||
regex.append("(\\d+)");
|
||||
break;
|
||||
case 'f':
|
||||
regex.append("([+-]?\\d*\\.\\d+)");
|
||||
break;
|
||||
case 's':
|
||||
regex.append("(\\S+)");
|
||||
break;
|
||||
default:
|
||||
throw new ExFailure("Unsupported format specifier: '%%%c'", sym);
|
||||
}
|
||||
literal = false;
|
||||
} else {
|
||||
regex.append(Pattern.quote(String.valueOf(sym)));
|
||||
}
|
||||
}
|
||||
}
|
||||
final Matcher matcher = Pattern.compile(regex.toString()).matcher(
|
||||
new Param(this, "read").strong(String.class)
|
||||
);
|
||||
String frmt = format;
|
||||
if (matcher.find()) {
|
||||
int index = 1;
|
||||
while (true) {
|
||||
final int idx = frmt.indexOf(EOsscanf.PERCENT);
|
||||
if (idx == -1) {
|
||||
break;
|
||||
}
|
||||
final char sym = frmt.charAt(idx + 1);
|
||||
if (sym != EOsscanf.PERCENT) {
|
||||
output.add(EOsscanf.converted(sym, matcher.group(index)));
|
||||
++index;
|
||||
}
|
||||
frmt = frmt.substring(idx + 2);
|
||||
}
|
||||
}
|
||||
return new Data.ToPhi(output.toArray(new Phi[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert given string to {@link Phi} depending on format {@code symbol}.
|
||||
* @param symbol Format symbol
|
||||
* @param str String to format
|
||||
* @return Phi object depending on format symbol
|
||||
*/
|
||||
private static Phi converted(final char symbol, final String str) {
|
||||
if (!EOsscanf.CONVERSION.containsKey(symbol)) {
|
||||
throw new ExFailure(
|
||||
String.format(
|
||||
"The format %c is unsupported, only %s formats can be used",
|
||||
symbol, "%s, %d, %f"
|
||||
)
|
||||
);
|
||||
}
|
||||
return EOsscanf.CONVERSION.get(symbol).apply(str);
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
+alias org.eolang.io.stdout
|
||||
+alias org.eolang.txt.sprintf
|
||||
+architect yegor256@gmail.com
|
||||
+home https://github.com/objectionary/eo
|
||||
@ -50,3 +51,43 @@
|
||||
sprintf
|
||||
"%x"
|
||||
* 42.as-bytes
|
||||
|
||||
# Test.
|
||||
[] > formats-all-objects
|
||||
eq. > @
|
||||
"string Jeff, bytes 4A-65-66-66, float 42.300000, int 14, bool false"
|
||||
sprintf
|
||||
"string %s, bytes %x, float %f, int %d, bool %b"
|
||||
* "Jeff" "Jeff".as-bytes 42.3 14 false
|
||||
|
||||
# Test.
|
||||
[] > sprintf-fails-if-amount-of-arguments-does-not-match
|
||||
try > @
|
||||
sprintf
|
||||
"%s%s"
|
||||
* "Jeff"
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > sprintf-does-not-fail-if-arguments-more-than-formats
|
||||
eq. > @
|
||||
"Hey"
|
||||
sprintf
|
||||
"%s"
|
||||
* "Hey" "Jeff"
|
||||
|
||||
# Test.
|
||||
[] > fails-on-unsupported-format
|
||||
try > @
|
||||
sprintf "%o" *
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > sprintf-prints-percents
|
||||
eq. > @
|
||||
"%Jeff"
|
||||
sprintf
|
||||
"%%%s"
|
||||
* "Jeff"
|
||||
|
121
eo-runtime/src/test/eo/org/eolang/txt/sscanf-tests.eo
Normal file
121
eo-runtime/src/test/eo/org/eolang/txt/sscanf-tests.eo
Normal file
@ -0,0 +1,121 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2016-2024 Objectionary.com
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
+alias org.eolang.io.stdout
|
||||
+alias org.eolang.txt.sprintf
|
||||
+alias org.eolang.txt.sscanf
|
||||
+alias org.eolang.structs.list
|
||||
+architect yegor256@gmail.com
|
||||
+home https://github.com/objectionary/eo
|
||||
+tests
|
||||
+package org.eolang.txt
|
||||
+version 0.0.0
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-string
|
||||
eq. > @
|
||||
"hello"
|
||||
tail.
|
||||
sscanf "%s" "hello"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-int
|
||||
eq. > @
|
||||
33
|
||||
tail.
|
||||
sscanf "%d" "33"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-float
|
||||
eq. > @
|
||||
0.24
|
||||
tail.
|
||||
sscanf "%f" "0.24"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-error
|
||||
try > @
|
||||
sscanf "%l" "error"
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-string-int-float
|
||||
eq. > @
|
||||
list
|
||||
sscanf
|
||||
"%s %d %f"
|
||||
"hello 33 0.24"
|
||||
* "hello" 33 0.24
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-string-with-ending
|
||||
eq. > @
|
||||
"hello"
|
||||
tail.
|
||||
sscanf "%s!" "hello!"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-complex-string
|
||||
eq. > @
|
||||
"test"
|
||||
tail.
|
||||
sscanf "some%sstring" "someteststring"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-complex-int
|
||||
eq. > @
|
||||
734987259
|
||||
tail.
|
||||
sscanf "!%d!" "!734987259!"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-complex-float
|
||||
eq. > @
|
||||
1991.01
|
||||
tail.
|
||||
sscanf "this will be=%f" "this will be=1991.01"
|
||||
|
||||
# Test.
|
||||
[] > sscanf-with-sprintf
|
||||
eq. > @
|
||||
list
|
||||
sscanf
|
||||
"%s is about %d?"
|
||||
sprintf
|
||||
"%s is about %d?"
|
||||
* "This" 8
|
||||
* "This" 8
|
||||
|
||||
# Test.
|
||||
[] > sscanf-complex-case
|
||||
eq. > @
|
||||
list
|
||||
sscanf
|
||||
"Im%d %s old and this is! Let's calculate %f + %f= %f"
|
||||
"Im18 years old and this is! Let's calculate 99999999.99 + 0.01= 100000000.0"
|
||||
*
|
||||
18
|
||||
"years"
|
||||
99999999.99
|
||||
0.01
|
||||
100000000.0
|
391
eo-runtime/src/test/eo/org/eolang/txt/text-tests.eo
Normal file
391
eo-runtime/src/test/eo/org/eolang/txt/text-tests.eo
Normal file
@ -0,0 +1,391 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2016-2024 Objectionary.com
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
+alias org.eolang.txt.text
|
||||
+alias org.eolang.io.stdout
|
||||
+architect yegor256@gmail.com
|
||||
+home https://github.com/objectionary/eo
|
||||
+tests
|
||||
+package org.eolang.txt
|
||||
+version 0.0.0
|
||||
|
||||
# Test.
|
||||
[] > text-slices-the-origin-string
|
||||
eq. > @
|
||||
(text "Hello, world!").slice 7 5
|
||||
"world"
|
||||
|
||||
# Test.
|
||||
[] > trimmed-left-empty-text
|
||||
eq. > @
|
||||
(text "").trimmed-left
|
||||
""
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-left-one-space
|
||||
eq. > @
|
||||
(text " s").trimmed-left
|
||||
"s"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-left-many-spaces
|
||||
eq. > @
|
||||
(text " some").trimmed-left
|
||||
"some"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-left-only-spaces
|
||||
eq. > @
|
||||
(text " ").trimmed-left
|
||||
""
|
||||
|
||||
# Test.
|
||||
[] > trimmed-right-empty-text
|
||||
eq. > @
|
||||
(text "").trimmed-right
|
||||
""
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-right-one-space
|
||||
eq. > @
|
||||
(text "s ").trimmed-right
|
||||
"s"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-right-many-spaces
|
||||
eq. > @
|
||||
(text "some ").trimmed-right
|
||||
"some"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-right-only-spaces
|
||||
eq. > @
|
||||
(text " ").trimmed-right
|
||||
""
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-one-space-left
|
||||
eq. > @
|
||||
(text " some").trimmed
|
||||
"some"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-one-space-right
|
||||
eq. > @
|
||||
(text "some ").trimmed
|
||||
"some"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-one-space-both
|
||||
eq. > @
|
||||
(text " some ").trimmed
|
||||
"some"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-many-spaces
|
||||
eq. > @
|
||||
(text " some ").trimmed
|
||||
"some"
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-empty
|
||||
eq. > @
|
||||
(text "").trimmed
|
||||
""
|
||||
|
||||
# Test.
|
||||
[] > text-trimmed-only-spaces
|
||||
eq. > @
|
||||
(text " ").trimmed
|
||||
""
|
||||
|
||||
# Test.
|
||||
[] > returns-first-char
|
||||
eq. > @
|
||||
"s"
|
||||
(text "some").at 0
|
||||
|
||||
# Test.
|
||||
[] > returns-third-char
|
||||
eq. > @
|
||||
"m"
|
||||
(text "some").at 2
|
||||
|
||||
# Test.
|
||||
[] > returns-char-at-negative-index
|
||||
eq. > @
|
||||
"m"
|
||||
(text "some").at -2
|
||||
|
||||
# Test.
|
||||
[] > returns-error-at-index-more-than-length
|
||||
try > @
|
||||
(text "some").at 10
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > chains-with-other-strings
|
||||
eq. > @
|
||||
"Hello, world!"
|
||||
chained.
|
||||
text "Hello"
|
||||
*
|
||||
", "
|
||||
"world"
|
||||
"!"
|
||||
|
||||
# Test.
|
||||
[] > returns-same-text-on-chaining-with-no-strings
|
||||
eq. > @
|
||||
"Some"
|
||||
chained.
|
||||
text "Some"
|
||||
*
|
||||
|
||||
# Test.
|
||||
[] > joined-no-strings
|
||||
eq. > @
|
||||
""
|
||||
(text "-").joined *
|
||||
|
||||
# Test.
|
||||
[] > joined-one-string
|
||||
eq. > @
|
||||
"some"
|
||||
(text "-").joined
|
||||
* "some"
|
||||
|
||||
# Test.
|
||||
[] > joined-many-strings
|
||||
eq. > @
|
||||
"hello-world-dear-friend"
|
||||
(text "-").joined
|
||||
* "hello" "world" "dear" "friend"
|
||||
|
||||
# Test.
|
||||
[] > text-repeat-less-than-zero-times
|
||||
try > @
|
||||
(text "").repeated -1
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > text-repeated-zero-times-is-empty
|
||||
eq. > @
|
||||
""
|
||||
(text "some").repeated 0
|
||||
|
||||
# Test.
|
||||
[] > text-repeated-five-times
|
||||
eq. > @
|
||||
"heyheyheyheyhey"
|
||||
(text "hey").repeated 5
|
||||
|
||||
# Test.
|
||||
[] > index-of-non-existed-substring-with-more-length
|
||||
eq. > @
|
||||
-1
|
||||
(text "Hello").index-of "Somebody"
|
||||
|
||||
# Test.
|
||||
[] > index-of-non-existed-substring-with-same-length
|
||||
eq. > @
|
||||
-1
|
||||
(text "Hello").index-of "world"
|
||||
|
||||
# Test.
|
||||
[] > returns-valid-index-of-substring
|
||||
eq. > @
|
||||
3
|
||||
(text "Hello world").index-of "lo wo"
|
||||
|
||||
# Test.
|
||||
[] > returns-valid-index-of-substring-in-the-end
|
||||
eq. > @
|
||||
6
|
||||
(text "Hello world").index-of "world"
|
||||
|
||||
# Test.
|
||||
[] > starts-with-substring
|
||||
(text "Hello, world").starts-with "Hello" > @
|
||||
|
||||
# Test.
|
||||
[] > does-not-start-with-substring
|
||||
not. > @
|
||||
(text "Hello, world").starts-with "world"
|
||||
|
||||
# Test.
|
||||
[] > ends-with-substring
|
||||
(text "Hello world!").ends-with "world!" > @
|
||||
|
||||
# Test.
|
||||
[] > does-not-end-with-substring
|
||||
not. > @
|
||||
(text "Hello world!").ends-with "Hello"
|
||||
|
||||
# Test.
|
||||
[] > text-contains-substring
|
||||
(text "Hello, world!").contains "o, wo" > @
|
||||
|
||||
# Test.
|
||||
[] > text-does-not-contain-substring
|
||||
not. > @
|
||||
(text "Hello, world!").contains "Hey"
|
||||
|
||||
# Test.
|
||||
[] > finds-last-index-of-substring
|
||||
eq. > @
|
||||
5
|
||||
(text "Hey, Hey, Hey").last-index-of "Hey,"
|
||||
|
||||
# Test.
|
||||
[] > finds-last-index-of-the-same-string
|
||||
eq. > @
|
||||
0
|
||||
(text "Hello").last-index-of "Hello"
|
||||
|
||||
# Test.
|
||||
[] > last-index-of-non-existed-substring
|
||||
eq. > @
|
||||
-1
|
||||
(text "Hello, world").last-index-of "somebody"
|
||||
|
||||
# Test.
|
||||
[] > splits-text-by-dash
|
||||
eq. > @
|
||||
(text "a-b-c").split "-"
|
||||
* "a" "b" "c"
|
||||
|
||||
# Test.
|
||||
[] > splits-text-with-empty-strings
|
||||
eq. > @
|
||||
(text "-a-b-").split "-"
|
||||
* "" "a" "b" ""
|
||||
|
||||
# Test.
|
||||
[] > converts-text-to-upper-case
|
||||
eq. > @
|
||||
"HELLO"
|
||||
(text "hello").up-cased
|
||||
|
||||
# Test.
|
||||
[] > converts-text-with-upper-letters-to-upper-case
|
||||
eq. > @
|
||||
"HELLO"
|
||||
(text "HeLlO").up-cased
|
||||
|
||||
# Test.
|
||||
[] > converts-text-to-lower-case
|
||||
eq. > @
|
||||
"hello"
|
||||
(text "HELLO").low-cased
|
||||
|
||||
# Test.
|
||||
[] > converts-text-with-low-letters-to-lower-case
|
||||
eq. > @
|
||||
"hello"
|
||||
(text "HeLlO").low-cased
|
||||
|
||||
# Test.
|
||||
[] > converts-text-to-int
|
||||
eq. > @
|
||||
5
|
||||
(text "5").as-int
|
||||
|
||||
# Test.
|
||||
[] > fails-on-converting-text-to-int
|
||||
try > @
|
||||
(text "Hello").as-int
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > converts-text-to-float
|
||||
eq. > @
|
||||
3.14
|
||||
(text "3.14").as-float
|
||||
|
||||
# Test.
|
||||
[] > fails-on-converting-text-to-float
|
||||
try > @
|
||||
(text "Hello").as-float
|
||||
stdout ex > [ex]
|
||||
false
|
||||
|
||||
# Test.
|
||||
[] > checks-if-text-is-ascii
|
||||
is-ascii. > @
|
||||
text
|
||||
"H311oW"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-emoji-is-not-ascii
|
||||
not. > @
|
||||
is-ascii.
|
||||
text
|
||||
"🌵"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-string-of-numbers-is-ascii
|
||||
is-ascii. > @
|
||||
text
|
||||
"123"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-simple-text-is-alphabetic
|
||||
is-alphabetic. > @
|
||||
text
|
||||
"eEo"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-text-with-number-is-alphabetic
|
||||
is-alphabetic. > @
|
||||
text
|
||||
"ab3d"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-text-with-dashes-is-not-alphabetic
|
||||
not. > @
|
||||
is-alphabetic.
|
||||
text
|
||||
"-w-"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-simple-text-is-alpha
|
||||
is-alpha. > @
|
||||
text
|
||||
"eEo"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-text-with-number-is-not-alpha
|
||||
not. > @
|
||||
is-alpha.
|
||||
text
|
||||
"ab3d"
|
||||
|
||||
# Test.
|
||||
[] > checks-if-text-with-dashes-is-not-alpha
|
||||
not. > @
|
||||
is-alpha.
|
||||
text
|
||||
"-w-"
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2024 Objectionary.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @checkstyle PackageNameCheck (10 lines)
|
||||
*/
|
||||
package EOorg.EOeolang.EOtxt;
|
||||
|
||||
import EOorg.EOeolang.EOerror;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.eolang.Data;
|
||||
import org.eolang.Dataized;
|
||||
import org.eolang.Phi;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test case for {@link EOsprintf}.
|
||||
*
|
||||
* @since 0.39
|
||||
* @checkstyle TypeNameCheck (4 lines)
|
||||
*/
|
||||
final class EOsprintfTest {
|
||||
@Test
|
||||
void returnsValidFormattedString() {
|
||||
final Phi sprintf = new EOsprintf();
|
||||
sprintf.put(0, new Data.ToPhi("string %s, bytes %x, float %f, int %d, bool %b"));
|
||||
sprintf.put(
|
||||
1,
|
||||
new Data.ToPhi(
|
||||
new Phi[] {
|
||||
new Data.ToPhi("Jeff"),
|
||||
new Data.ToPhi("Jeff".getBytes(StandardCharsets.UTF_8)),
|
||||
new Data.ToPhi(42.3),
|
||||
new Data.ToPhi(14L),
|
||||
new Data.ToPhi(false),
|
||||
}
|
||||
)
|
||||
);
|
||||
MatcherAssert.assertThat(
|
||||
"All types should be formatted successfully",
|
||||
new Dataized(sprintf).take(String.class),
|
||||
Matchers.equalTo(
|
||||
"string Jeff, bytes 4A-65-66-66, float 42.300000, int 14, bool false"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void failsIfAmountOfArgumentsDoesNotMatch() {
|
||||
final Phi sprintf = new EOsprintf();
|
||||
sprintf.put(0, new Data.ToPhi("%s%s"));
|
||||
sprintf.put(1, new Data.ToPhi(new Phi[] {new Data.ToPhi("Hey")}));
|
||||
final Throwable exception = Assertions.assertThrows(
|
||||
EOerror.ExError.class,
|
||||
() -> new Dataized(sprintf).take(),
|
||||
"Dataization of sprintf should fail if formats < arguments"
|
||||
);
|
||||
MatcherAssert.assertThat(
|
||||
"The exception message should contain an info about arguments and format occurrences amount",
|
||||
exception.getMessage(),
|
||||
Matchers.containsString(
|
||||
"The amount of arguments 1 does not match the amount of format occurrences 2"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotFailIfArgumentsMoreThanFormats() {
|
||||
final Phi sprintf = new EOsprintf();
|
||||
sprintf.put(0, new Data.ToPhi("%s"));
|
||||
sprintf.put(
|
||||
1,
|
||||
new Data.ToPhi(
|
||||
new Phi[] {
|
||||
new Data.ToPhi("Hey"),
|
||||
new Data.ToPhi("Hey"),
|
||||
}
|
||||
)
|
||||
);
|
||||
MatcherAssert.assertThat(
|
||||
"The second argument should be ignored",
|
||||
new Dataized(sprintf).take(String.class),
|
||||
Matchers.equalTo("Hey")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void failsOnUnsupportedFormat() {
|
||||
final Phi sprintf = new EOsprintf();
|
||||
sprintf.put(0, new Data.ToPhi("%o"));
|
||||
sprintf.put(1, Phi.Φ.take("org.eolang.tuple").take("empty"));
|
||||
Assertions.assertThrows(
|
||||
EOerror.ExError.class,
|
||||
() -> new Dataized(sprintf).take(),
|
||||
"Sprintf dataization should fail because of unsupported format %o"
|
||||
);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2024 Objectionary.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @checkstyle PackageNameCheck (20 lines)
|
||||
*/
|
||||
|
||||
/**
|
||||
* EO-txt, tests.
|
||||
*
|
||||
* @since 0.39
|
||||
*/
|
||||
package EOorg.EOeolang.EOtxt;
|
@ -58,11 +58,6 @@ import org.yaml.snakeyaml.Yaml;
|
||||
* Then, when new {@code eo-runtime.jar} is
|
||||
* released to Maven Central, you enable this test again.</p>
|
||||
* @since 0.1
|
||||
* @todo #2718:30min One snippets is disabled now, in
|
||||
* the "src/test/resources/snippets/*.yaml". It needs
|
||||
* "sprintf" object in objectionary (fibo.yaml).
|
||||
* When "sprintf" is in objectionary again - we need to enable
|
||||
* it (by removing the "skip" attribute from the YAML file).
|
||||
*/
|
||||
@ExtendWith(WeAreOnline.class)
|
||||
@SuppressWarnings({"JTCOP.RuleAllTestsHaveProductionClass", "JTCOP.RuleNotContainsTestWord"})
|
||||
@ -126,7 +121,7 @@ final class SnippetTestCase {
|
||||
.set("arguments", map.get("args"));
|
||||
f.exec("clean", "test");
|
||||
final String log = f.log();
|
||||
Logger.debug(this, log);
|
||||
Logger.info(this, log);
|
||||
MatcherAssert.assertThat(
|
||||
String.format("'%s' printed something wrong", yml),
|
||||
log,
|
||||
|
@ -20,14 +20,14 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
---
|
||||
skip: true
|
||||
file: org/eolang/snippets/fibo.eo
|
||||
out:
|
||||
- ".*8 is the 6th number.*"
|
||||
file: org/eolang/snippets/fibo.eo
|
||||
args: [ "org.eolang.snippets.fibo" ]
|
||||
eo: |
|
||||
+package org.eolang.snippets
|
||||
+alias org.eolang.io.stdout
|
||||
+alias org.eolang.txt.sprintf
|
||||
+package org.eolang.snippets
|
||||
|
||||
# This is the default 64+ symbols comment in front of named abstract object.
|
||||
[args] > fibo
|
||||
@ -40,7 +40,8 @@ eo: |
|
||||
f (n.minus 1)
|
||||
f (n.minus 2)
|
||||
stdout > @
|
||||
QQ.txt.sprintf
|
||||
sprintf
|
||||
"%d is the %dth number\n"
|
||||
8
|
||||
f 6
|
||||
*
|
||||
f 6
|
||||
6
|
||||
|
Loading…
Reference in New Issue
Block a user