Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
ContenT
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
ContenT
Commits
daedc86a
Commit
daedc86a
authored
Feb 17, 2026
by
Roman Alifanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add json.get, str.urlencode and Telegram echobot example
parent
8e34932a
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
222 additions
and
8 deletions
+222
-8
LANGUAGE_SPEC.md
LANGUAGE_SPEC.md
+32
-2
README.md
README.md
+15
-2
README_ru.md
README_ru.md
+15
-2
dce.py
bootstrap/dce.py
+1
-1
dispatch_codegen.py
bootstrap/dispatch_codegen.py
+5
-1
stdlib.py
bootstrap/stdlib.py
+10
-0
stmt_codegen.py
bootstrap/stmt_codegen.py
+1
-0
echobot.ct
examples/telegram_echobot/echobot.ct
+61
-0
test_integration.py
tests/test_integration.py
+82
-0
No files found.
LANGUAGE_SPEC.md
View file @
daedc86a
...
@@ -584,6 +584,33 @@ result = json.stringify (data)
...
@@ -584,6 +584,33 @@ result = json.stringify (data)
# {"name":"Alice","age":30,"city":"NYC"}
# {"name":"Alice","age":30,"city":"NYC"}
```
```
**json.get — извлечение из вложенного JSON:**
```
json_str = "\{\"user\": \{\"name\": \"Bob\", \"age\": 25\}\}"
name = json.get (json_str, ".user.name") # "Bob"
age = json.get (json_str, ".user.age") # 25
# Работа с массивами
items = "\{\"items\": [1, 2, 3]\}"
first = json.get (items, ".items[0]") # 1
count = json.get (items, ".items | length") # 3
```
Использует jq под капотом — поддерживает все jq-пути.
**Пример: Telegram бот**
```
response = http.get ("{base_url}/getUpdates")
chat_id = json.get (response, ".result[0].message.chat.id")
text = json.get (response, ".result[0].message.text")
encoded = text.urlencode ()
http.get ("{base_url}/sendMessage?chat_id={chat_id}&text={encoded}")
```
**Примечание:**
фигурные скобки в строках нужно экранировать как
`\{`
и
`\}`
.
**Примечание:**
фигурные скобки в строках нужно экранировать как
`\{`
и
`\}`
.
### logger
### logger
...
@@ -622,6 +649,9 @@ char = text.charAt (0) # H
...
@@ -622,6 +649,9 @@ char = text.charAt (0) # H
replaced = text.replace ("World", "ContenT")
replaced = text.replace ("World", "ContenT")
parts = text.split (", ") # массив ["Hello", "World!"]
parts = text.split (", ") # массив ["Hello", "World!"]
# URL-кодирование
encoded = text.urlencode () # "Hello%2C%20World%21"
# Символы (глобальные функции)
# Символы (глобальные функции)
code = ord ("A") # 65
code = ord ("A") # 65
char = chr (65) # "A"
char = chr (65) # "A"
...
@@ -929,12 +959,12 @@ Error: Unknown method 'badMethod' for type 'fs'. Available: append, exists, list
...
@@ -929,12 +959,12 @@ Error: Unknown method 'badMethod' for type 'fs'. Available: append, exists, list
Проверяются методы для:
Проверяются методы для:
-
**Массивов**
—
`filter`
,
`get`
,
`join`
,
`len`
,
`map`
,
`pop`
,
`push`
,
`set`
,
`shift`
,
`slice`
-
**Массивов**
—
`filter`
,
`get`
,
`join`
,
`len`
,
`map`
,
`pop`
,
`push`
,
`set`
,
`shift`
,
`slice`
-
**Словарей**
—
`del`
,
`get`
,
`has`
,
`keys`
,
`set`
-
**Словарей**
—
`del`
,
`get`
,
`has`
,
`keys`
,
`set`
-
**Строк**
—
`charAt`
,
`contains`
,
`ends`
,
`index`
,
`len`
,
`lower`
,
`replace`
,
`split`
,
`starts`
,
`substr`
,
`trim`
,
`upper`
-
**Строк**
—
`charAt`
,
`contains`
,
`ends`
,
`index`
,
`len`
,
`lower`
,
`replace`
,
`split`
,
`starts`
,
`substr`
,
`trim`
,
`upper`
,
`urlencode`
-
**Файловых дескрипторов**
—
`close`
,
`read`
,
`readline`
,
`write`
,
`writeln`
-
**Файловых дескрипторов**
—
`close`
,
`read`
,
`readline`
,
`write`
,
`writeln`
-
**Stdlib namespaces**
:
-
**Stdlib namespaces**
:
-
`fs`
—
`append`
,
`exists`
,
`list`
,
`mkdir`
,
`open`
,
`read`
,
`remove`
,
`write`
-
`fs`
—
`append`
,
`exists`
,
`list`
,
`mkdir`
,
`open`
,
`read`
,
`remove`
,
`write`
-
`http`
—
`delete`
,
`get`
,
`post`
,
`put`
-
`http`
—
`delete`
,
`get`
,
`post`
,
`put`
-
`json`
—
`parse`
,
`stringify`
-
`json`
—
`
get`
,
`
parse`
,
`stringify`
-
`logger`
—
`debug`
,
`error`
,
`info`
,
`warn`
-
`logger`
—
`debug`
,
`error`
,
`info`
,
`warn`
-
`regex`
—
`extract`
,
`match`
-
`regex`
—
`extract`
,
`match`
-
`args`
—
`count`
,
`get`
-
`args`
—
`count`
,
`get`
...
...
README.md
View file @
daedc86a
...
@@ -199,8 +199,8 @@ try {
...
@@ -199,8 +199,8 @@ try {
|
**HTTP**
|
`http.get/post/put/delete`
|
|
**HTTP**
|
`http.get/post/put/delete`
|
|
**Filesystem**
|
`fs.read/write/append/exists/remove/mkdir/list`
,
`fs.open()`
|
|
**Filesystem**
|
`fs.read/write/append/exists/remove/mkdir/list`
,
`fs.open()`
|
|
**File handles**
|
`f.read()`
,
`f.readline()`
,
`f.write()`
,
`f.writeln()`
,
`f.close()`
|
|
**File handles**
|
`f.read()`
,
`f.readline()`
,
`f.write()`
,
`f.writeln()`
,
`f.close()`
|
|
**JSON**
|
`json.parse()`
→ dict,
`json.stringify()`
→ string |
|
**JSON**
|
`json.parse()`
→ dict,
`json.stringify()`
→ string
,
`json.get(str, path)`
→ extract by jq path
|
|
**Strings**
|
`.len()`
,
`.upper()`
,
`.lower()`
,
`.trim()`
,
`.contains()`
,
`.replace()`
,
`.split()`
,
`.substr()`
|
|
**Strings**
|
`.len()`
,
`.upper()`
,
`.lower()`
,
`.trim()`
,
`.contains()`
,
`.replace()`
,
`.split()`
,
`.substr()`
,
`.urlencode()`
|
|
**Arrays**
|
`.push()`
,
`.pop()`
,
`.shift()`
,
`.len()`
,
`.get()`
,
`.set()`
,
`.join()`
,
`.slice()`
,
`.map()`
,
`.filter()`
|
|
**Arrays**
|
`.push()`
,
`.pop()`
,
`.shift()`
,
`.len()`
,
`.get()`
,
`.set()`
,
`.join()`
,
`.slice()`
,
`.map()`
,
`.filter()`
|
|
**Dicts**
|
`.get()`
,
`.set()`
,
`.has()`
,
`.del()`
,
`.keys()`
|
|
**Dicts**
|
`.get()`
,
`.set()`
,
`.has()`
,
`.del()`
,
`.keys()`
|
|
**Regex**
|
`regex.match/extract`
|
|
**Regex**
|
`regex.match/extract`
|
...
@@ -338,6 +338,19 @@ FAIL failing test (1ms)
...
@@ -338,6 +338,19 @@ FAIL failing test (1ms)
2 of 3 tests passed
2 of 3 tests passed
```
```
## Examples
### Telegram Echo Bot
A simple Telegram bot that echoes messages back (
`examples/telegram_echobot/`
):
```
bash
export
TELEGRAM_BOT_TOKEN
=
"your_token"
python3 content run examples/telegram_echobot/echobot.ct
```
Uses
`json.get()`
for parsing Telegram API responses and
`str.urlencode()`
for URL encoding.
## Documentation
## Documentation
-
[
Language Specification
](
LANGUAGE_SPEC.md
)
-
[
Language Specification
](
LANGUAGE_SPEC.md
)
...
...
README_ru.md
View file @
daedc86a
...
@@ -199,8 +199,8 @@ try {
...
@@ -199,8 +199,8 @@ try {
|
**HTTP**
|
`http.get/post/put/delete`
|
|
**HTTP**
|
`http.get/post/put/delete`
|
|
**Файловая система**
|
`fs.read/write/append/exists/remove/mkdir/list`
,
`fs.open()`
|
|
**Файловая система**
|
`fs.read/write/append/exists/remove/mkdir/list`
,
`fs.open()`
|
|
**Файловые дескрипторы**
|
`f.read()`
,
`f.readline()`
,
`f.write()`
,
`f.writeln()`
,
`f.close()`
|
|
**Файловые дескрипторы**
|
`f.read()`
,
`f.readline()`
,
`f.write()`
,
`f.writeln()`
,
`f.close()`
|
|
**JSON**
|
`json.parse()`
→ dict,
`json.stringify()`
→ string |
|
**JSON**
|
`json.parse()`
→ dict,
`json.stringify()`
→ string
,
`json.get(str, path)`
→ извлечь по jq-пути
|
|
**Строки**
|
`.len()`
,
`.upper()`
,
`.lower()`
,
`.trim()`
,
`.contains()`
,
`.replace()`
,
`.split()`
,
`.substr()`
|
|
**Строки**
|
`.len()`
,
`.upper()`
,
`.lower()`
,
`.trim()`
,
`.contains()`
,
`.replace()`
,
`.split()`
,
`.substr()`
,
`.urlencode()`
|
|
**Массивы**
|
`.push()`
,
`.pop()`
,
`.shift()`
,
`.len()`
,
`.get()`
,
`.set()`
,
`.join()`
,
`.slice()`
,
`.map()`
,
`.filter()`
|
|
**Массивы**
|
`.push()`
,
`.pop()`
,
`.shift()`
,
`.len()`
,
`.get()`
,
`.set()`
,
`.join()`
,
`.slice()`
,
`.map()`
,
`.filter()`
|
|
**Словари**
|
`.get()`
,
`.set()`
,
`.has()`
,
`.del()`
,
`.keys()`
|
|
**Словари**
|
`.get()`
,
`.set()`
,
`.has()`
,
`.del()`
,
`.keys()`
|
|
**Regex**
|
`regex.match/extract`
|
|
**Regex**
|
`regex.match/extract`
|
...
@@ -338,6 +338,19 @@ FAIL падающий тест (1ms)
...
@@ -338,6 +338,19 @@ FAIL падающий тест (1ms)
2 of 3 tests passed
2 of 3 tests passed
```
```
## Примеры
### Telegram эхо-бот
Простой Telegram-бот, который отправляет сообщения обратно (
`examples/telegram_echobot/`
):
```
bash
export
TELEGRAM_BOT_TOKEN
=
"your_token"
python3 content run examples/telegram_echobot/echobot.ct
```
Использует
`json.get()`
для парсинга ответов Telegram API и
`str.urlencode()`
для URL-кодирования.
## Документация
## Документация
-
[
Спецификация языка
](
LANGUAGE_SPEC.md
)
-
[
Спецификация языка
](
LANGUAGE_SPEC.md
)
...
...
bootstrap/dce.py
View file @
daedc86a
...
@@ -349,7 +349,7 @@ class UsageAnalyzer:
...
@@ -349,7 +349,7 @@ class UsageAnalyzer:
def
_check_method
(
self
,
method
:
str
):
def
_check_method
(
self
,
method
:
str
):
string_methods
=
{
'upper'
,
'lower'
,
'trim'
,
'len'
,
'contains'
,
'starts'
,
string_methods
=
{
'upper'
,
'lower'
,
'trim'
,
'len'
,
'contains'
,
'starts'
,
'ends'
,
'index'
,
'replace'
,
'substr'
,
'split'
,
'charAt'
}
'ends'
,
'index'
,
'replace'
,
'substr'
,
'split'
,
'charAt'
,
'urlencode'
}
array_methods
=
{
'push'
,
'pop'
,
'shift'
,
'join'
,
'get'
,
'set'
,
'slice'
,
'len'
}
array_methods
=
{
'push'
,
'pop'
,
'shift'
,
'join'
,
'get'
,
'set'
,
'slice'
,
'len'
}
dict_methods
=
{
'get'
,
'set'
,
'has'
,
'del'
,
'keys'
}
dict_methods
=
{
'get'
,
'set'
,
'has'
,
'del'
,
'keys'
}
...
...
bootstrap/dispatch_codegen.py
View file @
daedc86a
...
@@ -18,6 +18,7 @@ STR_METHODS = {
...
@@ -18,6 +18,7 @@ STR_METHODS = {
"trim"
:
"__ct_str_trim"
,
"contains"
:
"__ct_str_contains"
,
"starts"
:
"__ct_str_starts"
,
"trim"
:
"__ct_str_trim"
,
"contains"
:
"__ct_str_contains"
,
"starts"
:
"__ct_str_starts"
,
"ends"
:
"__ct_str_ends"
,
"index"
:
"__ct_str_index"
,
"replace"
:
"__ct_str_replace"
,
"ends"
:
"__ct_str_ends"
,
"index"
:
"__ct_str_index"
,
"replace"
:
"__ct_str_replace"
,
"substr"
:
"__ct_str_substr"
,
"split"
:
"__ct_str_split"
,
"charAt"
:
"__ct_str_char_at"
,
"substr"
:
"__ct_str_substr"
,
"split"
:
"__ct_str_split"
,
"charAt"
:
"__ct_str_char_at"
,
"urlencode"
:
"__ct_str_urlencode"
,
}
}
FILE_HANDLE_METHODS
=
{
FILE_HANDLE_METHODS
=
{
...
@@ -32,7 +33,7 @@ BUILTIN_FUNCS = {"print", "exit", "len", "range", "ngrep", "is_number", "is_empt
...
@@ -32,7 +33,7 @@ BUILTIN_FUNCS = {"print", "exit", "len", "range", "ngrep", "is_number", "is_empt
FS_METHODS
=
{
"read"
,
"write"
,
"append"
,
"exists"
,
"remove"
,
"mkdir"
,
"list"
,
"open"
}
FS_METHODS
=
{
"read"
,
"write"
,
"append"
,
"exists"
,
"remove"
,
"mkdir"
,
"list"
,
"open"
}
HTTP_METHODS
=
{
"get"
,
"post"
,
"put"
,
"delete"
}
HTTP_METHODS
=
{
"get"
,
"post"
,
"put"
,
"delete"
}
JSON_METHODS
=
{
"parse"
,
"stringify"
}
JSON_METHODS
=
{
"parse"
,
"stringify"
,
"get"
}
LOGGER_METHODS
=
{
"info"
,
"warn"
,
"error"
,
"debug"
}
LOGGER_METHODS
=
{
"info"
,
"warn"
,
"error"
,
"debug"
}
REGEX_METHODS
=
{
"match"
,
"extract"
}
REGEX_METHODS
=
{
"match"
,
"extract"
}
ARGS_METHODS
=
{
"count"
,
"get"
}
ARGS_METHODS
=
{
"count"
,
"get"
}
...
@@ -656,6 +657,9 @@ class DispatchMixin:
...
@@ -656,6 +657,9 @@ class DispatchMixin:
dict_name
=
expr
.
arguments
[
0
]
.
name
dict_name
=
expr
.
arguments
[
0
]
.
name
if
dict_name
in
self
.
dict_vars
:
if
dict_name
in
self
.
dict_vars
:
return
f
'__ct_json_stringify "{dict_name}"'
return
f
'__ct_json_stringify "{dict_name}"'
if
callee
.
object
.
name
==
"json"
and
callee
.
member
==
"get"
:
args
=
[
self
.
generate_expr
(
arg
)
for
arg
in
expr
.
arguments
]
return
f
'__ct_json_get "{args[0]}" "{args[1]}"'
args
=
[
self
.
generate_expr
(
arg
)
for
arg
in
expr
.
arguments
]
args
=
[
self
.
generate_expr
(
arg
)
for
arg
in
expr
.
arguments
]
args_str
=
" "
.
join
([
f
'"{a}"'
for
a
in
args
])
args_str
=
" "
.
join
([
f
'"{a}"'
for
a
in
args
])
...
...
bootstrap/stdlib.py
View file @
daedc86a
...
@@ -330,6 +330,15 @@ class StdlibMixin:
...
@@ -330,6 +330,15 @@ class StdlibMixin:
self
.
emit
(
"}"
)
self
.
emit
(
"}"
)
self
.
emit
()
self
.
emit
()
self
.
emit
(
"__ct_json_get () {"
)
self
.
indent_level
+=
1
self
.
emit
(
'local __json="$1"'
)
self
.
emit
(
'local __path="$2"'
)
self
.
emit
(
'echo "$__json" | jq -r "$__path" 2>/dev/null'
)
self
.
indent_level
-=
1
self
.
emit
(
"}"
)
self
.
emit
()
self
.
emit
(
"__ct_json_stringify () {"
)
self
.
emit
(
"__ct_json_stringify () {"
)
self
.
indent_level
+=
1
self
.
indent_level
+=
1
self
.
emit
(
'local -n __d="$1"'
)
self
.
emit
(
'local -n __d="$1"'
)
...
@@ -454,6 +463,7 @@ class StdlibMixin:
...
@@ -454,6 +463,7 @@ class StdlibMixin:
self
.
emit
(
"__ct_str_upper () { __CT_RET=
\"
${1^^}
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_upper () { __CT_RET=
\"
${1^^}
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_lower () { __CT_RET=
\"
${1,,}
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_lower () { __CT_RET=
\"
${1,,}
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_char_at () { __CT_RET=
\"
${1:$2:1}
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_char_at () { __CT_RET=
\"
${1:$2:1}
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_urlencode () { __CT_RET=$(printf '
%
s'
\"
$1
\"
| jq -sRr @uri); echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_concat () { __CT_RET=
\"
$1$2
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
(
"__ct_str_concat () { __CT_RET=
\"
$1$2
\"
; echo
\"
$__CT_RET
\"
; }"
)
self
.
emit
()
self
.
emit
()
...
...
bootstrap/stmt_codegen.py
View file @
daedc86a
...
@@ -516,6 +516,7 @@ class StmtMixin:
...
@@ -516,6 +516,7 @@ class StmtMixin:
"trim"
:
"__ct_str_trim"
,
"contains"
:
"__ct_str_contains"
,
"starts"
:
"__ct_str_starts"
,
"trim"
:
"__ct_str_trim"
,
"contains"
:
"__ct_str_contains"
,
"starts"
:
"__ct_str_starts"
,
"ends"
:
"__ct_str_ends"
,
"index"
:
"__ct_str_index"
,
"replace"
:
"__ct_str_replace"
,
"ends"
:
"__ct_str_ends"
,
"index"
:
"__ct_str_index"
,
"replace"
:
"__ct_str_replace"
,
"substr"
:
"__ct_str_substr"
,
"split"
:
"__ct_str_split"
,
"charAt"
:
"__ct_str_char_at"
,
"substr"
:
"__ct_str_substr"
,
"split"
:
"__ct_str_split"
,
"charAt"
:
"__ct_str_char_at"
,
"urlencode"
:
"__ct_str_urlencode"
,
}
}
args_str
=
" "
.
join
([
f
'"{a}"'
for
a
in
args
])
args_str
=
" "
.
join
([
f
'"{a}"'
for
a
in
args
])
...
...
examples/telegram_echobot/echobot.ct
0 → 100644
View file @
daedc86a
token = shell.capture ("printenv TELEGRAM_BOT_TOKEN")
if token == "" {
print ("Set TELEGRAM_BOT_TOKEN environment variable")
exit (1)
}
base_url = "https://api.telegram.org/bot{token}"
func get_username () {
response = http.get ("{base_url}/getMe")
username = json.get (response, ".result.username")
return username
}
func get_updates (offset) {
url = "{base_url}/getUpdates?timeout=30&offset={offset}"
response = http.get (url)
return response
}
func send_message (chat_id, text) {
encoded = text.urlencode ()
url = "{base_url}/sendMessage?chat_id={chat_id}&text={encoded}"
http.get (url)
}
username = get_username ()
if username == "null" {
print ("Invalid token")
exit (1)
}
print ("Bot @{username} started")
print ("Waiting for messages...")
offset = "0"
while true {
response = get_updates (offset)
count = json.get (response, ".result | length")
if count != "0" {
i = 0
while i < count {
update_id = json.get (response, ".result[{i}].update_id")
chat_id = json.get (response, ".result[{i}].message.chat.id")
text = json.get (response, ".result[{i}].message.text")
first_name = json.get (response, ".result[{i}].message.from.first_name")
offset = update_id + 1
if text != "null" {
print ("{first_name}: {text}")
send_message (chat_id, text)
}
i = i + 1
}
}
}
tests/test_integration.py
View file @
daedc86a
...
@@ -922,6 +922,87 @@ print(double(-1))
...
@@ -922,6 +922,87 @@ print(double(-1))
assert
code
!=
0
or
"must be"
in
stderr
assert
code
!=
0
or
"must be"
in
stderr
class
TestJsonGet
:
def
test_json_get_simple
(
self
):
code
,
stdout
,
_
=
run_ct
(
r'''
json_str = "\{\"name\": \"Alice\"\}"
result = json.get(json_str, ".name")
print(result)
'''
)
assert
code
==
0
assert
"Alice"
in
stdout
def
test_json_get_nested
(
self
):
code
,
stdout
,
_
=
run_ct
(
r'''
json_str = "\{\"user\": \{\"name\": \"Bob\", \"age\": 25\}\}"
name = json.get(json_str, ".user.name")
age = json.get(json_str, ".user.age")
print(name)
print(age)
'''
)
assert
code
==
0
assert
"Bob"
in
stdout
assert
"25"
in
stdout
def
test_json_get_array
(
self
):
code
,
stdout
,
_
=
run_ct
(
r'''
json_str = "\{\"items\": [1, 2, 3]\}"
first = json.get(json_str, ".items[0]")
print(first)
'''
)
assert
code
==
0
assert
"1"
in
stdout
def
test_json_get_length
(
self
):
code
,
stdout
,
_
=
run_ct
(
r'''
json_str = "\{\"items\": [1, 2, 3, 4, 5]\}"
count = json.get(json_str, ".items | length")
print(count)
'''
)
assert
code
==
0
assert
"5"
in
stdout
class
TestUrlencode
:
def
test_urlencode_simple
(
self
):
code
,
stdout
,
_
=
run_ct
(
'''
text = "hello world"
encoded = text.urlencode()
print(encoded)
'''
)
assert
code
==
0
assert
"hello
%20
world"
in
stdout
def
test_urlencode_special_chars
(
self
):
code
,
stdout
,
_
=
run_ct
(
'''
text = "a=b&c=d"
encoded = text.urlencode()
print(encoded)
'''
)
assert
code
==
0
assert
"
%3
D"
in
stdout
or
"
%3
d"
in
stdout
assert
"
%26
"
in
stdout
def
test_urlencode_cyrillic
(
self
):
code
,
stdout
,
_
=
run_ct
(
'''
text = "привет"
encoded = text.urlencode()
print(encoded)
'''
)
assert
code
==
0
assert
"
%
"
in
stdout
assert
"привет"
not
in
stdout
def
test_urlencode_empty
(
self
):
code
,
stdout
,
_
=
run_ct
(
'''
text = ""
encoded = text.urlencode()
print("result: {encoded}")
'''
)
assert
code
==
0
assert
"result:"
in
stdout
class
TestMethodValidation
:
class
TestMethodValidation
:
def
test_unknown_array_method
(
self
):
def
test_unknown_array_method
(
self
):
code
,
stdout
,
stderr
=
compile_ct_check
(
'''
code
,
stdout
,
stderr
=
compile_ct_check
(
'''
...
@@ -956,6 +1037,7 @@ a = text.upper()
...
@@ -956,6 +1037,7 @@ a = text.upper()
b = text.lower()
b = text.lower()
c = text.len()
c = text.len()
d = text.trim()
d = text.trim()
e = text.urlencode()
'''
)
'''
)
assert
code
==
0
assert
code
==
0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment