Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ tests/test_nested_cmd
tests/test_help
tests/test_argument
tests/test_parsecmdarg
tests/test_case_opt
13 changes: 11 additions & 2 deletions confutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func helpOptDesc(appInfo: HelpAppInfo): string =

func isCliSwitch(opt: OptInfo): bool =
opt.kind == CliSwitch or
(opt.kind == Discriminator and opt.isCommand == false)
(opt.kind == Discriminator and not opt.isCommand)

func isOpt(opt: OptInfo, excl: set[OptFlag]): bool =
opt.isCliSwitch and excl * opt.flags == {}
Expand Down Expand Up @@ -1280,6 +1280,8 @@ proc loadImpl[C, SecondarySources](
processHelpAndVersionOptions(key, val)

var opt = findOpt(activeCmds, key)
#for x in activeCmds:
# debugEcho repr x
if opt == nil:
# We didn't find the option.
# Check if it's from the default command and activate it if necessary:
Expand All @@ -1294,7 +1296,14 @@ proc loadImpl[C, SecondarySources](
discard

if opt != nil:
result.applySetter(opt.idx, val)
if opt.kind == Discriminator and not opt.isCommand:
let subCmd = findCmd(opt.subCmds, val)
if subCmd == nil:
fail "Unrecognized value '" & val & "'" & " for option '" & key & "'"
result.applySetter(opt.idx, if subCmd.desc.len > 0: subCmd.desc else: subCmd.name)
activeCmds.add subCmd
else:
result.applySetter(opt.idx, val)
elif not ignoreUnknown:
fail "Unrecognized option '" & key & "'"

Expand Down
1 change: 1 addition & 0 deletions tests/test_all.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import
test_argument,
test_case_opt,
test_config_file,
test_dispatch,
test_duplicates,
Expand Down
162 changes: 162 additions & 0 deletions tests/test_case_opt.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# confutils
# Copyright (c) 2018-2026 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.

import unittest2, ../confutils

#type
# StartupCommand* = enum
# noCommand
# cmdSlotProcessing
# cmdBlockProcessing
#
# BlockProcessingCat* = enum
# catBlockHeader
# catAttestations
# catDeposits
#
# ScenarioConf* = object
# preState* {.
# desc: "The name of your pre-state (without .ssz)"
# name: "pre"
# abbr: "p"
# defaultValue: "pre".}: string
# case cmd*{.
# command
# defaultValue: noCommand }: StartupCommand
# of noCommand:
# discard
# of cmdSlotProcessing:
# numSlots* {.
# desc: "The number of slots the pre-state will be advanced by"
# name: "num-slots"
# abbr: "s"
# defaultValue: 1.}: uint64
# of cmdBlockProcessing:
# case blockProcessingCat* {.
# desc: "block transitions"
# #name: "process-blocks" # Comment this to make it work
# implicitlySelectable
# required .}: BlockProcessingCat
# of catBlockHeader:
# discard
# of catAttestations:
# attestation*{.
# desc: "Attestation filename (without .ssz)"
# name: "attestation"
# defaultValue: "attestation default".}: string
# of catDeposits:
# discard
#
#suite "test case option":
# test "no command":
# let conf = ScenarioConf.load(cmdLine = @[])
# check:
# conf.cmd == StartupCommand.noCommand
# conf.preState == "pre"
#
# test "case option has default value":
# let conf = ScenarioConf.load(cmdLine = @[
# "cmdBlockProcessing",
# "--blockProcessingCat=catAttestations",
# "--attestation=attestation"
# ])
# check:
# conf.cmd == StartupCommand.cmdBlockProcessing
# conf.blockProcessingCat == BlockProcessingCat.catAttestations
# conf.attestation == "attestation"

type
StartupCommand* = enum
noCommand
cmdSlotProcessing
cmdBlockProcessing

BlockProcessingCat* = enum
catBlockHeader
catAttestations
catDeposits

TestConf = object
preState {.
desc: "The name of your pre-state (without .ssz)"
name: "pre"
abbr: "p"
defaultValue: "pre".}: string
case blockProcessingCat {.
desc: "block transitions"
#name: "process-blocks" # Comment this to make it work
implicitlySelectable
required .}: BlockProcessingCat
of catBlockHeader:
discard
of catAttestations:
attestation{.
desc: "Attestation filename (without .ssz)"
name: "attestation"
defaultValue: "attestation default".}: string
of catDeposits:
discard

case block2 {.
desc: "block transitions"
#name: "process-blocks" # Comment this to make it work
implicitlySelectable
required .}: StartupCommand
of noCommand:
discard
of cmdSlotProcessing:
attestation2 {.
desc: "Attestation filename (without .ssz)"
name: "attestation2"
defaultValue: "attestation default".}: string
of cmdBlockProcessing:
discard

suite "test case option":
# test "case option has default value":
# let conf = TestConf.load(cmdLine = @[
# "--blockProcessingCat=catAttestations",
# #"--attestation=attestation"
# ])
# check:
# conf.blockProcessingCat == BlockProcessingCat.catAttestations
# conf.attestation == "attestation default"
#
# test "case option set value":
# let conf = TestConf.load(cmdLine = @[
# "--blockProcessingCat=catAttestations",
# "--attestation=foobar"
# ])
# check:
# conf.blockProcessingCat == BlockProcessingCat.catAttestations
# conf.attestation == "foobar"
#
# test "case option set value":
# let conf = TestConf.load(cmdLine = @[
# "--blockProcessingCat=catAttestations",
# "--attestation=foobar",
# "--pre=foo"
# ])
# check:
# conf.blockProcessingCat == BlockProcessingCat.catAttestations
# conf.attestation == "foobar"
# conf.preState == "foo"

test "case option set value":
let conf = TestConf.load(cmdLine = @[
"--blockProcessingCat=catAttestations",
"--attestation=foobar",
"--block2=cmdSlotProcessing",
"--attestation2=bar"
])
check:
conf.blockProcessingCat == BlockProcessingCat.catAttestations
conf.block2 == StartupCommand.cmdSlotProcessing
conf.attestation == "foobar"
conf.attestation2 == "bar"