mirror of
https://github.com/dw-0/kiauh.git
synced 2025-12-27 17:53:35 +05:00
Squashed 'kiauh/core/submodules/simple_config_parser/' content from commit 90081a6
git-subtree-dir: kiauh/core/submodules/simple_config_parser git-subtree-split: 90081a6539ec38adf6a1a5bb707a0e9934567c7f
This commit is contained in:
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
1337
tests/assets/klipper_config.txt
Normal file
1337
tests/assets/klipper_config.txt
Normal file
File diff suppressed because it is too large
Load Diff
32
tests/assets/test_config_1.cfg
Normal file
32
tests/assets/test_config_1.cfg
Normal file
@@ -0,0 +1,32 @@
|
||||
# a comment at the very top
|
||||
# should be treated as the file header
|
||||
|
||||
# up to the first section, including all blank lines
|
||||
|
||||
[section_1]
|
||||
option_1: value_1
|
||||
option_1_1: True # this is a boolean
|
||||
option_1_2: 5 ; this is an integer
|
||||
option_1_3: 1.123 #;this is a float
|
||||
|
||||
[section_2] ; comment
|
||||
option_2: value_2
|
||||
|
||||
; comment
|
||||
|
||||
[section_3]
|
||||
option_3: value_3 # comment
|
||||
|
||||
[section_4]
|
||||
# comment
|
||||
option_4: value_4
|
||||
|
||||
[section number 5]
|
||||
#option_5: value_5
|
||||
option_5 = this.is.value-5
|
||||
multi_option:
|
||||
# these are multi-line values
|
||||
value_5_1
|
||||
value_5_2 ; here is a comment
|
||||
value_5_3
|
||||
option_5_1: value_5_1
|
||||
33
tests/assets/test_config_2.cfg
Normal file
33
tests/assets/test_config_2.cfg
Normal file
@@ -0,0 +1,33 @@
|
||||
# a comment at the very top
|
||||
# should be treated as the file header
|
||||
|
||||
# up to the first section, including all blank lines
|
||||
|
||||
[section_1]
|
||||
option_1: value_1
|
||||
option_1_1: True # this is a boolean
|
||||
option_1_2: 5 ; this is an integer
|
||||
option_1_3: 1.123 #;this is a float
|
||||
|
||||
[section_2] ; comment
|
||||
option_2: value_2
|
||||
|
||||
; comment
|
||||
|
||||
[section_3]
|
||||
option_3: value_3 # comment
|
||||
|
||||
[section_4]
|
||||
# comment
|
||||
option_4: value_4
|
||||
|
||||
[section number 5]
|
||||
#option_5: value_5
|
||||
option_5 = this.is.value-5
|
||||
multi_option:
|
||||
# these are multi-line values
|
||||
value_5_1
|
||||
value_5_2 ; here is a comment
|
||||
value_5_3
|
||||
option_5_1: value_5_1
|
||||
# config ending with a comment
|
||||
94
tests/assets/test_config_3.cfg
Normal file
94
tests/assets/test_config_3.cfg
Normal file
@@ -0,0 +1,94 @@
|
||||
# a comment at the very top
|
||||
# should be treated as the file header
|
||||
|
||||
# up to the first section, including all blank lines
|
||||
|
||||
[section_1]
|
||||
option_1: value_1
|
||||
option_1_1: True # this is a boolean
|
||||
option_1_2: 5 ; this is an integer
|
||||
option_1_3: 1.123 #;this is a float
|
||||
|
||||
[section_2] ; comment
|
||||
option_2: value_2
|
||||
|
||||
; comment
|
||||
|
||||
[section_3]
|
||||
option_3: value_3 # comment
|
||||
|
||||
[section_4]
|
||||
# comment
|
||||
option_4: value_4
|
||||
|
||||
[section number 5]
|
||||
#option_5: value_5
|
||||
option_5 = this.is.value-5
|
||||
multi_option:
|
||||
# these are multi-line values
|
||||
value_5_1
|
||||
value_5_2 ; here is a comment
|
||||
value_5_3
|
||||
option_5_1: value_5_1
|
||||
|
||||
[gcode_macro M117]
|
||||
rename_existing: M117.1
|
||||
gcode:
|
||||
{% if rawparams %}
|
||||
{% set escaped_msg = rawparams.split(';', 1)[0].split('\x23', 1)[0]|replace('"', '\\"') %}
|
||||
SET_DISPLAY_TEXT MSG="{escaped_msg}"
|
||||
RESPOND TYPE=command MSG="{escaped_msg}"
|
||||
{% else %}
|
||||
SET_DISPLAY_TEXT
|
||||
{% endif %}
|
||||
|
||||
# SDCard 'looping' (aka Marlin M808 commands) support
|
||||
#
|
||||
# Support SDCard looping
|
||||
[sdcard_loop]
|
||||
[gcode_macro M486]
|
||||
gcode:
|
||||
# Parameters known to M486 are as follows:
|
||||
# [C<flag>] Cancel the current object
|
||||
# [P<index>] Cancel the object with the given index
|
||||
# [S<index>] Set the index of the current object.
|
||||
# If the object with the given index has been canceled, this will cause
|
||||
# the firmware to skip to the next object. The value -1 is used to
|
||||
# indicate something that isn’t an object and shouldn’t be skipped.
|
||||
# [T<count>] Reset the state and set the number of objects
|
||||
# [U<index>] Un-cancel the object with the given index. This command will be
|
||||
# ignored if the object has already been skipped
|
||||
|
||||
{% if 'exclude_object' not in printer %}
|
||||
{action_raise_error("[exclude_object] is not enabled")}
|
||||
{% endif %}
|
||||
|
||||
{% if 'T' in params %}
|
||||
EXCLUDE_OBJECT RESET=1
|
||||
|
||||
{% for i in range(params.T | int) %}
|
||||
EXCLUDE_OBJECT_DEFINE NAME={i}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'C' in params %}
|
||||
EXCLUDE_OBJECT CURRENT=1
|
||||
{% endif %}
|
||||
|
||||
{% if 'P' in params %}
|
||||
EXCLUDE_OBJECT NAME={params.P}
|
||||
{% endif %}
|
||||
|
||||
{% if 'S' in params %}
|
||||
{% if params.S == '-1' %}
|
||||
{% if printer.exclude_object.current_object %}
|
||||
EXCLUDE_OBJECT_END NAME={printer.exclude_object.current_object}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
EXCLUDE_OBJECT_START NAME={params.S}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'U' in params %}
|
||||
EXCLUDE_OBJECT RESET=1 NAME={params.U}
|
||||
{% endif %}
|
||||
0
tests/line_matching/__init__.py
Normal file
0
tests/line_matching/__init__.py
Normal file
0
tests/line_matching/match_empty_line/__init__.py
Normal file
0
tests/line_matching/match_empty_line/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
not_empty
|
||||
[also_not_empty]
|
||||
#
|
||||
;
|
||||
;
|
||||
#
|
||||
option: value
|
||||
@@ -0,0 +1,39 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.joinpath("test_data")
|
||||
MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("matching_data.txt")
|
||||
NON_MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("non_matching_data.txt")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
return SimpleConfigParser()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(MATCHING_TEST_DATA_PATH))
|
||||
def test_match_line_comment(parser, line):
|
||||
"""Test that a line matches the definition of a line comment"""
|
||||
assert (
|
||||
parser._match_empty_line(line) is True
|
||||
), f"Expected line '{line}' to match line comment definition!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(NON_MATCHING_TEST_DATA_PATH))
|
||||
def test_non_matching_line_comment(parser, line):
|
||||
"""Test that a line does not match the definition of a line comment"""
|
||||
assert (
|
||||
parser._match_empty_line(line) is False
|
||||
), f"Expected line '{line}' to not match line comment definition!"
|
||||
0
tests/line_matching/match_line_comment/__init__.py
Normal file
0
tests/line_matching/match_line_comment/__init__.py
Normal file
@@ -0,0 +1,28 @@
|
||||
;[example_section]
|
||||
#[example_section]
|
||||
# [example_section]
|
||||
; [example_section]
|
||||
;[gcode_macro CANCEL_PRINT]
|
||||
#[gcode_macro CANCEL_PRINT]
|
||||
# [gcode_macro CANCEL_PRINT]
|
||||
; [gcode_macro CANCEL_PRINT]
|
||||
;[gcode_macro SET_PAUSE_NEXT_LAYER]
|
||||
#[gcode_macro SET_PAUSE_NEXT_LAYER]
|
||||
# [gcode_macro SET_PAUSE_NEXT_LAYER]
|
||||
; [gcode_macro SET_PAUSE_NEXT_LAYER]
|
||||
;[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
#[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
# [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
; [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
;[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
#[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
# [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
; [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
;[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
#[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
# [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
; [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
;[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
#[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
# [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
; [gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
@@ -0,0 +1,5 @@
|
||||
not_a_comment: nono
|
||||
|
||||
[also not a comment]
|
||||
not_a_comment: ; comment
|
||||
not_a_comment: # comment
|
||||
@@ -0,0 +1,39 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.joinpath("test_data")
|
||||
MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("matching_data.txt")
|
||||
NON_MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("non_matching_data.txt")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
return SimpleConfigParser()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(MATCHING_TEST_DATA_PATH))
|
||||
def test_match_line_comment(parser, line):
|
||||
"""Test that a line matches the definition of a line comment"""
|
||||
assert (
|
||||
parser._match_line_comment(line) is True
|
||||
), f"Expected line '{line}' to match line comment definition!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(NON_MATCHING_TEST_DATA_PATH))
|
||||
def test_non_matching_line_comment(parser, line):
|
||||
"""Test that a line does not match the definition of a line comment"""
|
||||
assert (
|
||||
parser._match_line_comment(line) is False
|
||||
), f"Expected line '{line}' to not match line comment definition!"
|
||||
0
tests/line_matching/match_option/__init__.py
Normal file
0
tests/line_matching/match_option/__init__.py
Normal file
461
tests/line_matching/match_option/test_data/matching_data.txt
Normal file
461
tests/line_matching/match_option/test_data/matching_data.txt
Normal file
@@ -0,0 +1,461 @@
|
||||
baud: 250000
|
||||
minimum_cruise_ratio: 0.5
|
||||
square_corner_velocity: 5.0
|
||||
full_steps_per_rotation: 200
|
||||
position_min: 0
|
||||
homing_speed: 5.0
|
||||
homing_retract_dist: 5.0
|
||||
kinematics: cartesian
|
||||
kinematics: delta
|
||||
minimum_z_position: 0
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
kinematics: deltesian
|
||||
minimum_z_position: 0
|
||||
min_angle: 5
|
||||
slow_ratio: 3
|
||||
kinematics: corexy
|
||||
kinematics: corexz
|
||||
kinematics: hybrid_corexy
|
||||
kinematics: hybrid_corexz
|
||||
kinematics: polar
|
||||
kinematics: rotary_delta
|
||||
minimum_z_position: 0
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
kinematics: winch
|
||||
kinematics: none
|
||||
max_velocity: 1
|
||||
max_accel: 1
|
||||
instantaneous_corner_velocity: 1.000
|
||||
max_extrude_only_distance: 50.0
|
||||
pressure_advance: 0.0
|
||||
pressure_advance_smooth_time: 0.040
|
||||
max_power: 1.0
|
||||
pullup_resistor: 4700
|
||||
smooth_time: 1.0
|
||||
max_delta: 2.0
|
||||
pwm_cycle_time: 0.100
|
||||
min_extrude_temp: 170
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
probe_count: 3, 3
|
||||
round_probe_count: 5
|
||||
fade_start: 1.0
|
||||
fade_end: 0.0
|
||||
split_delta_z: .025
|
||||
move_check_distance: 5.0
|
||||
mesh_pps: 2, 2
|
||||
algorithm: lagrange
|
||||
bicubic_tension: .2
|
||||
x_adjust: 0
|
||||
y_adjust: 0
|
||||
z_adjust: 0
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
horizontal_move_z: 5
|
||||
probe_height: 0
|
||||
speed: 50
|
||||
probe_speed: 5
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
screw_thread: CW-M3
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
retries: 0
|
||||
retry_tolerance: 0
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
max_adjust: 4
|
||||
retries: 0
|
||||
retry_tolerance: 0
|
||||
speed: 50.0
|
||||
z_hop_speed: 15.0
|
||||
move_to_previous: False
|
||||
axes: xyz
|
||||
endstop_align_zero: False
|
||||
description: G-Code macro
|
||||
initial_duration: 0.0
|
||||
timeout: 600
|
||||
enable_force_move: False
|
||||
recover_velocity: 50.
|
||||
retract_length: 0
|
||||
retract_speed: 20
|
||||
unretract_extra_length: 0
|
||||
unretract_speed: 10
|
||||
resolution: 1.0
|
||||
default_type: echo
|
||||
default_prefix: echo:
|
||||
shaper_freq_x: 0
|
||||
shaper_freq_y: 0
|
||||
shaper_type: mzv
|
||||
damping_ratio_x: 0.1
|
||||
damping_ratio_y: 0.1
|
||||
spi_speed: 5000000
|
||||
axes_map: x, y, z
|
||||
rate: 3200
|
||||
spi_speed: 5000000
|
||||
axes_map: x, y, z
|
||||
i2c_speed: 400000
|
||||
axes_map: x, y, z
|
||||
min_freq: 5
|
||||
max_freq: 133.33
|
||||
accel_per_hz: 75
|
||||
hz_per_sec: 1
|
||||
mcu: mcu
|
||||
deactivate_on_each_sample: True
|
||||
x_offset: 0.0
|
||||
y_offset: 0.0
|
||||
speed: 5.0
|
||||
samples: 1
|
||||
sampleretract_dist: 2.0
|
||||
samples_result: average
|
||||
samples_tolerance: 0.100
|
||||
samples_toleranceretries: 0
|
||||
pin_move_time: 0.680
|
||||
stow_on_each_sample: True
|
||||
probe_with_touch_mode: False
|
||||
pin_up_reports_not_triggered: True
|
||||
pin_up_touch_modereports_triggered: True
|
||||
recovery_time: 0.4
|
||||
sensor_type: ldc1612
|
||||
speed: 50
|
||||
horizontal_move_z: 5
|
||||
calibrate_start_x: 20
|
||||
calibrate_end_x: 200
|
||||
calibrate_y: 112.5
|
||||
max_error: 120
|
||||
hysteresis: 5
|
||||
heating_gain: 2
|
||||
extruder_heating_z: 50.
|
||||
max_validation_temp: 60.
|
||||
pullup_resistor: 4700
|
||||
inlineresistor: 0
|
||||
adc_voltage: 5.0
|
||||
voltage_offset: 0
|
||||
sensor_type: PT1000
|
||||
pullup_resistor: 4700
|
||||
spi_speed: 4000000
|
||||
tc_type: K
|
||||
tc_use_50Hz_filter: False
|
||||
tc_averaging_count: 1
|
||||
rtd_nominal_r: 100
|
||||
rtd_referencer: 430
|
||||
rtd_num_of_wires: 2
|
||||
rtd_use_50Hz_filter: False
|
||||
sensor_type: BME280
|
||||
sensor_type: AHT10
|
||||
sensor_type: temperature_mcu
|
||||
sensor_mcu: mcu
|
||||
sensor_type: temperature_host
|
||||
sensor_type: DS18B20
|
||||
sensor_type: temperature_combined
|
||||
max_power: 1.0
|
||||
shutdown_speed: 0
|
||||
cycle_time: 0.010
|
||||
hardware_pwm: False
|
||||
kick_start_time: 0.100
|
||||
off_below: 0.0
|
||||
tachometer_ppr: 2
|
||||
tachometer_poll_interval: 0.0015
|
||||
heater: extruder
|
||||
heater_temp: 50.0
|
||||
fan_speed: 1.0
|
||||
fan_speed: 1.0
|
||||
pid_deriv_time: 2.0
|
||||
target_temp: 40.0
|
||||
max_speed: 1.0
|
||||
min_speed: 0.3
|
||||
cycle_time: 0.010
|
||||
hardware_pwm: False
|
||||
initial_RED: 0.0
|
||||
initial_GREEN: 0.0
|
||||
initial_BLUE: 0.0
|
||||
initial_WHITE: 0.0
|
||||
color_order: GRB
|
||||
initial_RED: 0.0
|
||||
initial_GREEN: 0.0
|
||||
initial_BLUE: 0.0
|
||||
initial_WHITE: 0.0
|
||||
initial_RED: 0.0
|
||||
initial_GREEN: 0.0
|
||||
initial_BLUE: 0.0
|
||||
i2c_address: 98
|
||||
initial_RED: 0.0
|
||||
initial_GREEN: 0.0
|
||||
initial_BLUE: 0.0
|
||||
initial_WHITE: 0.0
|
||||
i2c_address: 98
|
||||
color_order: RGBW
|
||||
initial_RED: 0.0
|
||||
initial_GREEN: 0.0
|
||||
initial_BLUE: 0.0
|
||||
initial_WHITE: 0.0
|
||||
maximum_servo_angle: 180
|
||||
minimum_pulse_width: 0.001
|
||||
maximum_pulse_width: 0.002
|
||||
pwm: False
|
||||
cycle_time: 0.100
|
||||
hardware_pwm: False
|
||||
cycle_time: 0.100
|
||||
hardware_pwm: False
|
||||
cycle_time: 0.100
|
||||
interpolate: True
|
||||
senseresistor: 0.110
|
||||
stealthchop_threshold: 0
|
||||
driver_MSLUT0: 2863314260
|
||||
driver_MSLUT1: 1251300522
|
||||
driver_MSLUT2: 608774441
|
||||
driver_MSLUT3: 269500962
|
||||
driver_MSLUT4: 4227858431
|
||||
driver_MSLUT5: 3048961917
|
||||
driver_MSLUT6: 1227445590
|
||||
driver_MSLUT7: 4211234
|
||||
driver_W0: 2
|
||||
driver_W1: 1
|
||||
driver_W2: 1
|
||||
driver_W3: 1
|
||||
driver_X1: 128
|
||||
driver_X2: 255
|
||||
driver_X3: 255
|
||||
driver_START_SIN: 0
|
||||
driver_START_SIN90: 247
|
||||
driver_IHOLDDELAY: 8
|
||||
driver_TPOWERDOWN: 0
|
||||
driver_TBL: 1
|
||||
driver_TOFF: 4
|
||||
driver_HEND: 7
|
||||
driver_HSTRT: 0
|
||||
driver_VHIGHFS: 0
|
||||
driver_VHIGHCHM: 0
|
||||
driver_PWM_AUTOSCALE: True
|
||||
driver_PWM_FREQ: 1
|
||||
driver_PWM_GRAD: 4
|
||||
driver_PWM_AMPL: 128
|
||||
driver_SGT: 0
|
||||
driver_SEMIN: 0
|
||||
driver_SEUP: 0
|
||||
driver_SEMAX: 0
|
||||
driver_SEDN: 0
|
||||
driver_SEIMIN: 0
|
||||
driver_SFILT: 0
|
||||
interpolate: True
|
||||
sense_resistor: 0.110
|
||||
stealthchop_threshold: 0
|
||||
driver_MULTISTEP_FILT: True
|
||||
driver_IHOLDDELAY: 8
|
||||
driver_TPOWERDOWN: 20
|
||||
driver_TBL: 2
|
||||
driver_TOFF: 3
|
||||
driver_HEND: 0
|
||||
driver_HSTRT: 5
|
||||
driver_PWM_AUTOGRAD: True
|
||||
driver_PWM_AUTOSCALE: True
|
||||
driver_PWM_LIM: 12
|
||||
driver_PWM_REG: 8
|
||||
driver_PWM_FREQ: 1
|
||||
driver_PWM_GRAD: 14
|
||||
driver_PWM_OFS: 36
|
||||
interpolate: True
|
||||
sense_resistor: 0.110
|
||||
stealthchop_threshold: 0
|
||||
driver_MULTISTEP_FILT: True
|
||||
driver_IHOLDDELAY: 8
|
||||
driver_TPOWERDOWN: 20
|
||||
driver_TBL: 2
|
||||
driver_TOFF: 3
|
||||
driver_HEND: 0
|
||||
driver_HSTRT: 5
|
||||
driver_PWM_AUTOGRAD: True
|
||||
driver_PWM_AUTOSCALE: True
|
||||
driver_PWM_LIM: 12
|
||||
driver_PWM_REG: 8
|
||||
driver_PWM_FREQ: 1
|
||||
driver_PWM_GRAD: 14
|
||||
driver_PWM_OFS: 36
|
||||
driver_SGTHRS: 0
|
||||
driver_SEMIN: 0
|
||||
driver_SEUP: 0
|
||||
driver_SEMAX: 0
|
||||
driver_SEDN: 0
|
||||
driver_SEIMIN: 0
|
||||
spi_speed: 4000000
|
||||
interpolate: True
|
||||
idle_current_percent: 100
|
||||
driver_TBL: 2
|
||||
driver_RNDTF: 0
|
||||
driver_HDEC: 0
|
||||
driver_CHM: 0
|
||||
driver_HEND: 3
|
||||
driver_HSTRT: 3
|
||||
driver_TOFF: 4
|
||||
driver_SEIMIN: 0
|
||||
driver_SEDN: 0
|
||||
driver_SEMAX: 0
|
||||
driver_SEUP: 0
|
||||
driver_SEMIN: 0
|
||||
driver_SFILT: 0
|
||||
driver_SGT: 0
|
||||
driver_SLPH: 0
|
||||
driver_SLPL: 0
|
||||
driver_DISS2G: 0
|
||||
driver_TS2G: 3
|
||||
interpolate: True
|
||||
rref: 12000
|
||||
stealthchop_threshold: 0
|
||||
driver_MSLUT0: 2863314260
|
||||
driver_MSLUT1: 1251300522
|
||||
driver_MSLUT2: 608774441
|
||||
driver_MSLUT3: 269500962
|
||||
driver_MSLUT4: 4227858431
|
||||
driver_MSLUT5: 3048961917
|
||||
driver_MSLUT6: 1227445590
|
||||
driver_MSLUT7: 4211234
|
||||
driver_W0: 2
|
||||
driver_W1: 1
|
||||
driver_W2: 1
|
||||
driver_W3: 1
|
||||
driver_X1: 128
|
||||
driver_X2: 255
|
||||
driver_X3: 255
|
||||
driver_START_SIN: 0
|
||||
driver_START_SIN90: 247
|
||||
driver_OFFSET_SIN90: 0
|
||||
driver_MULTISTEP_FILT: True
|
||||
driver_IHOLDDELAY: 6
|
||||
driver_IRUNDELAY: 4
|
||||
driver_TPOWERDOWN: 10
|
||||
driver_TBL: 2
|
||||
driver_TOFF: 3
|
||||
driver_HEND: 2
|
||||
driver_HSTRT: 5
|
||||
driver_FD3: 0
|
||||
driver_TPFD: 4
|
||||
driver_CHM: 0
|
||||
driver_VHIGHFS: 0
|
||||
driver_VHIGHCHM: 0
|
||||
driver_DISS2G: 0
|
||||
driver_DISS2VS: 0
|
||||
driver_PWM_AUTOSCALE: True
|
||||
driver_PWM_AUTOGRAD: True
|
||||
driver_PWM_FREQ: 0
|
||||
driver_FREEWHEEL: 0
|
||||
driver_PWM_GRAD: 0
|
||||
driver_PWM_OFS: 29
|
||||
driver_PWM_REG: 4
|
||||
driver_PWM_LIM: 12
|
||||
driver_SGT: 0
|
||||
driver_SEMIN: 0
|
||||
driver_SEUP: 0
|
||||
driver_SEMAX: 0
|
||||
driver_SEDN: 0
|
||||
driver_SEIMIN: 0
|
||||
driver_SFILT: 0
|
||||
driver_SG4_ANGLE_OFFSET: 1
|
||||
interpolate: True
|
||||
sense_resistor: 0.075
|
||||
stealthchop_threshold: 0
|
||||
driver_MSLUT0: 2863314260
|
||||
driver_MSLUT1: 1251300522
|
||||
driver_MSLUT2: 608774441
|
||||
driver_MSLUT3: 269500962
|
||||
driver_MSLUT4: 4227858431
|
||||
driver_MSLUT5: 3048961917
|
||||
driver_MSLUT6: 1227445590
|
||||
driver_MSLUT7: 4211234
|
||||
driver_W0: 2
|
||||
driver_W1: 1
|
||||
driver_W2: 1
|
||||
driver_W3: 1
|
||||
driver_X1: 128
|
||||
driver_X2: 255
|
||||
driver_X3: 255
|
||||
driver_START_SIN: 0
|
||||
driver_START_SIN90: 247
|
||||
driver_MULTISTEP_FILT: True
|
||||
driver_IHOLDDELAY: 6
|
||||
driver_TPOWERDOWN: 10
|
||||
driver_TBL: 2
|
||||
driver_TOFF: 3
|
||||
driver_HEND: 2
|
||||
driver_HSTRT: 5
|
||||
driver_FD3: 0
|
||||
driver_TPFD: 4
|
||||
driver_CHM: 0
|
||||
driver_VHIGHFS: 0
|
||||
driver_VHIGHCHM: 0
|
||||
driver_DISS2G: 0
|
||||
driver_DISS2VS: 0
|
||||
driver_PWM_AUTOSCALE: True
|
||||
driver_PWM_AUTOGRAD: True
|
||||
driver_PWM_FREQ: 0
|
||||
driver_FREEWHEEL: 0
|
||||
driver_PWM_GRAD: 0
|
||||
driver_PWM_OFS: 30
|
||||
driver_PWM_REG: 4
|
||||
driver_PWM_LIM: 12
|
||||
driver_SGT: 0
|
||||
driver_SEMIN: 0
|
||||
driver_SEUP: 0
|
||||
driver_SEMAX: 0
|
||||
driver_SEDN: 0
|
||||
driver_SEIMIN: 0
|
||||
driver_SFILT: 0
|
||||
driver_DRVSTRENGTH: 0
|
||||
driver_BBMCLKS: 4
|
||||
driver_BBMTIME: 0
|
||||
driver_FILT_ISENSE: 0
|
||||
i2c_address: 96
|
||||
analog_pullup_resistor: 4700
|
||||
lcd_type: hd44780
|
||||
hd44780_protocol_init: True
|
||||
lcd_type: hd44780_spi
|
||||
hd44780_protocol_init: True
|
||||
lcd_type: st7920
|
||||
lcd_type: emulated_st7920
|
||||
lcd_type: uc1701
|
||||
vcomh: 0
|
||||
invert: False
|
||||
x_offset: 0
|
||||
type: disabled
|
||||
type: list
|
||||
type: command
|
||||
type: input
|
||||
pause_on_runout: True
|
||||
event_delay: 3.0
|
||||
pause_delay: 0.5
|
||||
detection_length: 7.0
|
||||
default_nominal_filament_diameter: 1.75
|
||||
max_difference: 0.2
|
||||
measurement_delay: 100
|
||||
cal_dia1: 1.50
|
||||
cal_dia2: 2.00
|
||||
raw_dia1: 9500
|
||||
raw_dia2: 10500
|
||||
default_nominal_filament_diameter: 1.75
|
||||
max_difference: 0.200
|
||||
measurement_delay: 70
|
||||
enable: False
|
||||
measurement_interval: 10
|
||||
logging: False
|
||||
min_diameter: 1.0
|
||||
use_current_dia_while_delay: False
|
||||
sensor_type: hx711
|
||||
gain: A-128
|
||||
sample_rate: 80
|
||||
sensor_type: hx717
|
||||
gain: A-128
|
||||
sample_rate: 320
|
||||
sensor_type: ads1220
|
||||
spi_speed: 512000
|
||||
gain: 128
|
||||
sample_rate: 660
|
||||
smooth_time: 2.0
|
||||
enable_pin: !gpio0_20
|
||||
standstill_power_down: False
|
||||
baud: 115200
|
||||
feedrate_splice: 0.8
|
||||
feedrate_normal: 1.0
|
||||
auto_load_speed: 2
|
||||
auto_cancel_variation: 0.1
|
||||
sample_period: 0.000400
|
||||
@@ -0,0 +1,37 @@
|
||||
[section]
|
||||
[section with spaces]
|
||||
[section with spaces and comments] ; comment 1
|
||||
[section with spaces and comments] # comment 2
|
||||
indented_option: value
|
||||
option_with_no_value:
|
||||
another_option_with_no_value:
|
||||
indented_option_with_no_value:
|
||||
# position_min: 0
|
||||
# homing_speed: 5.0
|
||||
|
||||
### this is a comment
|
||||
; this is also a comment
|
||||
# [section]
|
||||
# [section with spaces]
|
||||
# [section with spaces and comments] ; comment 1
|
||||
;[section]
|
||||
;[section with spaces]
|
||||
;[section with spaces and comments] ; comment 1
|
||||
# commented_option: value
|
||||
#commented_option: value
|
||||
;commented_option: value
|
||||
; commented_option: value
|
||||
#
|
||||
;
|
||||
option_1 :: value
|
||||
option_1:: value
|
||||
option_1 ::value
|
||||
option_2 == value
|
||||
option_2== value
|
||||
option_2 ==value
|
||||
option_1 := value
|
||||
option_1:= value
|
||||
option_1 :=value
|
||||
option_2 := value
|
||||
option_2:= value
|
||||
option_2 :=value
|
||||
39
tests/line_matching/match_option/test_match_option.py
Normal file
39
tests/line_matching/match_option/test_match_option.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.joinpath("test_data")
|
||||
MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("matching_data.txt")
|
||||
NON_MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("non_matching_data.txt")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
return SimpleConfigParser()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(MATCHING_TEST_DATA_PATH))
|
||||
def test_match_option(parser, line):
|
||||
"""Test that a line matches the definition of an option"""
|
||||
assert (
|
||||
parser._match_option(line) is True
|
||||
), f"Expected line '{line}' to match option definition!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(NON_MATCHING_TEST_DATA_PATH))
|
||||
def test_non_matching_option(parser, line):
|
||||
"""Test that a line does not match the definition of an option"""
|
||||
assert (
|
||||
parser._match_option(line) is False
|
||||
), f"Expected line '{line}' to not match option definition!"
|
||||
@@ -0,0 +1,15 @@
|
||||
trusted_clients:
|
||||
gcode:
|
||||
cors_domains:
|
||||
an_options_block_start_with_comment: ; this is a comment
|
||||
an_options_block_start_with_comment: # this is a comment
|
||||
options_block_start_with_comment:;this is a comment
|
||||
options_block_start_with_comment :;this is a comment
|
||||
options_block_start_with_comment:#this is a comment
|
||||
options_block_start_with_comment :#this is a comment
|
||||
parameter_temperature_(°C):
|
||||
parameter_temperature_(°C)=
|
||||
parameter_humidity_(%_RH):
|
||||
parameter_humidity_(%_RH) :
|
||||
parameter_spool_weight_(%):
|
||||
parameter_spool_weight_(%) =
|
||||
@@ -0,0 +1,31 @@
|
||||
type: jsonfile
|
||||
path: /dev/shm/drying_box.json
|
||||
baud: 250000
|
||||
minimum_cruise_ratio: 0.5
|
||||
square_corner_velocity: 5.0
|
||||
full_steps_per_rotation: 200
|
||||
position_min: 0
|
||||
homing_speed: 5.0
|
||||
# baud: 250000
|
||||
# minimum_cruise_ratio: 0.5
|
||||
# square_corner_velocity: 5.0
|
||||
# full_steps_per_rotation: 200
|
||||
# position_min: 0
|
||||
# homing_speed: 5.0
|
||||
|
||||
### this is a comment
|
||||
; this is also a comment
|
||||
;
|
||||
#
|
||||
homing_speed::
|
||||
homing_speed::
|
||||
homing_speed ::
|
||||
homing_speed ::
|
||||
homing_speed==
|
||||
homing_speed==
|
||||
homing_speed ==
|
||||
homing_speed ==
|
||||
homing_speed :=
|
||||
homing_speed :=
|
||||
homing_speed =:
|
||||
homing_speed =:
|
||||
@@ -0,0 +1,39 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.joinpath("test_data")
|
||||
MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("matching_data.txt")
|
||||
NON_MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("non_matching_data.txt")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
return SimpleConfigParser()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(MATCHING_TEST_DATA_PATH))
|
||||
def test_match_options_block_start(parser, line):
|
||||
"""Test that a line matches the definition of an options block start"""
|
||||
assert (
|
||||
parser._match_options_block_start(line) is True
|
||||
), f"Expected line '{line}' to match options block start definition!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(NON_MATCHING_TEST_DATA_PATH))
|
||||
def test_non_matching_options_block_start(parser, line):
|
||||
"""Test that a line does not match the definition of an options block start"""
|
||||
assert (
|
||||
parser._match_options_block_start(line) is False
|
||||
), f"Expected line '{line}' to not match options block start definition!"
|
||||
0
tests/line_matching/match_section/__init__,py.py
Normal file
0
tests/line_matching/match_section/__init__,py.py
Normal file
127
tests/line_matching/match_section/test_data/matching_data.txt
Normal file
127
tests/line_matching/match_section/test_data/matching_data.txt
Normal file
@@ -0,0 +1,127 @@
|
||||
[example_section]
|
||||
[gcode_macro CANCEL_PRINT]
|
||||
[gcode_macro SET_PAUSE_NEXT_LAYER]
|
||||
[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL]
|
||||
[update_manager moonraker-obico]
|
||||
[include moonraker_obico_macros.cfg]
|
||||
[include moonraker-obico-update.cfg]
|
||||
[example_section two]
|
||||
[valid_content]
|
||||
[valid content]
|
||||
[content123]
|
||||
[a]
|
||||
[valid_content] # comment
|
||||
[something];comment
|
||||
[mcu]
|
||||
[printer]
|
||||
[printer]
|
||||
[stepper_x]
|
||||
[stepper_y]
|
||||
[stepper_z]
|
||||
[printer]
|
||||
[stepper_a]
|
||||
[stepper_b]
|
||||
[stepper_c]
|
||||
[delta_calibrate]
|
||||
[printer]
|
||||
[stepper_left]
|
||||
[stepper_right]
|
||||
[stepper_bed]
|
||||
[stepper_arm]
|
||||
[delta_calibrate]
|
||||
[extruder]
|
||||
[heater_bed]
|
||||
[bed_mesh]
|
||||
[bed_tilt]
|
||||
[bed_screws]
|
||||
[screws_tilt_adjust]
|
||||
[z_tilt]
|
||||
[quad_gantry_level]
|
||||
[skew_correction]
|
||||
[z_thermal_adjust]
|
||||
[safe_z_home]
|
||||
[homing_override]
|
||||
[endstop_phase stepper_z]
|
||||
[gcode_macro my_cmd]
|
||||
[delayed_gcode my_delayed_gcode]
|
||||
[save_variables]
|
||||
[idle_timeout]
|
||||
[virtual_sdcard]
|
||||
[sdcard_loop]
|
||||
[force_move]
|
||||
[pause_resume]
|
||||
[firmware_retraction]
|
||||
[gcode_arcs]
|
||||
[respond]
|
||||
[exclude_object]
|
||||
[input_shaper]
|
||||
[adxl345]
|
||||
[lis2dw]
|
||||
[mpu9250 my_accelerometer]
|
||||
[resonance_tester]
|
||||
[board_pins my_aliases]
|
||||
[duplicate_pin_override]
|
||||
[probe]
|
||||
[bltouch]
|
||||
[smart_effector]
|
||||
[probe_eddy_current my_eddy_probe]
|
||||
[axis_twist_compensation]
|
||||
[stepper_z1]
|
||||
[extruder1]
|
||||
[dual_carriage]
|
||||
[extruder_stepper my_extra_stepper]
|
||||
[manual_stepper my_stepper]
|
||||
[verify_heater heater_config_name]
|
||||
[homing_heaters]
|
||||
[thermistor my_thermistor]
|
||||
[adc_temperature my_sensor]
|
||||
[heater_generic my_generic_heater]
|
||||
[temperature_sensor my_sensor]
|
||||
[temperature_probe my_probe]
|
||||
[fan]
|
||||
[heater_fan heatbreak_cooling_fan]
|
||||
[controller_fan my_controller_fan]
|
||||
[temperature_fan my_temp_fan]
|
||||
[fan_generic extruder_partfan]
|
||||
[led my_led]
|
||||
[neopixel my_neopixel]
|
||||
[dotstar my_dotstar]
|
||||
[pca9533 my_pca9533]
|
||||
[pca9632 my_pca9632]
|
||||
[servo my_servo]
|
||||
[gcode_button my_gcode_button]
|
||||
[output_pin my_pin]
|
||||
[pwm_tool my_tool]
|
||||
[pwm_cycle_time my_pin]
|
||||
[static_digital_output my_output_pins]
|
||||
[multi_pin my_multi_pin]
|
||||
[tmc2130 stepper_x]
|
||||
[tmc2208 stepper_x]
|
||||
[tmc2209 stepper_x]
|
||||
[tmc2660 stepper_x]
|
||||
[tmc2240 stepper_x]
|
||||
[tmc5160 stepper_x]
|
||||
[ad5206 my_digipot]
|
||||
[mcp4451 my_digipot]
|
||||
[mcp4728 my_dac]
|
||||
[mcp4018 my_digipot]
|
||||
[display]
|
||||
[display_data my_group_name my_data_name]
|
||||
[display_template my_template_name]
|
||||
[display_glyph my_display_glyph]
|
||||
[menu __some_list __some_name]
|
||||
[menu some_name]
|
||||
[menu some_list]
|
||||
[menu some_list some_command]
|
||||
[menu some_list some_input]
|
||||
[filament_switch_sensor my_sensor]
|
||||
[filament_motion_sensor my_sensor]
|
||||
[tsl1401cl_filament_width_sensor]
|
||||
[hall_filament_width_sensor]
|
||||
[load_cell]
|
||||
[sx1509 my_sx1509]
|
||||
[samd_sercom my_sercom]
|
||||
[adc_scaled my_name]
|
||||
[replicape]
|
||||
[palette2]
|
||||
[angle my_angle_sensor]
|
||||
@@ -0,0 +1,19 @@
|
||||
section: invalid
|
||||
not_a_valid_section
|
||||
[missing_square_bracket
|
||||
missing_square_bracket]
|
||||
[]
|
||||
[ ]
|
||||
[indented_section]
|
||||
[indented_section] # comment
|
||||
[indented_section] ; comment
|
||||
;[commented_section]
|
||||
#[another_commented_section]
|
||||
; [commented_section]
|
||||
# [another_commented_section]
|
||||
this_is_an_option: 123
|
||||
this_is_an_indented_option: 123
|
||||
this_is_an_option_block_start:
|
||||
|
||||
#
|
||||
;
|
||||
39
tests/line_matching/match_section/test_match_section.py
Normal file
39
tests/line_matching/match_section/test_match_section.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.joinpath("test_data")
|
||||
MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("matching_data.txt")
|
||||
NON_MATCHING_TEST_DATA_PATH = BASE_DIR.joinpath("non_matching_data.txt")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
return SimpleConfigParser()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(MATCHING_TEST_DATA_PATH))
|
||||
def test_match_section(parser, line):
|
||||
"""Test that a line matches the definition of a section"""
|
||||
assert (
|
||||
parser._match_section(line) is True
|
||||
), f"Expected line '{line}' to match section definition!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("line", load_testdata_from_file(NON_MATCHING_TEST_DATA_PATH))
|
||||
def test_non_matching_section(parser, line):
|
||||
"""Test that a line does not match the definition of a section"""
|
||||
assert (
|
||||
parser._match_section(line) is False
|
||||
), f"Expected line '{line}' to not match section definition!"
|
||||
0
tests/line_parsing/__init__.py
Normal file
0
tests/line_parsing/__init__.py
Normal file
62
tests/line_parsing/test_line_parsing.py
Normal file
62
tests/line_parsing/test_line_parsing.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.constants import HEADER_IDENT
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.parent.joinpath("assets")
|
||||
TEST_DATA_PATH = BASE_DIR.joinpath("test_config_1.cfg")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
parser = SimpleConfigParser()
|
||||
for line in load_testdata_from_file(TEST_DATA_PATH):
|
||||
parser._parse_line(line) # noqa
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def test_section_parsing(parser):
|
||||
expected_keys = {"section_1", "section_2", "section_3", "section_4"}
|
||||
assert expected_keys.issubset(
|
||||
parser.config.keys()
|
||||
), f"Expected keys: {expected_keys}, got: {parser.config.keys()}"
|
||||
assert parser.in_option_block is False
|
||||
assert parser.current_section == parser.get_sections()[-1]
|
||||
assert parser.config["section_2"]["_raw"] == "[section_2] ; comment"
|
||||
|
||||
|
||||
def test_option_parsing(parser):
|
||||
assert parser.config["section_1"]["option_1"]["value"] == "value_1"
|
||||
assert parser.config["section_1"]["option_1"]["_raw"] == "option_1: value_1"
|
||||
assert parser.config["section_3"]["option_3"]["value"] == "value_3"
|
||||
assert (
|
||||
parser.config["section_3"]["option_3"]["_raw"] == "option_3: value_3 # comment"
|
||||
)
|
||||
|
||||
|
||||
def test_header_parsing(parser):
|
||||
header = parser.config[HEADER_IDENT]
|
||||
assert isinstance(header, list)
|
||||
assert len(header) > 0
|
||||
|
||||
|
||||
def test_collector_parsing(parser):
|
||||
section = "section_2"
|
||||
section_content = list(parser.config[section].keys())
|
||||
coll_name = [name for name in section_content if name.startswith("#_")][0]
|
||||
collector = parser.config[section][coll_name]
|
||||
assert collector is not None
|
||||
assert isinstance(collector, list)
|
||||
assert len(collector) > 0
|
||||
assert "; comment" in collector
|
||||
0
tests/public_api/__init__.py
Normal file
0
tests/public_api/__init__.py
Normal file
26
tests/public_api/conftest.py
Normal file
26
tests/public_api/conftest.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.parent.joinpath("assets")
|
||||
CONFIG_FILES = ["test_config_1.cfg", "test_config_2.cfg", "test_config_3.cfg"]
|
||||
|
||||
|
||||
@pytest.fixture(params=CONFIG_FILES)
|
||||
def parser(request):
|
||||
parser = SimpleConfigParser()
|
||||
file_path = BASE_DIR.joinpath(request.param)
|
||||
for line in load_testdata_from_file(file_path):
|
||||
parser._parse_line(line) # noqa
|
||||
|
||||
return parser
|
||||
174
tests/public_api/test_options_api.py
Normal file
174
tests/public_api/test_options_api.py
Normal file
@@ -0,0 +1,174 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import (
|
||||
NoOptionError,
|
||||
NoSectionError,
|
||||
)
|
||||
|
||||
|
||||
def test_get_options(parser):
|
||||
expected_options = {
|
||||
"section_1": {"option_1"},
|
||||
"section_2": {"option_2"},
|
||||
"section_3": {"option_3"},
|
||||
"section_4": {"option_4"},
|
||||
"section number 5": {"option_5", "multi_option", "option_5_1"},
|
||||
}
|
||||
|
||||
for section, options in expected_options.items():
|
||||
assert options.issubset(
|
||||
parser.get_options(section)
|
||||
), f"Expected options: {options} in section: {section}, got: {parser.get_options(section)}"
|
||||
assert "_raw" not in parser.get_options(section)
|
||||
assert all(
|
||||
not option.startswith("#_") for option in parser.get_options(section)
|
||||
)
|
||||
|
||||
|
||||
def test_has_option(parser):
|
||||
assert parser.has_option("section_1", "option_1") is True
|
||||
assert parser.has_option("section_1", "option_128") is False
|
||||
# section does not exist:
|
||||
assert parser.has_option("section_128", "option_1") is False
|
||||
|
||||
|
||||
def test_getval(parser):
|
||||
# test regular option values
|
||||
assert parser.getval("section_1", "option_1") == "value_1"
|
||||
assert parser.getval("section_3", "option_3") == "value_3"
|
||||
assert parser.getval("section_4", "option_4") == "value_4"
|
||||
assert parser.getval("section number 5", "option_5") == "this.is.value-5"
|
||||
assert parser.getval("section number 5", "option_5_1") == "value_5_1"
|
||||
assert parser.getval("section_2", "option_2") == "value_2"
|
||||
|
||||
# test multiline option values
|
||||
ml_val = parser.getval("section number 5", "multi_option")
|
||||
assert isinstance(ml_val, list)
|
||||
assert len(ml_val) > 0
|
||||
|
||||
|
||||
def test_getval_fallback(parser):
|
||||
assert parser.getval("section_1", "option_128", "fallback") == "fallback"
|
||||
|
||||
|
||||
def test_getval_exceptions(parser):
|
||||
with pytest.raises(NoSectionError):
|
||||
parser.getval("section_128", "option_1")
|
||||
|
||||
with pytest.raises(NoOptionError):
|
||||
parser.getval("section_1", "option_128")
|
||||
|
||||
|
||||
def test_getint(parser):
|
||||
value = parser.getint("section_1", "option_1_2")
|
||||
assert isinstance(value, int)
|
||||
|
||||
|
||||
def test_getint_from_val(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getint("section_1", "option_1")
|
||||
|
||||
|
||||
def test_getint_from_float(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getint("section_1", "option_1_3")
|
||||
|
||||
|
||||
def test_getint_from_boolean(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getint("section_1", "option_1_1")
|
||||
|
||||
|
||||
def test_getint_fallback(parser):
|
||||
assert parser.getint("section_1", "option_128", 128) == 128
|
||||
|
||||
|
||||
def test_getboolean(parser):
|
||||
value = parser.getboolean("section_1", "option_1_1")
|
||||
assert isinstance(value, bool)
|
||||
assert value is True or value is False
|
||||
|
||||
|
||||
def test_getboolean_from_val(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getboolean("section_1", "option_1")
|
||||
|
||||
|
||||
def test_getboolean_from_int(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getboolean("section_1", "option_1_2")
|
||||
|
||||
|
||||
def test_getboolean_from_float(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getboolean("section_1", "option_1_3")
|
||||
|
||||
|
||||
def test_getboolean_fallback(parser):
|
||||
assert parser.getboolean("section_1", "option_128", True) is True
|
||||
assert parser.getboolean("section_1", "option_128", False) is False
|
||||
|
||||
|
||||
def test_getfloat(parser):
|
||||
value = parser.getfloat("section_1", "option_1_3")
|
||||
assert isinstance(value, float)
|
||||
|
||||
|
||||
def test_getfloat_from_val(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getfloat("section_1", "option_1")
|
||||
|
||||
|
||||
def test_getfloat_from_int(parser):
|
||||
value = parser.getfloat("section_1", "option_1_2")
|
||||
assert isinstance(value, float)
|
||||
|
||||
|
||||
def test_getfloat_from_boolean(parser):
|
||||
with pytest.raises(ValueError):
|
||||
parser.getfloat("section_1", "option_1_1")
|
||||
|
||||
|
||||
def test_getfloat_fallback(parser):
|
||||
assert parser.getfloat("section_1", "option_128", 1.234) == 1.234
|
||||
|
||||
|
||||
def test_set_existing_option(parser):
|
||||
parser.set_option("section_1", "new_option", "new_value")
|
||||
assert parser.getval("section_1", "new_option") == "new_value"
|
||||
assert parser.config["section_1"]["new_option"]["_raw"] == "new_option: new_value\n"
|
||||
|
||||
parser.set_option("section_1", "new_option", "new_value_2")
|
||||
assert parser.getval("section_1", "new_option") == "new_value_2"
|
||||
assert (
|
||||
parser.config["section_1"]["new_option"]["_raw"] == "new_option: new_value_2\n"
|
||||
)
|
||||
|
||||
|
||||
def test_set_new_option(parser):
|
||||
parser.set_option("new_section", "very_new_option", "very_new_value")
|
||||
assert (
|
||||
parser.has_section("new_section") is True
|
||||
), f"Expected 'new_section' in {parser.get_sections()}"
|
||||
assert parser.getval("new_section", "very_new_option") == "very_new_value"
|
||||
|
||||
parser.set_option("section_2", "array_option", ["value_1", "value_2", "value_3"])
|
||||
assert parser.getval("section_2", "array_option") == [
|
||||
"value_1",
|
||||
"value_2",
|
||||
"value_3",
|
||||
]
|
||||
assert parser.config["section_2"]["array_option"]["_raw"] == "array_option:\n"
|
||||
|
||||
|
||||
def test_remove_option(parser):
|
||||
parser.remove_option("section_1", "option_1")
|
||||
assert parser.has_option("section_1", "option_1") is False
|
||||
22
tests/public_api/test_read_file.py
Normal file
22
tests/public_api/test_read_file.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
from pathlib import Path
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import (
|
||||
SimpleConfigParser,
|
||||
)
|
||||
|
||||
BASE_DIR = Path(__file__).parent.parent.joinpath("assets")
|
||||
TEST_DATA_PATH = BASE_DIR.joinpath("test_config_1.cfg")
|
||||
|
||||
|
||||
def test_read_file():
|
||||
parser = SimpleConfigParser()
|
||||
parser.read_file(TEST_DATA_PATH)
|
||||
assert parser.config is not None
|
||||
assert parser.config.keys() is not None
|
||||
66
tests/public_api/test_sections_api.py
Normal file
66
tests/public_api/test_sections_api.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import (
|
||||
DuplicateSectionError,
|
||||
)
|
||||
|
||||
|
||||
def test_get_sections(parser):
|
||||
expected_keys = {
|
||||
"section_1",
|
||||
"section_2",
|
||||
"section_3",
|
||||
"section_4",
|
||||
"section number 5",
|
||||
}
|
||||
assert expected_keys.issubset(
|
||||
parser.get_sections()
|
||||
), f"Expected keys: {expected_keys}, got: {parser.get_sections()}"
|
||||
|
||||
|
||||
def test_has_section(parser):
|
||||
assert parser.has_section("section_1") is True
|
||||
assert parser.has_section("not_available") is False
|
||||
|
||||
|
||||
def test_add_section(parser):
|
||||
pre_add_count = len(parser.get_sections())
|
||||
parser.add_section("new_section")
|
||||
parser.add_section("new_section2")
|
||||
assert parser.has_section("new_section") is True
|
||||
assert parser.has_section("new_section2") is True
|
||||
assert len(parser.get_sections()) == pre_add_count + 2
|
||||
|
||||
new_section = parser.config["new_section"]
|
||||
assert isinstance(new_section, dict)
|
||||
assert new_section["_raw"] == "[new_section]\n"
|
||||
|
||||
# this should be the collector, added by the parser before
|
||||
# then second section was added
|
||||
assert list(new_section.keys())[-1].startswith("#_")
|
||||
assert "\n" in new_section[list(new_section.keys())[-1]]
|
||||
|
||||
new_section2 = parser.config["new_section2"]
|
||||
assert isinstance(new_section2, dict)
|
||||
assert new_section2["_raw"] == "[new_section2]\n"
|
||||
|
||||
|
||||
def test_add_section_duplicate(parser):
|
||||
with pytest.raises(DuplicateSectionError):
|
||||
parser.add_section("section_1")
|
||||
|
||||
|
||||
def test_remove_section(parser):
|
||||
pre_remove_count = len(parser.get_sections())
|
||||
parser.remove_section("section_1")
|
||||
assert parser.has_section("section_1") is False
|
||||
assert len(parser.get_sections()) == pre_remove_count - 1
|
||||
assert "section_1" not in parser.config
|
||||
41
tests/public_api/test_write_file.py
Normal file
41
tests/public_api/test_write_file.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import (
|
||||
SimpleConfigParser,
|
||||
)
|
||||
|
||||
BASE_DIR = Path(__file__).parent.parent.joinpath("assets")
|
||||
TEST_DATA_PATH = BASE_DIR.joinpath("test_config_1.cfg")
|
||||
# TEST_DATA_PATH_2 = BASE_DIR.joinpath("test_config_1_write.cfg")
|
||||
|
||||
|
||||
def test_write_file_exception():
|
||||
parser = SimpleConfigParser()
|
||||
with pytest.raises(ValueError):
|
||||
parser.write_file(None) # noqa
|
||||
|
||||
|
||||
def test_write_to_file(tmp_path):
|
||||
tmp_file = Path(tmp_path).joinpath("tmp_config.cfg")
|
||||
parser1 = SimpleConfigParser()
|
||||
parser1.read_file(TEST_DATA_PATH)
|
||||
# parser1.write_file(TEST_DATA_PATH_2)
|
||||
parser1.write_file(tmp_file)
|
||||
|
||||
parser2 = SimpleConfigParser()
|
||||
parser2.read_file(tmp_file)
|
||||
|
||||
assert tmp_file.exists()
|
||||
assert parser2.config is not None
|
||||
|
||||
with open(TEST_DATA_PATH, "r") as original, open(tmp_file, "r") as written:
|
||||
assert original.read() == written.read()
|
||||
15
tests/utils.py
Normal file
15
tests/utils.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def load_testdata_from_file(file_path: Path):
|
||||
"""Helper function to load test data from a text file"""
|
||||
|
||||
with open(file_path, "r") as f:
|
||||
return [line.replace("\n", "") for line in f]
|
||||
0
tests/value_conversion/__init__.py
Normal file
0
tests/value_conversion/__init__.py
Normal file
74
tests/value_conversion/test_get_conv.py
Normal file
74
tests/value_conversion/test_get_conv.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# ======================================================================= #
|
||||
# Copyright (C) 2024 Dominik Willner <th33xitus@gmail.com> #
|
||||
# #
|
||||
# https://github.com/dw-0/simple-config-parser #
|
||||
# #
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license #
|
||||
# ======================================================================= #
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from src.simple_config_parser.simple_config_parser import SimpleConfigParser
|
||||
from tests.utils import load_testdata_from_file
|
||||
|
||||
BASE_DIR = Path(__file__).parent.parent.joinpath("assets")
|
||||
TEST_DATA_PATH = BASE_DIR.joinpath("test_config_1.cfg")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def parser():
|
||||
parser = SimpleConfigParser()
|
||||
for line in load_testdata_from_file(TEST_DATA_PATH):
|
||||
parser._parse_line(line) # noqa
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def test_get_conv(parser):
|
||||
# Test conversion to int
|
||||
should_be_int = parser._get_conv("section_1", "option_1_2", int)
|
||||
assert isinstance(should_be_int, int)
|
||||
|
||||
# Test conversion to float
|
||||
should_be_float = parser._get_conv("section_1", "option_1_3", float)
|
||||
assert isinstance(should_be_float, float)
|
||||
|
||||
# Test conversion to boolean
|
||||
should_be_bool = parser._get_conv(
|
||||
"section_1", "option_1_1", parser._convert_to_boolean
|
||||
)
|
||||
assert isinstance(should_be_bool, bool)
|
||||
|
||||
# Test fallback for int
|
||||
should_be_fallback_int = parser._get_conv(
|
||||
"section_1", "option_128", int, fallback=128
|
||||
)
|
||||
assert isinstance(should_be_fallback_int, int)
|
||||
assert should_be_fallback_int == 128
|
||||
|
||||
# Test fallback for float
|
||||
should_be_fallback_float = parser._get_conv(
|
||||
"section_1", "option_128", float, fallback=1.234
|
||||
)
|
||||
assert isinstance(should_be_fallback_float, float)
|
||||
assert should_be_fallback_float == 1.234
|
||||
|
||||
# Test fallback for boolean
|
||||
should_be_fallback_bool = parser._get_conv(
|
||||
"section_1", "option_128", parser._convert_to_boolean, fallback=True
|
||||
)
|
||||
assert isinstance(should_be_fallback_bool, bool)
|
||||
assert should_be_fallback_bool is True
|
||||
|
||||
# Test ValueError exception for invalid int conversion
|
||||
with pytest.raises(ValueError):
|
||||
parser._get_conv("section_1", "option_1", int)
|
||||
|
||||
# Test ValueError exception for invalid float conversion
|
||||
with pytest.raises(ValueError):
|
||||
parser._get_conv("section_1", "option_1", float)
|
||||
|
||||
# Test ValueError exception for invalid boolean conversion
|
||||
with pytest.raises(ValueError):
|
||||
parser._get_conv("section_1", "option_1", parser._convert_to_boolean)
|
||||
Reference in New Issue
Block a user