fix: apply CodeRabbit nitpick suggestions and improve code quality

- Fix grammar.js TypeScript errors by correcting optional field usage
- Update .yamlignore to use more robust glob pattern (**/node_modules/**)
- Remove hard-coded test count from README.md for maintainability
- Fix shellcheck directive format (add space after #) in all test specs
- Fix typos throughout test specifications:
  - 'can not' → 'cannot'
  - 'expantion' → 'expansion'
  - 'singnal' → 'signal'
  - 'It mean' → 'It means'
- Update CODE_OF_CONDUCT.md HTTP links to HTTPS
- Update tree-sitter parse command to use --scope instead of --language
- Add comments to .mega-linter.yml explaining disabled linters

All grammar tests still pass (61/61) and the parser functions correctly
with the updated tree-sitter CLI v0.25.0.
This commit is contained in:
2025-09-13 03:54:32 +03:00
parent d65c6e6ec4
commit 193f8871b6
32 changed files with 363 additions and 363 deletions

View File

@@ -142,4 +142,4 @@ the [Geek Feminism Anti-Harassment Policy][geek-feminism].
[stumptown]: https://github.com/stumpsyn
[cc-by-sa]: https://creativecommons.org/licenses/by-sa/3.0/
[django]: https://www.djangoproject.com/conduct/
[geek-feminism]: http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy
[geek-feminism]: https://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy

View File

@@ -124,7 +124,7 @@ jobs:
End
EOF
npx tree-sitter parse --language=shellspec test_sample.shellspec --quiet || {
npx tree-sitter parse --scope=source.shellspec test_sample.shellspec --quiet || {
echo "❌ Parser failed on sample ShellSpec code"
exit 1
}

View File

@@ -18,8 +18,8 @@ SHOW_SKIPPED_LINTERS: false # Show skipped linters in MegaLinter log
DISABLE_LINTERS:
- REPOSITORY_DEVSKIM
- JSON_PRETTIER
- SPELL_LYCHEE
- JSON_PRETTIER # Disabled for causing probelms
- SPELL_LYCHEE # Disabled due to too many false positives
YAML_YAMLLINT_CONFIG_FILE: .yamllint.yml
MARKDOWN_MARKDOWNLINT_CONFIG_FILE: .markdownlint.json

View File

@@ -1 +1 @@
node_modules/**
**/node_modules/**

View File

@@ -263,7 +263,7 @@ npm run rebuild # Clean + generate + build
The grammar includes comprehensive test coverage:
- **59 test cases** covering all ShellSpec constructs
- **Comprehensive test cases** covering all ShellSpec constructs
- **Real-world patterns** from official ShellSpec repository
- **Edge cases** and complex nesting scenarios
- **Mixed content** (ShellSpec + bash code)

View File

@@ -103,7 +103,7 @@ module.exports = grammar(bashGrammar, {
"BeforeRun",
"AfterRun",
),
field("label", optional(choice($.string, $.raw_string, $.word))),
optional(field("label", choice($.string, $.raw_string, $.word))),
repeat($._terminated_statement),
"End",
),
@@ -115,7 +115,7 @@ module.exports = grammar(bashGrammar, {
1,
seq(
choice("Parameters", "Skip", "Pending", "Todo"),
field("label", optional(choice($.string, $.raw_string, $.word))),
optional(field("label", choice($.string, $.raw_string, $.word))),
repeat($._terminated_statement),
"End",
),

View File

@@ -7236,12 +7236,12 @@
]
},
{
"type": "FIELD",
"name": "label",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "label",
"content": {
"type": "CHOICE",
"members": [
{
@@ -7257,12 +7257,12 @@
"name": "word"
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT",
@@ -7306,12 +7306,12 @@
]
},
{
"type": "FIELD",
"name": "label",
"content": {
"type": "CHOICE",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "label",
"content": {
"type": "CHOICE",
"members": [
{
@@ -7327,12 +7327,12 @@
"name": "word"
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT",

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
It 'is simple'
When call echo 'ok'

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'this is "example group"'
Context 'this is also "example group"'

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'example example'
It 'is "example"'

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh disable=SC2016
# shellcheck shell=sh disable=SC2016
Describe 'evaluation example'
Describe 'call evaluation'
@@ -21,7 +21,7 @@ Describe 'evaluation example'
It 'must be one call each example'
When call echo 1
When call echo 2 # can not be called more than once.
When call echo 2 # cannot be called more than once.
The output should eq 1
End
@@ -29,9 +29,9 @@ Describe 'evaluation example'
The value 123 should eq 123
End
It 'can not be called after expectation'
It 'cannot be called after expectation'
The value 123 should eq 123
When call echo 1 # can not be called after expectation.
When call echo 1 # cannot be called after expectation.
End
It 'calls external command'
@@ -48,7 +48,7 @@ Describe 'evaluation example'
The status should be failure
End
It 'can not modify variable because it run with in subshell'
It 'cannot modify variable because it run with in subshell'
set_value() { SHELLSPEC_VERSION=$1; }
When run set_value 'no-version'
The value "$SHELLSPEC_VERSION" should not eq 'no-version'

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'expectation example'
It 'is succeeds because expectation is successful'

View File

@@ -1,49 +1,49 @@
#shellcheck shell=sh
# shellcheck shell=sh
# Each block (example group / example) runs within subshell.
# It mean that it works like lexical scope.
# It means that it works like lexical scope.
Describe 'scope example'
foo() { echo "foo"; } # It can call from anywhere within this example group
foo() { echo "foo"; } # It can call from anywhere within this example group
# By the way, you can only use shellspec DSL or define function here.
# Of course it is possible to write freely within the defined function
# but other code may breaks isolation of tests.
# By the way, you can only use shellspec DSL or define function here.
# Of course it is possible to write freely within the defined function
# but other code may breaks isolation of tests.
It 'calls "foo"'
When call foo
The output should eq 'foo'
End
It 'defines "bar" function'
bar() { echo "bar"; }
When call bar
The output should eq 'bar'
End
It 'can not call "bar" function, because different scope'
When call bar
The status should be failure # probably status is 127
The stderr should be present # probably stderr is "bar: not found"
End
It 'redefines "foo" function'
foo() { echo "FOO"; }
When call foo
The output should eq 'FOO'
End
It 'calls "foo" function of outer scope (not previous example)'
When call foo
The output should eq 'foo'
End
Describe 'sub block'
foo() { echo "Foo"; }
It 'calls "foo" function of upper scope'
When call foo
The output should eq 'Foo'
End
End
It 'calls "foo"'
When call foo
The output should eq 'foo'
End
It 'defines "bar" function'
bar() { echo "bar"; }
When call bar
The output should eq 'bar'
End
It 'cannot call "bar" function, because different scope'
When call bar
The status should be failure # probably status is 127
The stderr should be present # probably stderr is "bar: not found"
End
It 'redefines "foo" function'
foo() { echo "FOO"; }
When call foo
The output should eq 'FOO'
End
It 'calls "foo" function of outer scope (not previous example)'
When call foo
The output should eq 'foo'
End
Describe 'sub block'
foo() { echo "Foo"; }
It 'calls "foo" function of upper scope'
When call foo
The output should eq 'Foo'
End
End
End

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
# shellspec has Before and After hook.
# Those hooks are execute for each example (It/Example/Specify).

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
hook() { %logger "$1 $2 ${SHELLSPEC_EXAMPLE_ID}"; }

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'subject example'
Describe 'stdout'

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'modifier example'
data() {

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'matcher example'
Describe 'status matchers'

View File

@@ -1,100 +1,100 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'skip example'
Describe 'calc()'
calc() { echo "$(($*))"; }
Describe 'calc()'
calc() { echo "$(($*))"; }
It 'can add'
When call calc 1 + 1
The output should eq 2
End
It 'can minus'
When call calc 1 - 1
The output should eq 0
End
# Skip examples of after this line in current example group
Skip "decimal point can not be calculated"
It 'can add decimal point'
When call calc 1.1 + 1.1
The output should eq 2.2
End
It 'can minus decimal point'
When call calc 1.1 - 1.1
The output should eq 0
End
Describe 'Multiplication' # example group is also skipped
It 'can multiply decimal point'
When call calc 1.1 '*' 1.1
The output should eq 1.21
End
End
End
Describe 'status_to_singnal()'
status_to_singnal() {
if [ 128 -le "$1" ] && [ "$1" -le 192 ]; then
echo "$(($1 - 128))"
else
# Not implemented: echo "status is out of range" >&2
return 1
fi
}
It 'can not convert status to singnal'
When call status_to_singnal 0
The status should be failure
# Skip expection of after this line in current example
Skip 'outputs error message is not implemented'
The error should be present
End
# This example is going to execute
It 'converts status to singnal'
When call status_to_singnal 137
The output should eq 9
End
End
# "temporary skip" can not hidden with "--skip-message quiet" option
Describe 'temporary skip'
Example 'with Skip helper'
Skip # without reason
When call foo
The status should be success
End
xExample 'with xExample (prepend "x")'
When call foo
The status should be success
End
xDescribe 'with xDescribe (prepend "x")'
Example 'this is also skipped'
When call foo
The status should be success
End
End
End
Describe 'conditional skip'
Example 'skip1'
conditions() { return 0; }
Skip if "function returns success" conditions
When call echo ok
The stdout should eq ok
End
Example 'skip2'
conditions() { echo "skip"; }
Skip if 'function returns "skip"' [ "$(conditions)" = "skip" ]
When call echo ok
The stdout should eq ok
End
End
It 'can add'
When call calc 1 + 1
The output should eq 2
End
It 'can minus'
When call calc 1 - 1
The output should eq 0
End
# Skip examples of after this line in current example group
Skip "decimal point cannot be calculated"
It 'can add decimal point'
When call calc 1.1 + 1.1
The output should eq 2.2
End
It 'can minus decimal point'
When call calc 1.1 - 1.1
The output should eq 0
End
Describe 'Multiplication' # example group is also skipped
It 'can multiply decimal point'
When call calc 1.1 '*' 1.1
The output should eq 1.21
End
End
End
Describe 'status_to_signal()'
status_to_signal() {
if [ 128 -le "$1" ] && [ "$1" -le 192 ]; then
echo "$(($1 - 128))"
else
# Not implemented: echo "status is out of range" >&2
return 1
fi
}
It 'cannot convert status to signal'
When call status_to_signal 0
The status should be failure
# Skip expection of after this line in current example
Skip 'outputs error message is not implemented'
The error should be present
End
# This example is going to execute
It 'converts status to signal'
When call status_to_signal 137
The output should eq 9
End
End
# "temporary skip" cannot hidden with "--skip-message quiet" option
Describe 'temporary skip'
Example 'with Skip helper'
Skip # without reason
When call foo
The status should be success
End
xExample 'with xExample (prepend "x")'
When call foo
The status should be success
End
xDescribe 'with xDescribe (prepend "x")'
Example 'this is also skipped'
When call foo
The status should be success
End
End
End
Describe 'conditional skip'
Example 'skip1'
conditions() { return 0; }
Skip if "function returns success" conditions
When call echo ok
The stdout should eq ok
End
Example 'skip2'
conditions() { echo "skip"; }
Skip if 'function returns "skip"' [ "$(conditions)" = "skip" ]
When call echo ok
The stdout should eq ok
End
End
End

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
# Pending is better than skip in some case. Skip is just only skips,
# but Pending is runs example and decide the success or failure.

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'include helper example'
Describe 'include helper'

View File

@@ -1,85 +1,85 @@
#shellcheck shell=sh disable=SC2016
# shellcheck shell=sh disable=SC2016
# Data helper is easy way to input data from stdin for evaluation.
# Removes `#|` from the beginning of the each line in the Data helper,
# the rest is the input data.
Describe 'Data helper'
Example 'provide with Data helper block style'
Data
#|item1 123
#|item2 456
#|item3 789
End
When call awk '{total+=$2} END{print total}'
The output should eq 1368
End
Example 'provide string with Data helper'
Data '123 + 456 + 789'
When call bc
The output should eq 1368
End
Example 'provide from function with Data helper'
data() {
echo item1 123
echo item2 456
echo item3 789
}
Data data
When call awk '{total+=$2} END{print total}'
The output should eq 1368
End
Describe 'Data helper with filter'
Example 'from block'
Data | tr 'abc' 'ABC'
#|aaa
#|bbb
End
When call cat -
The first line of output should eq 'AAA'
The second line of output should eq 'BBB'
End
Example 'from function'
foo() { printf '%s\n' "$@"; }
Data foo a b c | tr 'abc' 'ABC' # comment
When call cat -
The first line of output should eq 'A'
The second line of output should eq 'B'
The third line of output should eq "C"
The lines of entire output should eq 3
End
Example 'from string'
Data 'abc'| tr 'abc' 'ABC' # comment
When call cat -
The output should eq ABC
End
End
Describe 'variable expansion'
Before 'item=123'
Example 'not expand variable (default)'
Data:raw
#|item $item
End
When call cat -
The output should eq 'item $item'
End
Example 'expand variable'
Data:expand
#|item $item
End
When call cat -
The output should eq 'item 123'
End
# variable expansion is supported by block style only.
End
Example 'provide with Data helper block style'
Data
#|item1 123
#|item2 456
#|item3 789
End
When call awk '{total+=$2} END{print total}'
The output should eq 1368
End
Example 'provide string with Data helper'
Data '123 + 456 + 789'
When call bc
The output should eq 1368
End
Example 'provide from function with Data helper'
data() {
echo item1 123
echo item2 456
echo item3 789
}
Data data
When call awk '{total+=$2} END{print total}'
The output should eq 1368
End
Describe 'Data helper with filter'
Example 'from block'
Data | tr 'abc' 'ABC'
#|aaa
#|bbb
End
When call cat -
The first line of output should eq 'AAA'
The second line of output should eq 'BBB'
End
Example 'from function'
foo() { printf '%s\n' "$@"; }
Data foo a b c | tr 'abc' 'ABC' # comment
When call cat -
The first line of output should eq 'A'
The second line of output should eq 'B'
The third line of output should eq "C"
The lines of entire output should eq 3
End
Example 'from string'
Data 'abc' | tr 'abc' 'ABC' # comment
When call cat -
The output should eq ABC
End
End
Describe 'variable expansion'
Before 'item=123'
Example 'not expand variable (default)'
Data:raw
#|item $item
End
When call cat -
The output should eq 'item $item'
End
Example 'expand variable'
Data:expand
#|item $item
End
When call cat -
The output should eq 'item 123'
End
# variable expansion is supported by block style only.
End
End

View File

@@ -1,93 +1,93 @@
#shellcheck shell=sh disable=SC2016
# shellcheck shell=sh disable=SC2016
# %text directive is easy way to output text like here document.
# Removes `#|` from the beginning of the each line in the %text directive,
# the rest is the output text.
Describe '%text directive'
It 'outputs texts'
output() {
echo "start" # you can write code here
%text
#|aaa
#|bbb
#|ccc
echo "end" # you can write code here
}
When call output
The line 1 of output should eq 'start'
The line 2 of output should eq 'aaa'
The line 3 of output should eq 'bbb'
The line 4 of output should eq "ccc"
The line 5 of output should eq 'end'
End
It 'sets to variable'
output() {
texts=$(
%text
#|aaa
#|bbb
#|ccc
)
echo "$texts"
}
When call output
The line 1 of output should eq 'aaa'
The line 2 of output should eq 'bbb'
The line 3 of output should eq "ccc"
End
It 'outputs texts with filter'
output() {
%text | tr 'a-z_' 'A-Z_'
#|abc
}
When call output
The output should eq 'ABC'
End
Describe 'variable expantion'
Before 'text=abc'
Example 'not expand variable (default)'
output() {
%text:raw
#|$text
}
When call output
The output should eq '$text'
End
Example 'expand variable'
output() {
%text:expand
#|$text
}
When call output
The output should eq 'abc'
End
End
It 'outputs texts with more complex code'
output() {
if true; then
set -- 1 2 3 4 5
while [ $# -gt 0 ]; do
%text:expand | tr 'a-z_' 'A-Z_'
#|value $(($1 * 10))
shift
done
else
%text
#|text
fi
}
When call output
The line 1 of output should eq 'VALUE 10'
The line 2 of output should eq 'VALUE 20'
The line 3 of output should eq 'VALUE 30'
The line 4 of output should eq "VALUE 40"
The line 5 of output should eq 'VALUE 50'
End
It 'outputs texts'
output() {
echo "start" # you can write code here
%text
#|aaa
#|bbb
#|ccc
echo "end" # you can write code here
}
When call output
The line 1 of output should eq 'start'
The line 2 of output should eq 'aaa'
The line 3 of output should eq 'bbb'
The line 4 of output should eq "ccc"
The line 5 of output should eq 'end'
End
It 'sets to variable'
output() {
texts=$(
%text
#|aaa
#|bbb
#|ccc
)
echo "$texts"
}
When call output
The line 1 of output should eq 'aaa'
The line 2 of output should eq 'bbb'
The line 3 of output should eq "ccc"
End
It 'outputs texts with filter'
output() {
%text | tr 'a-z_' 'A-Z_'
#|abc
}
When call output
The output should eq 'ABC'
End
Describe 'variable expansion'
Before 'text=abc'
Example 'not expand variable (default)'
output() {
%text:raw
#|$text
}
When call output
The output should eq '$text'
End
Example 'expand variable'
output() {
%text:expand
#|$text
}
When call output
The output should eq 'abc'
End
End
It 'outputs texts with more complex code'
output() {
if true; then
set -- 1 2 3 4 5
while [ $# -gt 0 ]; do
%text:expand | tr 'a-z_' 'A-Z_'
#|value $(($1 * 10))
shift
done
else
%text
#|text
fi
}
When call output
The line 1 of output should eq 'VALUE 10'
The line 2 of output should eq 'VALUE 20'
The line 3 of output should eq 'VALUE 30'
The line 4 of output should eq "VALUE 40"
The line 5 of output should eq 'VALUE 50'
End
End

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe '%putsn directive'
Example 'outputs arguments'

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
%const NAME: value
# shellcheck disable=SC2288
@@ -7,11 +7,11 @@
# %const (% is short hand) directive is define constant value.
# The characters that can be used for variable name is upper capital, number
# and underscore only. It can not be define inside of the example group or
# and underscore only. It cannot be define inside of the example group or
# the example.
#
# The timing of evaluation of the value is the specfile translation process.
# So you can access shellspec variables, but you can not access variable or
# So you can access shellspec variables, but you cannot access variable or
# function in the specfile.
#
# This feature assumed use with conditional skip. The conditional skip may runs

View File

@@ -1,8 +1,8 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'Logger helper'
%logger 'this is log'
Example 'outputs log'
%logger 'this is log'
End
%logger 'this is log'
Example 'outputs log'
%logger 'this is log'
End
End

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'mock stub example'
unixtime() { date +%s; }

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
Describe 'intercept example'
Intercept begin

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
# Sometime, functions are defined in a single shell script.
# You will want to test it. but you do not want to run the script.

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
# regexp custom matcher is defined in "support/custom_matcher.sh" and
# imported by "spec_helper.sh"

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
# set -eu

View File

@@ -1,4 +1,4 @@
#shellcheck shell=sh
# shellcheck shell=sh
# imported by "spec_helper.sh"