feat(#3251): introduced path object

This commit is contained in:
maxonfjvipon 2024-08-05 23:12:48 +03:00
parent 6a8fadcc2f
commit a52f475f04
No known key found for this signature in database
GPG Key ID: D8563899D473D273
12 changed files with 949 additions and 185 deletions

View File

@ -21,7 +21,7 @@
# SOFTWARE.
---
tests:
- //o[@base='.as-bytes' and @line and @pos and @name='x' and o[@base='org.eolang.dataized' and o[@base='org.eolang.int' and not(@name)]]]
- //o[@base='.as-bytes' and @line and @pos and @name='x' and o[@base='org.eolang.dataized' and o[@base='org.eolang.number' and not(@name)]]]
- //o[@base='.as-bytes' and @line and @pos and @name='m' and o[@base='org.eolang.dataized' and o[@abstract and @name='m-3' and count(o)=2]]]
- //o[@base='.as-bytes' and @line and @pos and @name='z' and o[@base='org.eolang.dataized' and o[@base='.o' and not(@name) and count(o)=1]]]
- //o[@base='.as-bytes' and @line and @pos and @name='y' and o[@base='org.eolang.dataized' and o[@base='org.eolang.c' and not(@name)]]]
@ -29,7 +29,7 @@ tests:
eo: |
# This is the default 64+ symbols comment in front of abstract object.
[] > foo
int > x!
number > x!
# This is the default 64+ symbols comment in front of named abstract object.
[] > m!
a

View File

@ -20,7 +20,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
+alias org.eolang.sys.os
+alias org.eolang.txt.sprintf
+architect yegor256@gmail.com
+home https://github.com/objectionary/eo
@ -31,32 +30,11 @@
# A file on the filesystem.
[path] > file
path > @
$.path > @
# Returns `true` if current file is a directory, returns `false` otherwise.
[] > is-directory /bool
# The system-dependent default name-separator character.
# On UNIX systems the value of this field is "/";
# on Microsoft Windows systems it is "\\".
[] > separator
string > @
as-bytes.
if.
os.is-windows
"\\"
"/"
# Resolves `other` path against `path` and returns as new `file` from it.
[other] > resolved
QQ.fs.file resolve.as-bytes.as-string > @
# Resolves `other` path against `^.path` and returns as `string`.
#
# Attention! The object is for internal usage only, please
# don't use the object programmatically outside of `file` object.
[] > resolve /string
# Returns `true` if file with current `path` exists in filesystem.
[] > exists /bool
@ -110,6 +88,9 @@
# don't use the object programmatically outside of `file` object.
[] > move /string
# Convert the `file` to `path`.
(QQ.fs.path ^.path).determined > [] > as-path
# Opens the file.
#
# The first argument `mode` defines the operations that are allowed on the file

View File

@ -0,0 +1,541 @@
# 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.sys.os
+alias org.eolang.structs.list
+alias org.eolang.txt.regex
+alias org.eolang.txt.text
+architect yegor256@gmail.com
+home https://github.com/objectionary/eo
+package org.eolang.fs
+rt jvm org.eolang:eo-runtime:0.0.0
+rt node eo2js-runtime:0.0.0
+version 0.0.0
# A `path` represents a path that is hierarchical and composed of a sequence of
# directory and file name elements separated by a special separator or delimiter.
[uri] > path
determined. > @
if.
os.is-windows
win32
string uri.as-bytes
posix
string uri.as-bytes
# Utility object that joins given `tuple` of paths with current OS separator
# and normalizes result path.
[paths] > joined
as-string. > joined-path
as-bytes.
joined.
text ^.separator
paths
normalized. > @
if.
os.is-windows
^.win32 joined-path
^.posix joined-path
# The system-dependent default name-separator character.
# On UNIX systems the value of this field is "/";
# on Microsoft Windows systems it is "\\".
[] > separator
if. > @
os.is-windows
^.win32.separator
^.posix.separator
# POSIX specified path.
[uri] > posix
$ > determined
"/" > separator
(QQ.fs.file uri).size.^ > as-file
(QQ.fs.dir (QQ.fs.file uri)).made.^ > as-dir
uri > @
# Returns `true` if current path is absolute - starts with '/' char.
[] > is-absolute
and. > @
^.uri.length.gt 0
(^.uri.as-bytes.slice 0 1).eq ^.separator
# Return new `path` with normalized uri.
# Normalization includes:
# - converting multiple slashes into a single slash.
# - resolving "." (current directory) and ".." (parent directory) segments.
[] > normalized
^.uri.as-bytes > uri-as-bytes
^.is-absolute.as-bool > is-absolute
and. > has-trailing-slash
uri-as-bytes.size.gt 0
eq.
uri-as-bytes.slice
uri-as-bytes.size.plus -1
1
^.separator
joined. > path
text ^.separator
reduced.
list
split.
text ^.uri
^.separator
*
[accum segment] >>
if. > @
segment.eq ".."
if.
and.
accum.length.gt 0
(accum.tail.eq "..").not
accum.head
if.
^.is-absolute.not
accum.with segment
accum
if.
or.
segment.eq "."
segment.eq ""
accum
accum.with segment
as-bytes. > normalized
if.
^.uri.length.eq 0
"."
concat.
if.
is-absolute
^.separator.concat path
path
if.
has-trailing-slash
^.separator
--
determined. > @
^.^.posix
as-string.
if.
normalized.eq "//"
"/"
normalized
# Resolves `other` path against `^.uri` and returns as new `path` from it.
# The original `uri` and resolving `other` may be:
# - absolute - start with unix separator '/'
# - relative - start with '.', '..' or any letter
#
# The resolving works as follows:
# |----------|----------|-------------|
# | uri | other | result |
# |==========|==========|=============|
# | absolute | absolute | other |
# | absolute | relative | uri + other |
# | relative | absolute | other |
# | relative | relative | uri + other |
# |----------|----------|-------------|
[other] > resolved
other.as-bytes > other-as-bytes
normalized. > @
^.^.posix
string
if.
(other-as-bytes.slice 0 1).eq ^.separator
other-as-bytes
concat.
concat.
^.uri
^.separator
other-as-bytes
# Takes the base name from the provided `path`, for example:
# |------------------------------|---------------|
# | path | result |
# |==============================|===============|
# | "/tmp/bar/foo.txt" | "foo.txt" |
# | "/tmp/bar/foo/" | "" |
# | "/var/www/html" | "html" |
# | "Hello, Jeff" | "Hello, Jeff" |
# | "" | "" |
# |------------------------------|---------------|
#
# Unix OS allows to have "\" (backslash) if file name.
# In such case it'll be included to the base name since separator
# is "/" (regular slash) in Unix OS:
# With the `path` "/tmp/var/hello\world" `base-name` returns `hello\world`.
[] > basename
^.uri > pth!
text > txt
string pth
plus. > slice-start-idx!
txt.last-index-of ^.separator
1
string > @
if.
or.
pth.size.eq 0
slice-start-idx.eq 0
pth
as-bytes.
txt.slice
slice-start-idx
txt.length.minus
number slice-start-idx
# Takes the extension part from the provided `path`, for example:
# |------------------------------|--------|
# | path | result |
# |==============================|========|
# | "/tmp/bar/foo.txt" | ".txt" |
# | "/tmp/bar/foo/" | "" |
# | /var/www/html | "" |
# | "Hello, Jeff" | "" |
# | "" | "" |
# |------------------------------|--------|
#
# The object takes the `basename` from the provided path
# and returns substring after "." if it's found.
# If it's not - empty string is returned.
[] > extname
^.basename > base!
text > txt
string base
txt.last-index-of "." > slice-start-idx!
if. > @
or.
base.size.eq 0
slice-start-idx.eq -1
""
string
as-bytes.
txt.slice
slice-start-idx
txt.length.minus
number slice-start-idx
# Takes the directory name from the provided `path`, for example:
# |------------------------------|--------------------|
# | path | result |
# |==============================|====================|
# | "/tmp/bar/foo.txt" | "/tmp/bar" |
# | "/tmp/bar/foo/" | "/tmp/bar/foo" |
# | "/var/www/html" | "/var/www" |
# | "C:\Windows\Users\Error.log" | "C:\Windows\Users" |
# | "Hello, Jeff" | "Hello, Jeff" |
# | "" | "" |
# |------------------------------|--------------------|
#
# Unix OS allows to have "\" (backslash) if file or directory name.
# In such case it'll be included to the dir name since separator
# is "/" (regular slash) in Unix OS:
# With the `path` "/tmp/v\a\r/hello" `dir-name` returns `/tmp/v\a\r`.
[] > dirname
^.uri > pth!
text > txt
string pth
txt.last-index-of ^.separator > len!
string > @
if.
or.
pth.size.eq 0
len.eq -1
pth
as-bytes.
txt.slice 0 len
# Windows specified path.
# Here `uri` is file system URI which may contain forward slashes '/'.
# The object decorates `win32.validated` with forward slashes replaced with
# back ones.
[uri] > win32
"\\" > separator
determined. > @
validated
as-string.
as-bytes.
validated.separated-correctly
uri
# Windows validated path with forward slashes replaced with back ones.
#
# Attention! The object is for internal usage only, please
# don't use the object programmatically outside of `path` object.
[uri] > validated
$ > determined
^.separator > separator
(QQ.fs.file uri).size.^ > as-file
(QQ.fs.dir (QQ.fs.file uri)).made.^ > as-dir
uri > @
# Returns `true` if given `uri` is drive relative which means it
# starts with "X:" where 'X' - system drive name.
((regex "/^[a-zA-Z]:/").matches uri).as-bool > [uri] > is-drive-relative
# Returns `true` if given `uri` is root relative which means it
# starts with windows separator '\'.
[uri] > is-root-relative
uri > uri-as-bytes!
and. > @
uri-as-bytes.size.gt 0
(uri-as-bytes.slice 0 1).eq ^.separator
# Replaces slashes '/' with valid windows separator '\'.
[uri] > separated-correctly
uri > uri-as-bytes!
text > pth
string uri-as-bytes
pth.replaced > replaced!
regex "/\\//"
^.separator
if. > @
(pth.index-of path.posix.separator).eq -1
string uri-as-bytes
string replaced
# Returns `true` if current path is absolute, which means:
# - either path root is root relative (starts with "\")
# - or path is drive relative (starts with "X:\", where 'X' - 1 char disk name).
[] > is-absolute
uri > uri-as-bytes!
if. > @
uri-as-bytes.size.eq 0
false
or.
^.is-root-relative uri-as-bytes
and.
uri-as-bytes.size.gt 1
^.is-drive-relative uri-as-bytes
# Return new `path` with normalized uri.
# Normalization includes:
# - converting multiple slashes into a single slash.
# - resolving "." (current directory) and ".." (parent directory) segments.
# - handling of drive letters in Windows
[] > normalized
^.uri > uri-as-bytes!
(^.is-drive-relative uri-as-bytes).as-bool > is-drive-relative
(^.is-root-relative uri-as-bytes).as-bool > is-root-relative
if. > driveless!
is-drive-relative
uri-as-bytes.slice
2
uri-as-bytes.size.plus -2
uri-as-bytes
and. > has-trailing-slash
uri-as-bytes.size.gt 0
eq.
uri-as-bytes.slice
uri-as-bytes.size.plus -1
1
^.separator
joined. > path!
text ^.separator
reduced.
list
split.
text driveless
^.separator
*
[accum segment] >>
if. > @
segment.eq ".."
if.
and.
accum.length.gt 0
(accum.tail.eq "..").not
accum.head
if.
and.
^.is-root-relative.not
^.is-drive-relative.not
accum.with segment
accum
if.
or.
segment.eq "."
segment.eq ""
accum
accum.with segment
as-bytes. > normalized
if.
driveless.size.eq 0
"."
concat.
concat.
if.
is-drive-relative
if.
(driveless.slice 0 1).eq ^.separator
^.uri.slice 0 3
^.uri.slice 0 2
if.
is-root-relative
^.separator
--
path
if.
has-trailing-slash
^.separator
--
determined. > @
^.^.validated
as-string.
if.
normalized.eq "\\\\"
^.separator
normalized
# Resolves `other` path against `^.uri` and returns as new `path` from it.
# Original `uri` and `other` path for resolving may be:
# - drive relative - start from "X:" where 'X' - system drive name
# - root relative - start from windows separator '\'
# - any - start from '.', '..' or any letter
#
# Accounting these options resolving work as follows:
# |--------------------|----------------|-------------------|
# | uri | other | result |
# |====================|================|===================|
# | any | any | uri + other |
# | any | drive relative | other |
# | any | root relative | other |
# | drive relative | any | uri + other |
# | drive relative | drive relative | other |
# | drive relative | root relative | uri drive + other |
# | root relative | any | uri + other |
# | root relative | drive relative | other |
# | root relative | root relative | other |
# |--------------------|----------------|-------------------|
[other] > resolved
^.uri > uri-as-bytes!
^.separated-correctly other > valid-other!
(^.is-drive-relative valid-other).as-bool > other-is-drive-relative
(^.is-root-relative valid-other).as-bool > other-is-root-relative
normalized. > @
^.^.validated
string
if.
other-is-drive-relative
valid-other
if.
other-is-root-relative
if.
^.is-drive-relative uri-as-bytes
concat.
uri-as-bytes.slice 0 2
valid-other
valid-other
concat.
concat.
uri-as-bytes
^.separator
valid-other
# Takes the base name from the provided `path`, for example:
# |------------------------------|---------------|
# | path | result |
# |==============================|===============|
# | "/tmp/bar/foo.txt" | "foo.txt" |
# | "/tmp/bar/foo/" | "" |
# | "/var/www/html" | "html" |
# | "Hello, Jeff" | "Hello, Jeff" |
# | "" | "" |
# |------------------------------|---------------|
#
# Unix OS allows to have "\" (backslash) if file name.
# In such case it'll be included to the base name since separator
# is "/" (regular slash) in Unix OS:
# With the `path` "/tmp/var/hello\world" `base-name` returns `hello\world`.
[] > basename
^.uri > pth!
text > txt
string pth
plus. > slice-start-idx!
txt.last-index-of ^.separator
1
string > @
if.
or.
pth.size.eq 0
slice-start-idx.eq 0
pth
as-bytes.
txt.slice
slice-start-idx
txt.length.minus
number slice-start-idx
# Takes the extension part from the provided `path`, for example:
# |------------------------------|--------|
# | path | result |
# |==============================|========|
# | "/tmp/bar/foo.txt" | ".txt" |
# | "/tmp/bar/foo/" | "" |
# | /var/www/html | "" |
# | "Hello, Jeff" | "" |
# | "" | "" |
# |------------------------------|--------|
#
# The object takes the `basename` from the provided path
# and returns substring after "." if it's found.
# If it's not - empty string is returned.
[] > extname
^.basename > base!
text > txt
string base
txt.last-index-of "." > slice-start-idx!
if. > @
or.
base.size.eq 0
slice-start-idx.eq -1
""
string
as-bytes.
txt.slice
slice-start-idx
txt.length.minus
number slice-start-idx
# Takes the directory name from the provided `path`, for example:
# |------------------------------|--------------------|
# | path | result |
# |==============================|====================|
# | "/tmp/bar/foo.txt" | "\tmp\bar" |
# | "\tmp\bar\foo\" | "\tmp\bar\foo" |
# | "/var/www/html" | "\var\www" |
# | "C:\Windows\Users\Error.log" | "C:\Windows\Users" |
# | "Hello, Jeff" | "Hello, Jeff" |
# | "" | "" |
# |------------------------------|--------------------|
[] > dirname
^.uri > pth!
text > txt
string pth
txt.last-index-of ^.separator > len!
string > @
if.
or.
pth.size.eq 0
len.eq -1
pth
as-bytes.
txt.slice 0 len

View File

@ -141,7 +141,7 @@
error > get
sprintf
"Object by hash code %d from given key does not exists"
* (int ^.hash)
* ^.hash
# Returns the new `map` with added object
# Replaces if there was one before.

View File

@ -322,12 +322,38 @@
* 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 `text` where all regex target changed to replacement.
# Here `target` must be a `org.eolang.txt.regex` object.
# The `replacement` here is a `string` that would be pasted instead of
# matched text in original one.
[target replacement] > replaced
^.origin > self-as-bytes!
string self-as-bytes > reinit
(target.match reinit).next > matched
if. > @
matched.exists.not
QQ.txt.text reinit
QQ.txt.text
rec-replaced matched "" matched.start
[block accum start] > rec-replaced
if. > @
block.exists
^.rec-replaced
block.next
concat.
concat.
accum
^.reinit.slice
start
block.from.minus start
^.replacement
block.to
as-string.
accum.concat
^.reinit.slice
start
^.reinit.length.minus start
# Returns the original `text` as `number`.
[] > as-number
@ -340,16 +366,15 @@
* ^.origin
scanned.tail
# Returns a `list` of `strings`, separated by a given `delimiter`.
# Returns a `tuple` 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
if. > @
len.eq 0
*
rec-split * 0 0
[accum start current] > rec-split
if. > @

View File

@ -1,58 +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.EOfs;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import org.eolang.Atom;
import org.eolang.Attr;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhDefault;
import org.eolang.Phi;
import org.eolang.XmirObject;
/**
* File.resolved.resolve.
*
* @since 0.40
* @checkstyle TypeNameCheck (100 lines)
*/
@XmirObject(oname = "file.resolved.resolve")
public final class EOfile$EOresolved$EOresolve extends PhDefault implements Atom {
@Override
public Phi lambda() throws Exception {
final Phi rho = this.take(Attr.RHO);
return new Data.ToPhi(
Paths.get(new Dataized(rho.take(Attr.RHO).take("path")).asString())
.resolve(new Dataized(rho.take("other")).asString())
.toString()
);
}
}

View File

@ -93,15 +93,13 @@ final class PhPackage implements Phi {
final String obj = this.eoPackage(name);
final String key = new JavaPath(obj).toString();
if (!this.objects.get().containsKey(key)) {
this.objects.get().put(key, this.loadPhi(key).orElseGet(() -> new PhPackage(obj)));
}
final Phi res;
final Phi phi = this.objects.get().get(key);
if (phi instanceof PhPackage) {
res = phi;
} else {
res = new AtSetRho(this.objects.get().get(key), this, key).get();
final Phi initialized = this.loadPhi(key).orElseGet(() -> new PhPackage(obj));
if (!(initialized instanceof PhPackage)) {
initialized.put(Attr.RHO, this);
}
this.objects.get().put(key, initialized);
}
final Phi res = this.objects.get().get(key);
this.objects.remove();
return res;
}

View File

@ -35,18 +35,20 @@
# test.
[] > makes-new-directory
made. > d
dir
tmpdir.tmpfile.deleted.resolved "foo-new"
(tmpdir.tmpfile.deleted.as-path.resolved "foo-new").as-dir.made > d
and. > @
d.exists
d.is-directory
# Test.
[] > deletes-empty-directory
dir
tmpdir.tmpfile.deleted.resolved
"bar-empty"
tmpdir
.tmpfile
.deleted
.as-path
.resolved
"bar-empty"
.as-dir
.made
.deleted
.exists
@ -92,11 +94,11 @@
# Test.
[] > walks-recursively
(dir tmpdir.tmpfile.deleted).made > d
(dir tmpdir.tmpfile.deleted).made.as-path > d
seq > @
*
(dir (d.resolved "foo/bar")).made
(d.resolved "foo/bar/test.txt").touched
(dir (d.resolved "x/y/z")).made
(d.resolved "x/y/z/a.txt").touched
(d.walk "**/*.txt").length.eq 2
(d.resolved "foo/bar").as-dir.made
(d.resolved "foo/bar/test.txt").as-file.touched
(d.resolved "x/y/z").as-dir.made
(d.resolved "x/y/z/a.txt").as-file.touched
(d.as-dir.walk "**/*.txt").length.eq 2

View File

@ -20,8 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
+alias org.eolang.fs.dir
+alias org.eolang.fs.file
+alias org.eolang.fs.path
+alias org.eolang.fs.tmpdir
+alias org.eolang.txt.sprintf
+alias org.eolang.txt.text
@ -71,20 +71,22 @@
# Test.
[] > throws-an-error-on-touching-temp-file-in-absent-dir
(tmpdir.resolve "foo").tmpfile > @
(tmpdir.as-path.resolved "foo").as-dir.tmpfile > @
# Test.
[] > resolves-and-touches
dir (tmpdir.resolved "foo/bar") > resolved
(tmpdir.as-path.resolved "foo/bar").as-dir > resolved
resolved.tmpfile > f
seq > @
*
resolved.deleted.made.path
resolved.deleted.made
and.
f.exists
contains.
text f.path
"bar"
joined.
text path.separator
* "foo" "bar"
# Test.
[] > moves-a-file

View File

@ -0,0 +1,275 @@
# 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.sys.os
+alias org.eolang.fs.path
+architect yegor256@gmail.com
+home https://github.com/objectionary/eo
+tests
+package org.eolang.fs
+version 0.0.0
# Test.
[] > determines-separator-depending-on-os
eq. > @
path.separator
if.
os.is-windows
path.win32.separator
path.posix.separator
# Test.
[] > detects-absolute-posix-path
and. > @
(path.posix "/var/www/html").is-absolute
(path.posix "foo/bar/baz").is-absolute.not
# Test.
[] > detects-absolute-win32-path
and. > @
and.
(path.win32 "C:\\Windows\\Users").is-absolute
(path.win32 "\\Windows\\Users").is-absolute
(path.win32 "temp\\var").is-absolute.not
# Test.
[] > normalizes-posix-path
eq. > @
(path.posix "/foo/bar/.//./baz//../x/").normalized
"/foo/bar/x/"
# Test.
[] > normalizes-posix-relative-path
eq. > @
(path.posix "../../foo/./bar/../x/../y").normalized
"../../foo/y"
# Test.
[] > normalizes-empty-posix-path-to-current-dir
eq. > @
(path.posix "").normalized
"."
# Test.
[] > normalizes-path-to-root
eq. > @
(path.posix "/foo/bar/baz/../../../../").normalized
"/"
# Test.
[] > normalizes-absolute-win32-path-without-drive
eq. > @
(path.win32 "\\Windows\\Users\\..\\App\\\\.\\Local\\\\").normalized
"\\Windows\\App\\Local\\"
# Test.
[] > normalizes-absolute-win32-path-with-drive
eq. > @
(path.win32 "C:\\Windows\\\\..\\Users\\.\\AppLocal").normalized
"C:\\Users\\AppLocal"
# Test.
[] > normalizes-relative-win32-path
eq. > @
(path.win32 "..\\..\\foo\\bar\\..\\x\\y\\\\").normalized
"..\\..\\foo\\x\\y\\"
# Test.
[] > normalizes-empty-win32-driveless-path-to-current-dir
eq. > @
(path.win32 "").normalized
"."
# Test.
[] > normalizes-win32-path-down-to-drive-with-separator
eq. > @
(path.win32 "C:\\Windows\\..").normalized
"C:\\"
# Test.
[] > normalizes-win32-path-down-to-drive-without-separator
eq. > @
(path.win32 "C:hello\\..").normalized
"C:"
# Test.
[] > normalizes-win32-path-with-replacing-slashes
eq. > @
(path.win32 "/var/www/../html/").normalized
"\\var\\html\\"
# Test.
[] > resolves-posix-absolute-path-against-other-absolute-path
eq. > @
(path.posix "/var/temp").resolved "/www/html"
"/www/html"
# Test.
[] > resolves-posix-absolute-path-against-other-relative-path
eq. > @
(path.posix "/var/temp").resolved "./www/html"
"/var/temp/www/html"
# Test.
[] > resolves-posix-relative-path-against-other-absolute-path
eq. > @
(path.posix "./var/temp").resolved "/www/html"
"/www/html"
# Test.
[] > resolves-posix-relative-path-against-other-relative-path
eq. > @
(path.posix "./var/temp").resolved "../www/html"
"var/www/html"
# Test.
[] > resolves-win32-relative-path-against-other-relative-path
eq. > @
(path.win32 ".\\temp\\var").resolved ".\\..\\x"
"temp\\x"
# Test.
[] > resolves-win32-relative-path-against-other-drive-relative-path
eq. > @
(path.win32 ".\\temp\\var").resolved "C:\\Windows\\Users"
"C:\\Windows\\Users"
# Test.
[] > resolves-win32-relative-path-against-other-root-relative-path
eq. > @
(path.win32 ".\\temp\\var").resolved "\\Windows\\Users"
"\\Windows\\Users"
# Test.
[] > resolves-win32-drive-relative-path-against-other-relative-path
eq. > @
(path.win32 "C:\\users\\local").resolved ".\\var\\temp"
"C:\\users\\local\\var\\temp"
# Test.
[] > resolves-win32-drive-relative-path-against-other-drive-relative-path
eq. > @
(path.win32 "C:\\users\\local").resolved "D:\\local\\var"
"D:\\local\\var"
# Test.
[] > resolves-win32-drive-relative-path-against-other-root-relative-path
eq. > @
(path.win32 "C:\\users\\local").resolved "\\local\\var"
"C:\\local\\var"
# Test.
[] > resolves-win32-root-relative-path-against-other-relative-path
eq. > @
(path.win32 "\\users\\local").resolved ".\\hello\\var"
"\\users\\local\\hello\\var"
# Test.
[] > resolves-win32-root-relative-path-against-other-drive-relative-path
eq. > @
(path.win32 "\\users\\local").resolved "D:\\hello\\var"
"D:\\hello\\var"
# Test.
[] > resolves-win32-root-relative-path-against-other-root-relative-path
eq. > @
(path.win32 "\\users\\local").resolved "\\hello\\var"
"\\hello\\var"
# Test.
[] > takes-valid-basename
eq. > @
basename.
path.joined
* "var" "www" "html" "hello.eo"
"hello.eo"
# Test.
[] > returns-empty-basename-from-path-ended-with-separator
eq. > @
basename.
path.joined
* "var" "www" "html" path.separator
""
# Test.
[] > returns-base-with-backslash-in-path-on-posix
eq. > @
(path.posix "/var/www/html/foo\\bar").basename
"foo\\bar"
# Test.
[] > returns-the-same-string-if-no-separator-is-found
eq. > @
(path "Somebody").basename
"Somebody"
# Test.
[] > takes-file-extname
eq. > @
extname.
path.joined
* "var" "www" "hello.txt"
".txt"
# Test.
[] > does-not-take-extname-on-file-without-extension
eq. > @
extname.
path.joined
* "var" "www" "html"
""
# Test.
[] > does-not-take-extname-if-ends-with-separator
eq. > @
extname.
path.joined
* "var" "www" path.separator
""
# Test.
[] > returns-valid-dirname-from-file-path
eq. > @
dirname.
path.joined
* "var" "www" "hello.txt"
path.joined
* "var" "www"
# Test.
[] > returns-valid-dirname-from-dir-path
eq. > @
dirname.
path.joined
* "var" "www" path.separator
path.joined
* "var" "www"
# Test.
[] > returns-valid-dirname-from-file-path-without-extension
eq. > @
dirname.
path.joined
* "var" "www" "html"
path.joined
* "var" "www"

View File

@ -20,8 +20,10 @@
# 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
+alias org.eolang.structs.list
+alias org.eolang.txt.regex
+alias org.eolang.txt.text
+architect yegor256@gmail.com
+home https://github.com/objectionary/eo
+tests
@ -273,13 +275,15 @@
# Test.
[] > splits-text-by-dash
eq. > @
(text "a-b-c").split "-"
list
(text "a-b-c").split "-"
* "a" "b" "c"
# Test.
[] > splits-text-with-empty-strings
eq. > @
(text "-a-b-").split "-"
list
(text "-a-b-").split "-"
* "" "a" "b" ""
# Test.
@ -382,3 +386,58 @@
is-alpha.
text
"-w-"
# Test.
[] > does-not-replaces-if-regex-not-found
text
"Hello, world"
.replaced
regex
"/[0-9]+/"
"12345"
.eq > @
"Hello, world"
# Test.
[] > replaces-digits-with-string
text
"Hell0, w0rld"
.replaced
regex
"/[0-9]+/"
"o"
.eq > @
"Hello, world"
# Test.
[] > replaces-slashes-to-windows-separator
text
"C:\\Windows/foo\\bar/hello.txt"
.replaced
regex
"/\\//"
"\\"
.eq > @
"C:\\Windows\\foo\\bar\\hello.txt"
# Test.
[] > replaces-windows-path-with-slash
text
"C:\\Windows\\Users\\AppLocal\\shrek"
.replaced
regex
"/[\\\\:]+/"
"/"
.eq > @
"C/Windows/Users/AppLocal/shrek"
# Test.
[] > sanitizes-windows-path-with-regex
text
"foo\\bar<:>?*\"|baz\\asdf"
.replaced
regex
"/[<>:\\\"\\/\\|\\?\\*\\x00-\\x1F]/"
""
.eq > @
"foo\\barbaz\\asdf"

View File

@ -1,61 +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.EOfs;
import java.nio.file.Path;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhWith;
import org.eolang.Phi;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
/**
* Test case for {@link EOfile}.
* @since 0.40
*/
@SuppressWarnings("JTCOP.RuleAllTestsHaveProductionClass")
final class EOfileTest {
@Test
void resolvesPath(@TempDir final Path temp) {
final Phi resolved = new PhWith(
new EOfile(),
"path", new Data.ToPhi(temp.toAbsolutePath().toString())
).take("resolved").copy();
resolved.put(0, new Data.ToPhi("foo/bar/baz"));
MatcherAssert.assertThat(
"The `file.resolved` object should resolve in a right way",
new Dataized(resolved).asString(),
Matchers.equalTo(
temp.resolve("foo/bar/baz").toAbsolutePath().toString()
)
);
}
}