mirror of
https://github.com/esphome/esphome.git
synced 2025-09-02 03:12:20 +01:00
Merge branch 'dev' into bump-1.17.0b1
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
""" Tests for the binary sensor component """
|
||||
"""Tests for the binary sensor component."""
|
||||
|
||||
|
||||
def test_binary_sensor_is_setup(generate_main):
|
||||
@@ -8,7 +8,9 @@ def test_binary_sensor_is_setup(generate_main):
|
||||
# Given
|
||||
|
||||
# When
|
||||
main_cpp = generate_main("tests/component_tests/binary_sensor/test_binary_sensor.yaml")
|
||||
main_cpp = generate_main(
|
||||
"tests/component_tests/binary_sensor/test_binary_sensor.yaml"
|
||||
)
|
||||
|
||||
# Then
|
||||
assert "new gpio::GPIOBinarySensor();" in main_cpp
|
||||
@@ -22,10 +24,12 @@ def test_binary_sensor_sets_mandatory_fields(generate_main):
|
||||
# Given
|
||||
|
||||
# When
|
||||
main_cpp = generate_main("tests/component_tests/binary_sensor/test_binary_sensor.yaml")
|
||||
main_cpp = generate_main(
|
||||
"tests/component_tests/binary_sensor/test_binary_sensor.yaml"
|
||||
)
|
||||
|
||||
# Then
|
||||
assert "bs_1->set_name(\"test bs1\");" in main_cpp
|
||||
assert 'bs_1->set_name("test bs1");' in main_cpp
|
||||
assert "bs_1->set_pin(new GPIOPin" in main_cpp
|
||||
|
||||
|
||||
@@ -36,7 +40,9 @@ def test_binary_sensor_config_value_internal_set(generate_main):
|
||||
# Given
|
||||
|
||||
# When
|
||||
main_cpp = generate_main("tests/component_tests/binary_sensor/test_binary_sensor.yaml")
|
||||
main_cpp = generate_main(
|
||||
"tests/component_tests/binary_sensor/test_binary_sensor.yaml"
|
||||
)
|
||||
|
||||
# Then
|
||||
assert "bs_1->set_internal(true);" in main_cpp
|
||||
|
@@ -1,4 +1,12 @@
|
||||
""" Fixtures for component tests """
|
||||
"""Fixtures for component tests."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add package root to python path
|
||||
here = Path(__file__).parent
|
||||
package_root = here.parent.parent
|
||||
sys.path.insert(0, package_root.as_posix())
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -9,7 +17,7 @@ from esphome.__main__ import generate_cpp_contents
|
||||
|
||||
@pytest.fixture
|
||||
def generate_main():
|
||||
""" Generates the C++ main.cpp file and returns it in string form """
|
||||
"""Generates the C++ main.cpp file and returns it in string form."""
|
||||
|
||||
def generator(path: str) -> str:
|
||||
CORE.config_path = path
|
||||
|
14
tests/component_tests/sensor/test_sensor.py
Normal file
14
tests/component_tests/sensor/test_sensor.py
Normal file
@@ -0,0 +1,14 @@
|
||||
"""Tests for the sensor component."""
|
||||
|
||||
|
||||
def test_sensor_device_class_set(generate_main):
|
||||
"""
|
||||
When the device_class of sensor is set in the yaml file, it should be registered in main
|
||||
"""
|
||||
# Given
|
||||
|
||||
# When
|
||||
main_cpp = generate_main("tests/component_tests/sensor/test_sensor.yaml")
|
||||
|
||||
# Then
|
||||
assert 's_1->set_device_class("voltage");' in main_cpp
|
12
tests/component_tests/sensor/test_sensor.yaml
Normal file
12
tests/component_tests/sensor/test_sensor.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
esphome:
|
||||
name: test
|
||||
platform: ESP8266
|
||||
board: d1_mini_lite
|
||||
|
||||
sensor:
|
||||
- platform: adc
|
||||
pin: A0
|
||||
id: s_1
|
||||
name: "test s1"
|
||||
update_interval: 60s
|
||||
device_class: "voltage"
|
225
tests/test1.yaml
225
tests/test1.yaml
@@ -1,8 +1,12 @@
|
||||
substitutions:
|
||||
devicename: test1
|
||||
sensorname: my
|
||||
textname: template
|
||||
roomname: living_room
|
||||
|
||||
esphome:
|
||||
name: test1
|
||||
name_add_mac_suffix: true
|
||||
platform: ESP32
|
||||
board: nodemcu-32s
|
||||
on_boot:
|
||||
@@ -26,6 +30,31 @@ esphome:
|
||||
green: !lambda 'return 255;'
|
||||
blue: 0%
|
||||
white: 100%
|
||||
- http_request.get:
|
||||
url: https://esphome.io
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
verify_ssl: false
|
||||
- http_request.post:
|
||||
url: https://esphome.io
|
||||
verify_ssl: false
|
||||
json:
|
||||
key: !lambda |-
|
||||
return id(${textname}_text).state;
|
||||
greeting: 'Hello World'
|
||||
- http_request.send:
|
||||
method: PUT
|
||||
url: https://esphome.io
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
body: 'Some data'
|
||||
verify_ssl: false
|
||||
on_response:
|
||||
then:
|
||||
- logger.log:
|
||||
format: 'Response status: %d'
|
||||
args:
|
||||
- status_code
|
||||
build_path: build/test1
|
||||
|
||||
packages:
|
||||
@@ -50,6 +79,10 @@ wifi:
|
||||
reboot_timeout: 120s
|
||||
power_save_mode: none
|
||||
|
||||
http_request:
|
||||
useragent: esphome/device
|
||||
timeout: 10s
|
||||
|
||||
mqtt:
|
||||
broker: '192.168.178.84'
|
||||
port: 1883
|
||||
@@ -98,7 +131,7 @@ mqtt:
|
||||
int data = x["my_data"];
|
||||
ESP_LOGD("main", "The data is: %d", data);
|
||||
- light.turn_on:
|
||||
id: living_room_lights
|
||||
id: ${roomname}_lights
|
||||
brightness: !lambda |-
|
||||
float brightness = 1.0;
|
||||
if (x.containsKey("brightness"))
|
||||
@@ -110,17 +143,21 @@ mqtt:
|
||||
effect = x["effect"];
|
||||
return effect;
|
||||
- light.control:
|
||||
id: living_room_lights
|
||||
brightness: !lambda 'return id(living_room_lights).current_values.get_brightness() + 0.5;'
|
||||
id: ${roomname}_lights
|
||||
brightness: !lambda 'return id(${roomname}_lights).current_values.get_brightness() + 0.5;'
|
||||
- light.dim_relative:
|
||||
id: living_room_lights
|
||||
id: ${roomname}_lights
|
||||
relative_brightness: 5%
|
||||
- uart.write:
|
||||
id: uart0
|
||||
data: Hello World
|
||||
- uart.write: [0x00, 0x20, 0x30]
|
||||
- uart.write: !lambda |-
|
||||
return {};
|
||||
- uart.write:
|
||||
id: uart0
|
||||
data: [0x00, 0x20, 0x30]
|
||||
- uart.write:
|
||||
id: uart0
|
||||
data: !lambda |-
|
||||
return {};
|
||||
|
||||
i2c:
|
||||
sda: 21
|
||||
@@ -143,6 +180,7 @@ uart:
|
||||
data_bits: 8
|
||||
stop_bits: 1
|
||||
rx_buffer_size: 512
|
||||
invert: false
|
||||
|
||||
- id: adalight_uart
|
||||
tx_pin: GPIO25
|
||||
@@ -237,6 +275,14 @@ sensor:
|
||||
window_size: 5
|
||||
send_every: 5
|
||||
send_first_at: 3
|
||||
- min:
|
||||
window_size: 5
|
||||
send_every: 5
|
||||
send_first_at: 3
|
||||
- max:
|
||||
window_size: 5
|
||||
send_every: 5
|
||||
send_first_at: 3
|
||||
- sliding_window_moving_average:
|
||||
window_size: 15
|
||||
send_every: 15
|
||||
@@ -256,9 +302,9 @@ sensor:
|
||||
then:
|
||||
- lambda: |-
|
||||
ESP_LOGD("main", "Got value %f", x);
|
||||
id(my_sensor).publish_state(42.0);
|
||||
ESP_LOGI("main", "Value of my sensor: %f", id(my_sensor).state);
|
||||
ESP_LOGI("main", "Raw Value of my sensor: %f", id(my_sensor).state);
|
||||
id(${sensorname}_sensor).publish_state(42.0);
|
||||
ESP_LOGI("main", "Value of my sensor: %f", id(${sensorname}_sensor).state);
|
||||
ESP_LOGI("main", "Raw Value of my sensor: %f", id(${sensorname}_sensor).state);
|
||||
on_value_range:
|
||||
above: 5
|
||||
below: 10
|
||||
@@ -285,7 +331,7 @@ sensor:
|
||||
- platform: ads1115
|
||||
multiplexer: 'A0_A1'
|
||||
gain: 1.024
|
||||
id: my_sensor
|
||||
id: ${sensorname}_sensor
|
||||
filters:
|
||||
state_topic: hi/me
|
||||
retain: false
|
||||
@@ -435,7 +481,7 @@ sensor:
|
||||
name: 'HLW8012 Power'
|
||||
id: hlw8012_power
|
||||
energy:
|
||||
name: "HLW8012 Energy"
|
||||
name: 'HLW8012 Energy'
|
||||
id: hlw8012_energy
|
||||
update_interval: 15s
|
||||
current_resistor: 0.001 ohm
|
||||
@@ -549,6 +595,7 @@ sensor:
|
||||
reference_resistance: '430 Ω'
|
||||
rtd_nominal_resistance: '100 Ω'
|
||||
- platform: mhz19
|
||||
uart_id: uart0
|
||||
co2:
|
||||
name: 'MH-Z19 CO2 Value'
|
||||
temperature:
|
||||
@@ -586,6 +633,13 @@ sensor:
|
||||
falling_edge: DECREMENT
|
||||
internal_filter: 13us
|
||||
update_interval: 15s
|
||||
- platform: pulse_meter
|
||||
name: 'Pulse Meter'
|
||||
pin: GPIO12
|
||||
internal_filter: 100ms
|
||||
timeout: 2 min
|
||||
total:
|
||||
name: 'Pulse Meter Total'
|
||||
- platform: rotary_encoder
|
||||
name: 'Rotary Encoder'
|
||||
id: rotary_encoder1
|
||||
@@ -613,10 +667,23 @@ sensor:
|
||||
- platform: pulse_width
|
||||
name: Pulse Width
|
||||
pin: GPIO12
|
||||
- platform: senseair
|
||||
- platform: sm300d2
|
||||
uart_id: uart0
|
||||
co2:
|
||||
name: 'SenseAir CO2 Value'
|
||||
update_interval: 15s
|
||||
name: 'SM300D2 CO2 Value'
|
||||
formaldehyde:
|
||||
name: 'SM300D2 Formaldehyde Value'
|
||||
tvoc:
|
||||
name: 'SM300D2 TVOC Value'
|
||||
pm_2_5:
|
||||
name: 'SM300D2 PM2.5 Value'
|
||||
pm_10_0:
|
||||
name: 'SM300D2 PM10 Value'
|
||||
temperature:
|
||||
name: 'SM300D2 Temperature Value'
|
||||
humidity:
|
||||
name: 'SM300D2 Humidity Value'
|
||||
update_interval: 60s
|
||||
- platform: sht3xd
|
||||
temperature:
|
||||
name: 'Living Room Temperature 8'
|
||||
@@ -735,6 +802,7 @@ sensor:
|
||||
root["key"] = id(the_sensor).state;
|
||||
root["greeting"] = "Hello World";
|
||||
- platform: sds011
|
||||
uart_id: uart0
|
||||
pm_2_5:
|
||||
name: 'SDS011 PM2.5'
|
||||
pm_10_0:
|
||||
@@ -784,6 +852,7 @@ sensor:
|
||||
name: 'AQI'
|
||||
calculation_type: 'CAQI'
|
||||
- platform: teleinfo
|
||||
uart_id: uart0
|
||||
tags:
|
||||
- tag_name: 'HCHC'
|
||||
sensor:
|
||||
@@ -829,7 +898,7 @@ binary_sensor:
|
||||
- platform: gpio
|
||||
name: 'MCP23S08 Pin #1'
|
||||
pin:
|
||||
mcp23s08: mcp23s08_hub
|
||||
mcp23xxx: mcp23s08_hub
|
||||
# Use pin number 1
|
||||
number: 1
|
||||
# One of INPUT or INPUT_PULLUP
|
||||
@@ -838,12 +907,22 @@ binary_sensor:
|
||||
- platform: gpio
|
||||
name: 'MCP23S17 Pin #1'
|
||||
pin:
|
||||
mcp23s17: mcp23s17_hub
|
||||
mcp23xxx: mcp23s17_hub
|
||||
# Use pin number 1
|
||||
number: 1
|
||||
# One of INPUT or INPUT_PULLUP
|
||||
mode: INPUT_PULLUP
|
||||
inverted: False
|
||||
- platform: gpio
|
||||
name: 'MCP23S17 Pin #1 with interrupt'
|
||||
pin:
|
||||
mcp23xxx: mcp23s17_hub
|
||||
# Use pin number 1
|
||||
number: 1
|
||||
# One of INPUT or INPUT_PULLUP
|
||||
mode: INPUT_PULLUP
|
||||
inverted: False
|
||||
interrupt: FALLING
|
||||
- platform: gpio
|
||||
pin: GPIO9
|
||||
name: 'Living Room Window'
|
||||
@@ -924,12 +1003,12 @@ binary_sensor:
|
||||
name: 'Garage Door Open'
|
||||
id: garage_door
|
||||
lambda: |-
|
||||
if (isnan(id(my_sensor).state)) {
|
||||
if (isnan(id(${sensorname}_sensor).state)) {
|
||||
// isnan checks if the ultrasonic sensor echo
|
||||
// has timed out, resulting in a NaN (not a number) state
|
||||
// in that case, return {} to indicate that we don't know.
|
||||
return {};
|
||||
} else if (id(my_sensor).state > 30) {
|
||||
} else if (id(${sensorname}_sensor).state > 30) {
|
||||
// Garage Door is open.
|
||||
return true;
|
||||
} else {
|
||||
@@ -947,6 +1026,7 @@ binary_sensor:
|
||||
id: gpio_19
|
||||
frequency: !lambda 'return 500.0;'
|
||||
- platform: pn532
|
||||
pn532_id: pn532_bs
|
||||
uid: 74-10-37-94
|
||||
name: 'PN532 NFC Tag'
|
||||
- platform: rdm6300
|
||||
@@ -962,14 +1042,14 @@ binary_sensor:
|
||||
- platform: gpio
|
||||
name: 'MCP21 binary sensor'
|
||||
pin:
|
||||
mcp23017: mcp23017_hub
|
||||
mcp23xxx: mcp23017_hub
|
||||
number: 1
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
- platform: gpio
|
||||
name: 'MCP22 binary sensor'
|
||||
pin:
|
||||
mcp23008: mcp23008_hub
|
||||
mcp23xxx: mcp23008_hub
|
||||
number: 7
|
||||
mode: INPUT_PULLUP
|
||||
inverted: False
|
||||
@@ -1126,14 +1206,14 @@ output:
|
||||
- platform: gpio
|
||||
id: id22
|
||||
pin:
|
||||
mcp23017: mcp23017_hub
|
||||
mcp23xxx: mcp23017_hub
|
||||
number: 0
|
||||
mode: OUTPUT
|
||||
inverted: False
|
||||
- platform: gpio
|
||||
id: id23
|
||||
pin:
|
||||
mcp23008: mcp23008_hub
|
||||
mcp23xxx: mcp23008_hub
|
||||
number: 0
|
||||
mode: OUTPUT
|
||||
inverted: False
|
||||
@@ -1173,6 +1253,8 @@ output:
|
||||
- platform: esp32_dac
|
||||
pin: GPIO25
|
||||
id: dac_output
|
||||
- platform: mcp4725
|
||||
id: mcp4725_dac_output
|
||||
|
||||
e131:
|
||||
|
||||
@@ -1220,7 +1302,7 @@ light:
|
||||
state = 0;
|
||||
- platform: rgb
|
||||
name: 'Living Room Lights'
|
||||
id: living_room_lights
|
||||
id: ${roomname}_lights
|
||||
red: pca_0
|
||||
green: pca_1
|
||||
blue: pca_2
|
||||
@@ -1376,14 +1458,14 @@ climate:
|
||||
name: TCL112 Climate With Sensor
|
||||
supports_heat: True
|
||||
supports_cool: True
|
||||
sensor: my_sensor
|
||||
sensor: ${sensorname}_sensor
|
||||
- platform: tcl112
|
||||
name: TCL112 Climate
|
||||
- platform: coolix
|
||||
name: Coolix Climate With Sensor
|
||||
supports_heat: True
|
||||
supports_cool: True
|
||||
sensor: my_sensor
|
||||
sensor: ${sensorname}_sensor
|
||||
- platform: coolix
|
||||
name: Coolix Climate
|
||||
- platform: fujitsu_general
|
||||
@@ -1402,12 +1484,29 @@ climate:
|
||||
name: Toshiba Climate
|
||||
- platform: hitachi_ac344
|
||||
name: Hitachi Climate
|
||||
- platform: midea_ac
|
||||
visual:
|
||||
min_temperature: 18 °C
|
||||
max_temperature: 25 °C
|
||||
temperature_step: 0.1 °C
|
||||
name: "Electrolux EACS"
|
||||
beeper: true
|
||||
outdoor_temperature:
|
||||
name: "Temp"
|
||||
power_usage:
|
||||
name: "Power"
|
||||
humidity_setpoint:
|
||||
name: "Hum"
|
||||
|
||||
midea_dongle:
|
||||
uart_id: uart0
|
||||
strength_icon: true
|
||||
|
||||
switch:
|
||||
- platform: gpio
|
||||
name: 'MCP23S08 Pin #0'
|
||||
pin:
|
||||
mcp23s08: mcp23s08_hub
|
||||
mcp23xxx: mcp23s08_hub
|
||||
# Use pin number 0
|
||||
number: 0
|
||||
mode: OUTPUT
|
||||
@@ -1415,7 +1514,7 @@ switch:
|
||||
- platform: gpio
|
||||
name: 'MCP23S17 Pin #0'
|
||||
pin:
|
||||
mcp23s17: mcp23s17_hub
|
||||
mcp23xxx: mcp23s17_hub
|
||||
# Use pin number 0
|
||||
number: 1
|
||||
mode: OUTPUT
|
||||
@@ -1451,6 +1550,12 @@ switch:
|
||||
turn_on_action:
|
||||
remote_transmitter.transmit_samsung:
|
||||
data: 0xABCDEF
|
||||
- platform: template
|
||||
name: Samsung36
|
||||
turn_on_action:
|
||||
remote_transmitter.transmit_samsung36:
|
||||
address: 0x0400
|
||||
command: 0x000E00FF
|
||||
- platform: template
|
||||
name: Sony
|
||||
turn_on_action:
|
||||
@@ -1542,6 +1647,9 @@ switch:
|
||||
- output.set_level:
|
||||
id: dac_output
|
||||
level: !lambda 'return 0.5;'
|
||||
- output.set_level:
|
||||
id: mcp4725_dac_output
|
||||
level: !lambda 'return 0.5;'
|
||||
turn_off_action:
|
||||
- switch.turn_on: living_room_lights_off
|
||||
restore_state: False
|
||||
@@ -1582,11 +1690,18 @@ switch:
|
||||
id: my_switch
|
||||
state: !lambda 'return false;'
|
||||
- platform: uart
|
||||
uart_id: uart0
|
||||
name: 'UART String Output'
|
||||
data: 'DataToSend'
|
||||
- platform: uart
|
||||
uart_id: uart0
|
||||
name: 'UART Bytes Output'
|
||||
data: [0xDE, 0xAD, 0xBE, 0xEF]
|
||||
- platform: uart
|
||||
uart_id: uart0
|
||||
name: 'UART Recurring Output'
|
||||
data: [0xDE, 0xAD, 0xBE, 0xEF]
|
||||
send_every: 1s
|
||||
- platform: template
|
||||
assumed_state: yes
|
||||
name: Stepper Switch
|
||||
@@ -1620,13 +1735,10 @@ fan:
|
||||
direction_output: gpio_26
|
||||
- platform: speed
|
||||
output: pca_6
|
||||
speed_count: 10
|
||||
name: 'Living Room Fan 2'
|
||||
oscillation_output: gpio_19
|
||||
direction_output: gpio_26
|
||||
speed:
|
||||
low: 0.45
|
||||
medium: 0.75
|
||||
high: 1.0
|
||||
oscillation_state_topic: oscillation/state/topic
|
||||
oscillation_command_topic: oscillation/command/topic
|
||||
speed_state_topic: speed/state/topic
|
||||
@@ -1653,7 +1765,7 @@ interval:
|
||||
color:
|
||||
- id: kbx_red
|
||||
red: 100%
|
||||
green: 1%
|
||||
green_int: 123
|
||||
blue: 2%
|
||||
- id: kbx_blue
|
||||
red: 0%
|
||||
@@ -1690,15 +1802,16 @@ display:
|
||||
it.print("1234");
|
||||
- platform: tm1637
|
||||
clk_pin:
|
||||
mcp23017: mcp23017_hub
|
||||
mcp23xxx: mcp23017_hub
|
||||
number: 1
|
||||
dio_pin:
|
||||
mcp23017: mcp23017_hub
|
||||
mcp23xxx: mcp23017_hub
|
||||
number: 2
|
||||
intensity: 3
|
||||
lambda: |-
|
||||
it.print("1234");
|
||||
- platform: nextion
|
||||
uart_id: uart0
|
||||
lambda: |-
|
||||
it.set_component_value("gauge", 50);
|
||||
it.set_component_text("textview", "Hello World!");
|
||||
@@ -1730,7 +1843,7 @@ display:
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: ssd1322_spi
|
||||
model: "SSD1322 256x64"
|
||||
model: 'SSD1322 256x64'
|
||||
cs_pin: GPIO23
|
||||
dc_pin: GPIO23
|
||||
reset_pin: GPIO23
|
||||
@@ -1776,24 +1889,6 @@ display:
|
||||
reset_pin: GPIO23
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: waveshare_epaper
|
||||
cs_pin: GPIO23
|
||||
dc_pin: GPIO23
|
||||
busy_pin: GPIO23
|
||||
reset_pin: GPIO23
|
||||
model: 2.90in
|
||||
full_update_every: 30
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: waveshare_epaper
|
||||
cs_pin: GPIO23
|
||||
dc_pin: GPIO23
|
||||
busy_pin: GPIO23
|
||||
reset_pin: GPIO23
|
||||
model: 2.90inv2
|
||||
full_update_every: 30
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: st7789v
|
||||
cs_pin: GPIO5
|
||||
dc_pin: GPIO16
|
||||
@@ -1807,10 +1902,10 @@ display:
|
||||
dc_pin: GPIO16
|
||||
reset_pin: GPIO23
|
||||
rotation: 0
|
||||
devicewidth: 128
|
||||
deviceheight: 160
|
||||
colstart: 0
|
||||
rowstart: 0
|
||||
device_width: 128
|
||||
device_height: 160
|
||||
col_start: 0
|
||||
row_start: 0
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
tm1651:
|
||||
@@ -1826,6 +1921,7 @@ status_led:
|
||||
pin: GPIO2
|
||||
|
||||
pn532_spi:
|
||||
id: pn532_bs
|
||||
cs_pin: GPIO23
|
||||
update_interval: 1s
|
||||
on_tag:
|
||||
@@ -1838,6 +1934,7 @@ pn532_spi:
|
||||
pn532_i2c:
|
||||
|
||||
rdm6300:
|
||||
uart_id: uart0
|
||||
|
||||
rc522_spi:
|
||||
cs_pin: GPIO23
|
||||
@@ -1853,6 +1950,7 @@ rc522_i2c:
|
||||
ESP_LOGD("main", "Found tag %s", x.c_str());
|
||||
|
||||
gps:
|
||||
uart_id: uart0
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
@@ -1875,8 +1973,7 @@ time:
|
||||
update_interval: never
|
||||
on_time:
|
||||
seconds: 0
|
||||
then:
|
||||
ds1307.read_time
|
||||
then: ds1307.read_time
|
||||
|
||||
cover:
|
||||
- platform: template
|
||||
@@ -1950,10 +2047,10 @@ text_sensor:
|
||||
qos: 2
|
||||
on_value:
|
||||
- text_sensor.template.publish:
|
||||
id: template_text
|
||||
id: ${textname}_text
|
||||
state: Hello World
|
||||
- text_sensor.template.publish:
|
||||
id: template_text
|
||||
id: ${textname}_text
|
||||
state: |-
|
||||
return "Hello World2";
|
||||
- globals.set:
|
||||
@@ -1964,7 +2061,7 @@ text_sensor:
|
||||
data: [0x10, 0x20, 0x30]
|
||||
- platform: template
|
||||
name: Template Text Sensor
|
||||
id: template_text
|
||||
id: ${textname}_text
|
||||
- platform: wifi_info
|
||||
ip_address:
|
||||
name: 'IP Address'
|
||||
@@ -2006,4 +2103,4 @@ canbus:
|
||||
condition:
|
||||
lambda: 'return x[0] == 0x11;'
|
||||
then:
|
||||
light.toggle: living_room_lights
|
||||
light.toggle: ${roomname}_lights
|
||||
|
@@ -45,6 +45,12 @@ ota:
|
||||
logger:
|
||||
level: DEBUG
|
||||
|
||||
deep_sleep:
|
||||
run_duration: 20s
|
||||
sleep_duration: 50s
|
||||
wakeup_pin: GPIO39
|
||||
wakeup_pin_mode: INVERT_WAKEUP
|
||||
|
||||
as3935_i2c:
|
||||
irq_pin: GPIO12
|
||||
|
||||
@@ -64,6 +70,18 @@ sensor:
|
||||
- platform: ble_rssi
|
||||
service_uuid: '11223344-5566-7788-99aa-bbccddeeff00'
|
||||
name: 'BLE Test Service 128'
|
||||
- platform: senseair
|
||||
id: senseair0
|
||||
co2:
|
||||
name: 'SenseAir CO2 Value'
|
||||
on_value:
|
||||
then:
|
||||
- senseair.background_calibration: senseair0
|
||||
- senseair.background_calibration_result: senseair0
|
||||
- senseair.abc_get_period: senseair0
|
||||
- senseair.abc_enable: senseair0
|
||||
- senseair.abc_disable: senseair0
|
||||
update_interval: 15s
|
||||
- platform: ruuvitag
|
||||
mac_address: FF:56:D3:2F:7D:E8
|
||||
humidity:
|
||||
@@ -181,6 +199,14 @@ sensor:
|
||||
name: 'ATC Battery-Level'
|
||||
battery_voltage:
|
||||
name: 'ATC Battery-Voltage'
|
||||
- platform: inkbird_ibsth1_mini
|
||||
mac_address: 38:81:D7:0A:9C:11
|
||||
temperature:
|
||||
name: 'Inkbird IBS-TH1 Temperature'
|
||||
humidity:
|
||||
name: 'Inkbird IBS-TH1 Humidity'
|
||||
battery_level:
|
||||
name: 'Inkbird IBS-TH1 Battery Level'
|
||||
|
||||
time:
|
||||
- platform: homeassistant
|
||||
@@ -294,6 +320,8 @@ text_sensor:
|
||||
- homeassistant.tag_scanned:
|
||||
tag: 1234-abcd
|
||||
- homeassistant.tag_scanned: 1234-abcd
|
||||
- deep_sleep.enter:
|
||||
sleep_duration: 30min
|
||||
- platform: template
|
||||
name: 'Template Text Sensor'
|
||||
lambda: |-
|
||||
|
@@ -197,10 +197,6 @@ uart:
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 115200
|
||||
|
||||
- id: adalight_uart
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 115200
|
||||
|
||||
ota:
|
||||
safe_mode: True
|
||||
port: 3286
|
||||
@@ -229,6 +225,8 @@ sensor:
|
||||
name: 'VL53L0x Distance'
|
||||
address: 0x29
|
||||
update_interval: 60s
|
||||
enable_pin: GPIO13
|
||||
timeout: 200us
|
||||
- platform: apds9960
|
||||
type: clear
|
||||
name: APDS9960 Clear
|
||||
@@ -558,14 +556,14 @@ switch:
|
||||
- platform: gpio
|
||||
id: gpio_switch1
|
||||
pin:
|
||||
mcp23017: mcp23017_hub
|
||||
mcp23xxx: mcp23017_hub
|
||||
number: 0
|
||||
mode: OUTPUT
|
||||
interlock: &interlock [gpio_switch1, gpio_switch2, gpio_switch3]
|
||||
- platform: gpio
|
||||
id: gpio_switch2
|
||||
pin:
|
||||
mcp23008: mcp23008_hub
|
||||
mcp23xxx: mcp23008_hub
|
||||
number: 0
|
||||
mode: OUTPUT
|
||||
interlock: *interlock
|
||||
@@ -812,7 +810,6 @@ light:
|
||||
effects:
|
||||
- wled:
|
||||
- adalight:
|
||||
uart_id: adalight_uart
|
||||
- e131:
|
||||
universe: 1
|
||||
- platform: hbridge
|
||||
@@ -842,6 +839,8 @@ sim800l:
|
||||
- sim800l.send_sms:
|
||||
message: 'hello you'
|
||||
recipient: '+1234'
|
||||
- sim800l.dial:
|
||||
recipient: '+1234'
|
||||
|
||||
dfplayer:
|
||||
on_finished_playback:
|
||||
@@ -886,6 +885,25 @@ rf_bridge:
|
||||
code: 'ABC123'
|
||||
- rf_bridge.send_raw:
|
||||
raw: 'AAA5070008001000ABC12355'
|
||||
- http_request.get:
|
||||
url: https://esphome.io
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
verify_ssl: false
|
||||
- http_request.post:
|
||||
url: https://esphome.io
|
||||
verify_ssl: false
|
||||
json:
|
||||
key: !lambda |-
|
||||
return id(version_sensor).state;
|
||||
greeting: 'Hello World'
|
||||
- http_request.send:
|
||||
method: PUT
|
||||
url: https://esphome.io
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
body: 'Some data'
|
||||
verify_ssl: false
|
||||
|
||||
display:
|
||||
- platform: max7219digit
|
||||
@@ -897,3 +915,7 @@ display:
|
||||
id: my_matrix
|
||||
lambda: |-
|
||||
it.printdigit("hello");
|
||||
|
||||
http_request:
|
||||
useragent: esphome/device
|
||||
timeout: 10s
|
||||
|
@@ -99,3 +99,64 @@ switch:
|
||||
- platform: tuya
|
||||
id: tuya_switch
|
||||
switch_datapoint: 1
|
||||
|
||||
light:
|
||||
- platform: fastled_clockless
|
||||
id: led_matrix_32x8
|
||||
name: "led_matrix_32x8"
|
||||
chipset: WS2812B
|
||||
pin: GPIO15
|
||||
num_leds: 256
|
||||
rgb_order: GRB
|
||||
default_transition_length: 0s
|
||||
color_correct: [50%, 50%, 50%]
|
||||
|
||||
display:
|
||||
- platform: addressable_light
|
||||
id: led_matrix_32x8_display
|
||||
addressable_light_id: led_matrix_32x8
|
||||
width: 32
|
||||
height: 8
|
||||
pixel_mapper: |-
|
||||
if (x % 2 == 0) {
|
||||
return (x * 8) + y;
|
||||
}
|
||||
return (x * 8) + (7 - y);
|
||||
lambda: |-
|
||||
Color red = Color(0xFF0000);
|
||||
Color green = Color(0x00FF00);
|
||||
Color blue = Color(0x0000FF);
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height(), red);
|
||||
it.rectangle(1, 1, it.get_width()-2, it.get_height()-2, green);
|
||||
it.rectangle(2, 2, it.get_width()-4, it.get_height()-4, blue);
|
||||
it.rectangle(3, 3, it.get_width()-6, it.get_height()-6, red);
|
||||
rotation: 0°
|
||||
update_interval: 16ms
|
||||
- platform: waveshare_epaper
|
||||
cs_pin: GPIO23
|
||||
dc_pin: GPIO23
|
||||
busy_pin: GPIO23
|
||||
reset_pin: GPIO23
|
||||
model: 2.13in-ttgo-b1
|
||||
full_update_every: 30
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: waveshare_epaper
|
||||
cs_pin: GPIO23
|
||||
dc_pin: GPIO23
|
||||
busy_pin: GPIO23
|
||||
reset_pin: GPIO23
|
||||
model: 2.90in
|
||||
full_update_every: 30
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
- platform: waveshare_epaper
|
||||
cs_pin: GPIO23
|
||||
dc_pin: GPIO23
|
||||
busy_pin: GPIO23
|
||||
reset_pin: GPIO23
|
||||
model: 2.90inv2
|
||||
full_update_every: 30
|
||||
lambda: |-
|
||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||
|
||||
|
@@ -27,4 +27,3 @@ def fixture_path() -> Path:
|
||||
Location of all fixture files.
|
||||
"""
|
||||
return here / "fixtures"
|
||||
|
||||
|
@@ -12,4 +12,6 @@ def mac_addr_strings():
|
||||
This consists of six strings representing integers [0..255],
|
||||
without zero-padding, joined by dots.
|
||||
"""
|
||||
return st.builds("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}".format, *(6 * [st.integers(0, 255)]))
|
||||
return st.builds(
|
||||
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}".format, *(6 * [st.integers(0, 255)])
|
||||
)
|
||||
|
@@ -4,23 +4,75 @@ from esphome import codegen as cg
|
||||
|
||||
|
||||
# Test interface remains the same.
|
||||
@pytest.mark.parametrize("attr", (
|
||||
# from cpp_generator
|
||||
"Expression", "RawExpression", "RawStatement", "TemplateArguments",
|
||||
"StructInitializer", "ArrayInitializer", "safe_exp", "Statement", "LineComment",
|
||||
"progmem_array", "statement", "variable", "Pvariable", "new_Pvariable",
|
||||
"add", "add_global", "add_library", "add_build_flag", "add_define",
|
||||
"get_variable", "get_variable_with_full_id", "process_lambda", "is_template", "templatable", "MockObj",
|
||||
"MockObjClass",
|
||||
# from cpp_helpers
|
||||
"gpio_pin_expression", "register_component", "build_registry_entry",
|
||||
"build_registry_list", "extract_registry_entry_config", "register_parented",
|
||||
"global_ns", "void", "nullptr", "float_", "double", "bool_", "int_", "std_ns", "std_string",
|
||||
"std_vector", "uint8", "uint16", "uint32", "int32", "const_char_ptr", "NAN",
|
||||
"esphome_ns", "App", "Nameable", "Component", "ComponentPtr",
|
||||
# from cpp_types
|
||||
"PollingComponent", "Application", "optional", "arduino_json_ns", "JsonObject",
|
||||
"JsonObjectRef", "JsonObjectConstRef", "Controller", "GPIOPin"
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"attr",
|
||||
(
|
||||
# from cpp_generator
|
||||
"Expression",
|
||||
"RawExpression",
|
||||
"RawStatement",
|
||||
"TemplateArguments",
|
||||
"StructInitializer",
|
||||
"ArrayInitializer",
|
||||
"safe_exp",
|
||||
"Statement",
|
||||
"LineComment",
|
||||
"progmem_array",
|
||||
"statement",
|
||||
"variable",
|
||||
"Pvariable",
|
||||
"new_Pvariable",
|
||||
"add",
|
||||
"add_global",
|
||||
"add_library",
|
||||
"add_build_flag",
|
||||
"add_define",
|
||||
"get_variable",
|
||||
"get_variable_with_full_id",
|
||||
"process_lambda",
|
||||
"is_template",
|
||||
"templatable",
|
||||
"MockObj",
|
||||
"MockObjClass",
|
||||
# from cpp_helpers
|
||||
"gpio_pin_expression",
|
||||
"register_component",
|
||||
"build_registry_entry",
|
||||
"build_registry_list",
|
||||
"extract_registry_entry_config",
|
||||
"register_parented",
|
||||
"global_ns",
|
||||
"void",
|
||||
"nullptr",
|
||||
"float_",
|
||||
"double",
|
||||
"bool_",
|
||||
"int_",
|
||||
"std_ns",
|
||||
"std_string",
|
||||
"std_vector",
|
||||
"uint8",
|
||||
"uint16",
|
||||
"uint32",
|
||||
"int32",
|
||||
"const_char_ptr",
|
||||
"NAN",
|
||||
"esphome_ns",
|
||||
"App",
|
||||
"Nameable",
|
||||
"Component",
|
||||
"ComponentPtr",
|
||||
# from cpp_types
|
||||
"PollingComponent",
|
||||
"Application",
|
||||
"optional",
|
||||
"arduino_json_ns",
|
||||
"JsonObject",
|
||||
"JsonObjectRef",
|
||||
"JsonObjectConstRef",
|
||||
"Controller",
|
||||
"GPIOPin",
|
||||
),
|
||||
)
|
||||
def test_exists(attr):
|
||||
assert hasattr(cg, attr)
|
||||
|
@@ -2,7 +2,7 @@ import pytest
|
||||
import string
|
||||
|
||||
from hypothesis import given, example
|
||||
from hypothesis.strategies import one_of, text, integers, booleans, builds
|
||||
from hypothesis.strategies import one_of, text, integers, builds
|
||||
|
||||
from esphome import config_validation
|
||||
from esphome.config_validation import Invalid
|
||||
@@ -24,7 +24,7 @@ def test_alphanumeric__valid(value):
|
||||
@pytest.mark.parametrize("value", ("£23", "Foo!"))
|
||||
def test_alphanumeric__invalid(value):
|
||||
with pytest.raises(Invalid):
|
||||
actual = config_validation.alphanumeric(value)
|
||||
config_validation.alphanumeric(value)
|
||||
|
||||
|
||||
@given(value=text(alphabet=string.ascii_lowercase + string.digits + "_-"))
|
||||
@@ -34,9 +34,7 @@ def test_valid_name__valid(value):
|
||||
assert actual == value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
"foo bar", "FooBar", "foo::bar"
|
||||
))
|
||||
@pytest.mark.parametrize("value", ("foo bar", "FooBar", "foo::bar"))
|
||||
def test_valid_name__invalid(value):
|
||||
with pytest.raises(Invalid):
|
||||
config_validation.valid_name(value)
|
||||
@@ -49,9 +47,7 @@ def test_string__valid(value):
|
||||
assert actual == str(value)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
{}, [], True, False, None
|
||||
))
|
||||
@pytest.mark.parametrize("value", ({}, [], True, False, None))
|
||||
def test_string__invalid(value):
|
||||
with pytest.raises(Invalid):
|
||||
config_validation.string(value)
|
||||
@@ -83,23 +79,17 @@ def test_icon__invalid():
|
||||
config_validation.icon("foo")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
"True", "YES", "on", "enAblE", True
|
||||
))
|
||||
@pytest.mark.parametrize("value", ("True", "YES", "on", "enAblE", True))
|
||||
def test_boolean__valid_true(value):
|
||||
assert config_validation.boolean(value) is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
"False", "NO", "off", "disAblE", False
|
||||
))
|
||||
@pytest.mark.parametrize("value", ("False", "NO", "off", "disAblE", False))
|
||||
def test_boolean__valid_false(value):
|
||||
assert config_validation.boolean(value) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
None, 1, 0, "foo"
|
||||
))
|
||||
@pytest.mark.parametrize("value", (None, 1, 0, "foo"))
|
||||
def test_boolean__invalid(value):
|
||||
with pytest.raises(Invalid, match="Expected boolean value"):
|
||||
config_validation.boolean(value)
|
||||
|
@@ -8,13 +8,16 @@ from esphome import core, const
|
||||
|
||||
|
||||
class TestHexInt:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
(1, "0x01"),
|
||||
(255, "0xFF"),
|
||||
(128, "0x80"),
|
||||
(256, "0x100"),
|
||||
(-1, "-0x01"), # TODO: this currently fails
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
(1, "0x01"),
|
||||
(255, "0xFF"),
|
||||
(128, "0x80"),
|
||||
(256, "0x100"),
|
||||
(-1, "-0x01"), # TODO: this currently fails
|
||||
),
|
||||
)
|
||||
def test_str(self, value, expected):
|
||||
target = core.HexInt(value)
|
||||
|
||||
@@ -68,18 +71,14 @@ class TestMACAddress:
|
||||
assert actual.text == "0xDEADBEEF00FFULL"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
1, 2, -1, 0, 1.0, -1.0, 42.0009, -42.0009
|
||||
))
|
||||
@pytest.mark.parametrize("value", (1, 2, -1, 0, 1.0, -1.0, 42.0009, -42.0009))
|
||||
def test_is_approximately_integer__in_range(value):
|
||||
actual = core.is_approximately_integer(value)
|
||||
|
||||
assert actual is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", (
|
||||
42.01, -42.01, 1.5
|
||||
))
|
||||
@pytest.mark.parametrize("value", (42.01, -42.01, 1.5))
|
||||
def test_is_approximately_integer__not_in_range(value):
|
||||
actual = core.is_approximately_integer(value)
|
||||
|
||||
@@ -87,26 +86,29 @@ def test_is_approximately_integer__not_in_range(value):
|
||||
|
||||
|
||||
class TestTimePeriod:
|
||||
@pytest.mark.parametrize("kwargs, expected", (
|
||||
({}, {}),
|
||||
({"microseconds": 1}, {"microseconds": 1}),
|
||||
({"microseconds": 1.0001}, {"microseconds": 1}),
|
||||
({"milliseconds": 2}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.0001}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.01}, {"milliseconds": 2, "microseconds": 10}),
|
||||
({"seconds": 3}, {"seconds": 3}),
|
||||
({"seconds": 3.0001}, {"seconds": 3}),
|
||||
({"seconds": 3.01}, {"seconds": 3, "milliseconds": 10}),
|
||||
({"minutes": 4}, {"minutes": 4}),
|
||||
({"minutes": 4.0001}, {"minutes": 4}),
|
||||
({"minutes": 4.1}, {"minutes": 4, "seconds": 6}),
|
||||
({"hours": 5}, {"hours": 5}),
|
||||
({"hours": 5.0001}, {"hours": 5}),
|
||||
({"hours": 5.1}, {"hours": 5, "minutes": 6}),
|
||||
({"days": 6}, {"days": 6}),
|
||||
({"days": 6.0001}, {"days": 6}),
|
||||
({"days": 6.1}, {"days": 6, "hours": 2, "minutes": 24}),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"kwargs, expected",
|
||||
(
|
||||
({}, {}),
|
||||
({"microseconds": 1}, {"microseconds": 1}),
|
||||
({"microseconds": 1.0001}, {"microseconds": 1}),
|
||||
({"milliseconds": 2}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.0001}, {"milliseconds": 2}),
|
||||
({"milliseconds": 2.01}, {"milliseconds": 2, "microseconds": 10}),
|
||||
({"seconds": 3}, {"seconds": 3}),
|
||||
({"seconds": 3.0001}, {"seconds": 3}),
|
||||
({"seconds": 3.01}, {"seconds": 3, "milliseconds": 10}),
|
||||
({"minutes": 4}, {"minutes": 4}),
|
||||
({"minutes": 4.0001}, {"minutes": 4}),
|
||||
({"minutes": 4.1}, {"minutes": 4, "seconds": 6}),
|
||||
({"hours": 5}, {"hours": 5}),
|
||||
({"hours": 5.0001}, {"hours": 5}),
|
||||
({"hours": 5.1}, {"hours": 5, "minutes": 6}),
|
||||
({"days": 6}, {"days": 6}),
|
||||
({"days": 6.0001}, {"days": 6}),
|
||||
({"days": 6.1}, {"days": 6, "hours": 2, "minutes": 24}),
|
||||
),
|
||||
)
|
||||
def test_init(self, kwargs, expected):
|
||||
target = core.TimePeriod(**kwargs)
|
||||
|
||||
@@ -118,26 +120,29 @@ class TestTimePeriod:
|
||||
with pytest.raises(ValueError, match="Maximum precision is microseconds"):
|
||||
core.TimePeriod(microseconds=1.1)
|
||||
|
||||
@pytest.mark.parametrize("kwargs, expected", (
|
||||
({}, "0s"),
|
||||
({"microseconds": 1}, "1us"),
|
||||
({"microseconds": 1.0001}, "1us"),
|
||||
({"milliseconds": 2}, "2ms"),
|
||||
({"milliseconds": 2.0001}, "2ms"),
|
||||
({"milliseconds": 2.01}, "2010us"),
|
||||
({"seconds": 3}, "3s"),
|
||||
({"seconds": 3.0001}, "3s"),
|
||||
({"seconds": 3.01}, "3010ms"),
|
||||
({"minutes": 4}, "4min"),
|
||||
({"minutes": 4.0001}, "4min"),
|
||||
({"minutes": 4.1}, "246s"),
|
||||
({"hours": 5}, "5h"),
|
||||
({"hours": 5.0001}, "5h"),
|
||||
({"hours": 5.1}, "306min"),
|
||||
({"days": 6}, "6d"),
|
||||
({"days": 6.0001}, "6d"),
|
||||
({"days": 6.1}, "8784min"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"kwargs, expected",
|
||||
(
|
||||
({}, "0s"),
|
||||
({"microseconds": 1}, "1us"),
|
||||
({"microseconds": 1.0001}, "1us"),
|
||||
({"milliseconds": 2}, "2ms"),
|
||||
({"milliseconds": 2.0001}, "2ms"),
|
||||
({"milliseconds": 2.01}, "2010us"),
|
||||
({"seconds": 3}, "3s"),
|
||||
({"seconds": 3.0001}, "3s"),
|
||||
({"seconds": 3.01}, "3010ms"),
|
||||
({"minutes": 4}, "4min"),
|
||||
({"minutes": 4.0001}, "4min"),
|
||||
({"minutes": 4.1}, "246s"),
|
||||
({"hours": 5}, "5h"),
|
||||
({"hours": 5.0001}, "5h"),
|
||||
({"hours": 5.1}, "306min"),
|
||||
({"days": 6}, "6d"),
|
||||
({"days": 6.0001}, "6d"),
|
||||
({"days": 6.1}, "8784min"),
|
||||
),
|
||||
)
|
||||
def test_str(self, kwargs, expected):
|
||||
target = core.TimePeriod(**kwargs)
|
||||
|
||||
@@ -145,61 +150,59 @@ class TestTimePeriod:
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.TimePeriod(microseconds=900), False),
|
||||
("__eq__", core.TimePeriod(milliseconds=1), True),
|
||||
("__eq__", core.TimePeriod(microseconds=1100), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
|
||||
("__ne__", core.TimePeriod(microseconds=900), True),
|
||||
("__ne__", core.TimePeriod(milliseconds=1), False),
|
||||
("__ne__", core.TimePeriod(microseconds=1100), True),
|
||||
("__ne__", 1000, NotImplemented),
|
||||
("__ne__", "1000", NotImplemented),
|
||||
("__ne__", True, NotImplemented),
|
||||
("__ne__", object(), NotImplemented),
|
||||
("__ne__", None, NotImplemented),
|
||||
|
||||
("__lt__", core.TimePeriod(microseconds=900), False),
|
||||
("__lt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__lt__", core.TimePeriod(microseconds=1100), True),
|
||||
("__lt__", 1000, NotImplemented),
|
||||
("__lt__", "1000", NotImplemented),
|
||||
("__lt__", True, NotImplemented),
|
||||
("__lt__", object(), NotImplemented),
|
||||
("__lt__", None, NotImplemented),
|
||||
|
||||
("__gt__", core.TimePeriod(microseconds=900), True),
|
||||
("__gt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__gt__", core.TimePeriod(microseconds=1100), False),
|
||||
("__gt__", 1000, NotImplemented),
|
||||
("__gt__", "1000", NotImplemented),
|
||||
("__gt__", True, NotImplemented),
|
||||
("__gt__", object(), NotImplemented),
|
||||
("__gt__", None, NotImplemented),
|
||||
|
||||
("__le__", core.TimePeriod(microseconds=900), False),
|
||||
("__le__", core.TimePeriod(milliseconds=1), True),
|
||||
("__le__", core.TimePeriod(microseconds=1100), True),
|
||||
("__le__", 1000, NotImplemented),
|
||||
("__le__", "1000", NotImplemented),
|
||||
("__le__", True, NotImplemented),
|
||||
("__le__", object(), NotImplemented),
|
||||
("__le__", None, NotImplemented),
|
||||
|
||||
("__ge__", core.TimePeriod(microseconds=900), True),
|
||||
("__ge__", core.TimePeriod(milliseconds=1), True),
|
||||
("__ge__", core.TimePeriod(microseconds=1100), False),
|
||||
("__ge__", 1000, NotImplemented),
|
||||
("__ge__", "1000", NotImplemented),
|
||||
("__ge__", True, NotImplemented),
|
||||
("__ge__", object(), NotImplemented),
|
||||
("__ge__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.TimePeriod(microseconds=900), False),
|
||||
("__eq__", core.TimePeriod(milliseconds=1), True),
|
||||
("__eq__", core.TimePeriod(microseconds=1100), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
("__ne__", core.TimePeriod(microseconds=900), True),
|
||||
("__ne__", core.TimePeriod(milliseconds=1), False),
|
||||
("__ne__", core.TimePeriod(microseconds=1100), True),
|
||||
("__ne__", 1000, NotImplemented),
|
||||
("__ne__", "1000", NotImplemented),
|
||||
("__ne__", True, NotImplemented),
|
||||
("__ne__", object(), NotImplemented),
|
||||
("__ne__", None, NotImplemented),
|
||||
("__lt__", core.TimePeriod(microseconds=900), False),
|
||||
("__lt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__lt__", core.TimePeriod(microseconds=1100), True),
|
||||
("__lt__", 1000, NotImplemented),
|
||||
("__lt__", "1000", NotImplemented),
|
||||
("__lt__", True, NotImplemented),
|
||||
("__lt__", object(), NotImplemented),
|
||||
("__lt__", None, NotImplemented),
|
||||
("__gt__", core.TimePeriod(microseconds=900), True),
|
||||
("__gt__", core.TimePeriod(milliseconds=1), False),
|
||||
("__gt__", core.TimePeriod(microseconds=1100), False),
|
||||
("__gt__", 1000, NotImplemented),
|
||||
("__gt__", "1000", NotImplemented),
|
||||
("__gt__", True, NotImplemented),
|
||||
("__gt__", object(), NotImplemented),
|
||||
("__gt__", None, NotImplemented),
|
||||
("__le__", core.TimePeriod(microseconds=900), False),
|
||||
("__le__", core.TimePeriod(milliseconds=1), True),
|
||||
("__le__", core.TimePeriod(microseconds=1100), True),
|
||||
("__le__", 1000, NotImplemented),
|
||||
("__le__", "1000", NotImplemented),
|
||||
("__le__", True, NotImplemented),
|
||||
("__le__", object(), NotImplemented),
|
||||
("__le__", None, NotImplemented),
|
||||
("__ge__", core.TimePeriod(microseconds=900), True),
|
||||
("__ge__", core.TimePeriod(milliseconds=1), True),
|
||||
("__ge__", core.TimePeriod(microseconds=1100), False),
|
||||
("__ge__", 1000, NotImplemented),
|
||||
("__ge__", "1000", NotImplemented),
|
||||
("__ge__", True, NotImplemented),
|
||||
("__ge__", object(), NotImplemented),
|
||||
("__ge__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.TimePeriod(microseconds=1000)
|
||||
|
||||
@@ -238,19 +241,19 @@ class TestLambda:
|
||||
"it.strftime(64, 0, ",
|
||||
"my_font",
|
||||
"",
|
||||
", TextAlign::TOP_CENTER, \"%H:%M:%S\", ",
|
||||
', TextAlign::TOP_CENTER, "%H:%M:%S", ',
|
||||
"esptime",
|
||||
".",
|
||||
"now());\nit.printf(64, 16, ",
|
||||
"my_font2",
|
||||
"",
|
||||
", TextAlign::TOP_CENTER, \"%.1f°C (%.1f%%)\", ",
|
||||
', TextAlign::TOP_CENTER, "%.1f°C (%.1f%%)", ',
|
||||
"office_tmp",
|
||||
".",
|
||||
"state, ",
|
||||
"office_hmd",
|
||||
".",
|
||||
"state);\n \nint x = 4; "
|
||||
"state);\n \nint x = 4; ",
|
||||
]
|
||||
|
||||
def test_requires_ids(self):
|
||||
@@ -296,24 +299,33 @@ class TestID:
|
||||
def target(self):
|
||||
return core.ID(None, is_declaration=True, type="binary_sensor::Example")
|
||||
|
||||
@pytest.mark.parametrize("id, is_manual, expected", (
|
||||
("foo", None, True),
|
||||
(None, None, False),
|
||||
("foo", True, True),
|
||||
("foo", False, False),
|
||||
(None, True, True),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"id, is_manual, expected",
|
||||
(
|
||||
("foo", None, True),
|
||||
(None, None, False),
|
||||
("foo", True, True),
|
||||
("foo", False, False),
|
||||
(None, True, True),
|
||||
),
|
||||
)
|
||||
def test_init__resolve_is_manual(self, id, is_manual, expected):
|
||||
target = core.ID(id, is_manual=is_manual)
|
||||
|
||||
assert target.is_manual == expected
|
||||
|
||||
@pytest.mark.parametrize("registered_ids, expected", (
|
||||
([], "binary_sensor_example"),
|
||||
(["binary_sensor_example"], "binary_sensor_example_2"),
|
||||
(["foo"], "binary_sensor_example"),
|
||||
(["binary_sensor_example", "foo", "binary_sensor_example_2"], "binary_sensor_example_3"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"registered_ids, expected",
|
||||
(
|
||||
([], "binary_sensor_example"),
|
||||
(["binary_sensor_example"], "binary_sensor_example_2"),
|
||||
(["foo"], "binary_sensor_example"),
|
||||
(
|
||||
["binary_sensor_example", "foo", "binary_sensor_example_2"],
|
||||
"binary_sensor_example_3",
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_resolve(self, target, registered_ids, expected):
|
||||
actual = target.resolve(registered_ids)
|
||||
|
||||
@@ -326,18 +338,23 @@ class TestID:
|
||||
actual = target.copy()
|
||||
|
||||
assert actual is not target
|
||||
assert all(getattr(actual, n) == getattr(target, n)
|
||||
for n in ("id", "is_declaration", "type", "is_manual"))
|
||||
assert all(
|
||||
getattr(actual, n) == getattr(target, n)
|
||||
for n in ("id", "is_declaration", "type", "is_manual")
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.ID(id="foo"), True),
|
||||
("__eq__", core.ID(id="bar"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.ID(id="foo"), True),
|
||||
("__eq__", core.ID(id="bar"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.ID(id="foo")
|
||||
|
||||
@@ -384,14 +401,17 @@ class TestDocumentRange:
|
||||
|
||||
|
||||
class TestDefine:
|
||||
@pytest.mark.parametrize("name, value, prop, expected", (
|
||||
("ANSWER", None, "as_build_flag", "-DANSWER"),
|
||||
("ANSWER", None, "as_macro", "#define ANSWER"),
|
||||
("ANSWER", None, "as_tuple", ("ANSWER", None)),
|
||||
("ANSWER", 42, "as_build_flag", "-DANSWER=42"),
|
||||
("ANSWER", 42, "as_macro", "#define ANSWER 42"),
|
||||
("ANSWER", 42, "as_tuple", ("ANSWER", 42)),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"name, value, prop, expected",
|
||||
(
|
||||
("ANSWER", None, "as_build_flag", "-DANSWER"),
|
||||
("ANSWER", None, "as_macro", "#define ANSWER"),
|
||||
("ANSWER", None, "as_tuple", ("ANSWER", None)),
|
||||
("ANSWER", 42, "as_build_flag", "-DANSWER=42"),
|
||||
("ANSWER", 42, "as_macro", "#define ANSWER 42"),
|
||||
("ANSWER", 42, "as_tuple", ("ANSWER", 42)),
|
||||
),
|
||||
)
|
||||
def test_properties(self, name, value, prop, expected):
|
||||
target = core.Define(name, value)
|
||||
|
||||
@@ -399,18 +419,21 @@ class TestDefine:
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.Define(name="FOO", value=42), True),
|
||||
("__eq__", core.Define(name="FOO", value=13), False),
|
||||
("__eq__", core.Define(name="FOO"), False),
|
||||
("__eq__", core.Define(name="BAR", value=42), False),
|
||||
("__eq__", core.Define(name="BAR"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.Define(name="FOO", value=42), True),
|
||||
("__eq__", core.Define(name="FOO", value=13), False),
|
||||
("__eq__", core.Define(name="FOO"), False),
|
||||
("__eq__", core.Define(name="BAR", value=42), False),
|
||||
("__eq__", core.Define(name="BAR"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.Define(name="FOO", value=42)
|
||||
|
||||
@@ -420,12 +443,15 @@ class TestDefine:
|
||||
|
||||
|
||||
class TestLibrary:
|
||||
@pytest.mark.parametrize("name, value, prop, expected", (
|
||||
("mylib", None, "as_lib_dep", "mylib"),
|
||||
("mylib", None, "as_tuple", ("mylib", None)),
|
||||
("mylib", "1.2.3", "as_lib_dep", "mylib@1.2.3"),
|
||||
("mylib", "1.2.3", "as_tuple", ("mylib", "1.2.3")),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"name, value, prop, expected",
|
||||
(
|
||||
("mylib", None, "as_lib_dep", "mylib"),
|
||||
("mylib", None, "as_tuple", ("mylib", None)),
|
||||
("mylib", "1.2.3", "as_lib_dep", "mylib@1.2.3"),
|
||||
("mylib", "1.2.3", "as_tuple", ("mylib", "1.2.3")),
|
||||
),
|
||||
)
|
||||
def test_properties(self, name, value, prop, expected):
|
||||
target = core.Library(name, value)
|
||||
|
||||
@@ -433,16 +459,19 @@ class TestLibrary:
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("comparison, other, expected", (
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.3"), True),
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.4"), False),
|
||||
("__eq__", core.Library(name="libbar", version="1.2.3"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"comparison, other, expected",
|
||||
(
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.3"), True),
|
||||
("__eq__", core.Library(name="libfoo", version="1.2.4"), False),
|
||||
("__eq__", core.Library(name="libbar", version="1.2.3"), False),
|
||||
("__eq__", 1000, NotImplemented),
|
||||
("__eq__", "1000", NotImplemented),
|
||||
("__eq__", True, NotImplemented),
|
||||
("__eq__", object(), NotImplemented),
|
||||
("__eq__", None, NotImplemented),
|
||||
),
|
||||
)
|
||||
def test_comparison(self, comparison, other, expected):
|
||||
target = core.Library(name="libfoo", version="1.2.3")
|
||||
|
||||
|
@@ -9,18 +9,18 @@ from esphome import cpp_types as ct
|
||||
|
||||
|
||||
class TestExpressions:
|
||||
@pytest.mark.parametrize("target, expected", (
|
||||
(cg.RawExpression("foo && bar"), "foo && bar"),
|
||||
|
||||
(cg.AssignmentExpression(None, None, "foo", "bar", None), 'foo = "bar"'),
|
||||
(cg.AssignmentExpression(ct.float_, "*", "foo", 1, None), 'float *foo = 1'),
|
||||
(cg.AssignmentExpression(ct.float_, "", "foo", 1, None), 'float foo = 1'),
|
||||
|
||||
(cg.VariableDeclarationExpression(ct.int32, "*", "foo"), "int32_t *foo"),
|
||||
(cg.VariableDeclarationExpression(ct.int32, "", "foo"), "int32_t foo"),
|
||||
|
||||
(cg.ParameterExpression(ct.std_string, "foo"), "std::string foo"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"target, expected",
|
||||
(
|
||||
(cg.RawExpression("foo && bar"), "foo && bar"),
|
||||
(cg.AssignmentExpression(None, None, "foo", "bar", None), 'foo = "bar"'),
|
||||
(cg.AssignmentExpression(ct.float_, "*", "foo", 1, None), "float *foo = 1"),
|
||||
(cg.AssignmentExpression(ct.float_, "", "foo", 1, None), "float foo = 1"),
|
||||
(cg.VariableDeclarationExpression(ct.int32, "*", "foo"), "int32_t *foo"),
|
||||
(cg.VariableDeclarationExpression(ct.int32, "", "foo"), "int32_t foo"),
|
||||
(cg.ParameterExpression(ct.std_string, "foo"), "std::string foo"),
|
||||
),
|
||||
)
|
||||
def test_str__simple(self, target: cg.Expression, expected: str):
|
||||
actual = str(target)
|
||||
|
||||
@@ -67,10 +67,7 @@ class TestTemplateArguments:
|
||||
|
||||
class TestCallExpression:
|
||||
def test_str__no_template_args(self):
|
||||
target = cg.CallExpression(
|
||||
cg.RawExpression("my_function"),
|
||||
1, "2", False
|
||||
)
|
||||
target = cg.CallExpression(cg.RawExpression("my_function"), 1, "2", False)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
@@ -80,7 +77,9 @@ class TestCallExpression:
|
||||
target = cg.CallExpression(
|
||||
cg.RawExpression("my_function"),
|
||||
cg.TemplateArguments(int, float),
|
||||
1, "2", False
|
||||
1,
|
||||
"2",
|
||||
False,
|
||||
)
|
||||
|
||||
actual = str(target)
|
||||
@@ -100,36 +99,32 @@ class TestStructInitializer:
|
||||
|
||||
actual = str(target)
|
||||
|
||||
assert actual == 'foo::MyStruct{\n' \
|
||||
' .state = "on",\n' \
|
||||
' .min_length = 1,\n' \
|
||||
' .max_length = 5,\n' \
|
||||
'}'
|
||||
assert (
|
||||
actual == "foo::MyStruct{\n"
|
||||
' .state = "on",\n'
|
||||
" .min_length = 1,\n"
|
||||
" .max_length = 5,\n"
|
||||
"}"
|
||||
)
|
||||
|
||||
|
||||
class TestArrayInitializer:
|
||||
def test_str__empty(self):
|
||||
target = cg.ArrayInitializer(
|
||||
None, None
|
||||
)
|
||||
target = cg.ArrayInitializer(None, None)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
assert actual == "{}"
|
||||
|
||||
def test_str__not_multiline(self):
|
||||
target = cg.ArrayInitializer(
|
||||
1, 2, 3, 4
|
||||
)
|
||||
target = cg.ArrayInitializer(1, 2, 3, 4)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
assert actual == "{1, 2, 3, 4}"
|
||||
|
||||
def test_str__multiline(self):
|
||||
target = cg.ArrayInitializer(
|
||||
1, 2, 3, 4, multiline=True
|
||||
)
|
||||
target = cg.ArrayInitializer(1, 2, 3, 4, multiline=True)
|
||||
|
||||
actual = str(target)
|
||||
|
||||
@@ -169,7 +164,7 @@ class TestLambdaExpression:
|
||||
|
||||
def test_str__with_return(self):
|
||||
target = cg.LambdaExpression(
|
||||
("return (foo == 5) && (bar < 10));", ),
|
||||
("return (foo == 5) && (bar < 10));",),
|
||||
cg.ParameterListExpression((int, "foo"), (float, "bar")),
|
||||
"=",
|
||||
bool,
|
||||
@@ -185,27 +180,26 @@ class TestLambdaExpression:
|
||||
|
||||
|
||||
class TestLiterals:
|
||||
@pytest.mark.parametrize("target, expected", (
|
||||
(cg.StringLiteral("foo"), '"foo"'),
|
||||
|
||||
(cg.IntLiteral(0), "0"),
|
||||
(cg.IntLiteral(42), "42"),
|
||||
(cg.IntLiteral(4304967295), "4304967295ULL"),
|
||||
(cg.IntLiteral(2150483647), "2150483647UL"),
|
||||
(cg.IntLiteral(-2150083647), "-2150083647LL"),
|
||||
|
||||
(cg.BoolLiteral(True), "true"),
|
||||
(cg.BoolLiteral(False), "false"),
|
||||
|
||||
(cg.HexIntLiteral(0), "0x00"),
|
||||
(cg.HexIntLiteral(42), "0x2A"),
|
||||
(cg.HexIntLiteral(682), "0x2AA"),
|
||||
|
||||
(cg.FloatLiteral(0.0), "0.0f"),
|
||||
(cg.FloatLiteral(4.2), "4.2f"),
|
||||
(cg.FloatLiteral(1.23456789), "1.23456789f"),
|
||||
(cg.FloatLiteral(math.nan), "NAN"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"target, expected",
|
||||
(
|
||||
(cg.StringLiteral("foo"), '"foo"'),
|
||||
(cg.IntLiteral(0), "0"),
|
||||
(cg.IntLiteral(42), "42"),
|
||||
(cg.IntLiteral(4304967295), "4304967295ULL"),
|
||||
(cg.IntLiteral(2150483647), "2150483647UL"),
|
||||
(cg.IntLiteral(-2150083647), "-2150083647LL"),
|
||||
(cg.BoolLiteral(True), "true"),
|
||||
(cg.BoolLiteral(False), "false"),
|
||||
(cg.HexIntLiteral(0), "0x00"),
|
||||
(cg.HexIntLiteral(42), "0x2A"),
|
||||
(cg.HexIntLiteral(682), "0x2AA"),
|
||||
(cg.FloatLiteral(0.0), "0.0f"),
|
||||
(cg.FloatLiteral(4.2), "4.2f"),
|
||||
(cg.FloatLiteral(1.23456789), "1.23456789f"),
|
||||
(cg.FloatLiteral(math.nan), "NAN"),
|
||||
),
|
||||
)
|
||||
def test_str__simple(self, target: cg.Literal, expected: str):
|
||||
actual = str(target)
|
||||
|
||||
@@ -216,7 +210,9 @@ FAKE_ENUM_VALUE = cg.EnumValue()
|
||||
FAKE_ENUM_VALUE.enum_value = "foo"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj, expected_type", (
|
||||
@pytest.mark.parametrize(
|
||||
"obj, expected_type",
|
||||
(
|
||||
(cg.RawExpression("foo"), cg.RawExpression),
|
||||
(FAKE_ENUM_VALUE, cg.StringLiteral),
|
||||
(True, cg.BoolLiteral),
|
||||
@@ -230,49 +226,59 @@ FAKE_ENUM_VALUE.enum_value = "foo"
|
||||
(cg.TimePeriodMinutes(minutes=42), cg.IntLiteral),
|
||||
((1, 2, 3), cg.ArrayInitializer),
|
||||
([1, 2, 3], cg.ArrayInitializer),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_safe_exp__allowed_values(obj, expected_type):
|
||||
actual = cg.safe_exp(obj)
|
||||
|
||||
assert isinstance(actual, expected_type)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj, expected_type", (
|
||||
@pytest.mark.parametrize(
|
||||
"obj, expected_type",
|
||||
(
|
||||
(bool, ct.bool_),
|
||||
(int, ct.int32),
|
||||
(float, ct.float_),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_safe_exp__allowed_types(obj, expected_type):
|
||||
actual = cg.safe_exp(obj)
|
||||
|
||||
assert actual is expected_type
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj, expected_error", (
|
||||
@pytest.mark.parametrize(
|
||||
"obj, expected_error",
|
||||
(
|
||||
(cg.ID("foo"), "Object foo is an ID."),
|
||||
((x for x in "foo"), r"Object <.*> is a coroutine."),
|
||||
(None, "Object is not an expression"),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_safe_exp__invalid_values(obj, expected_error):
|
||||
with pytest.raises(ValueError, match=expected_error):
|
||||
cg.safe_exp(obj)
|
||||
|
||||
|
||||
class TestStatements:
|
||||
@pytest.mark.parametrize("target, expected", (
|
||||
(cg.RawStatement("foo && bar"), "foo && bar"),
|
||||
|
||||
(cg.ExpressionStatement("foo"), '"foo";'),
|
||||
(cg.ExpressionStatement(42), '42;'),
|
||||
|
||||
(cg.LineComment("The point of foo is..."), "// The point of foo is..."),
|
||||
(cg.LineComment("Help help\nI'm being repressed"), "// Help help\n// I'm being repressed"),
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"target, expected",
|
||||
(
|
||||
cg.ProgmemAssignmentExpression(ct.uint16, "foo", "bar", None),
|
||||
'static const uint16_t foo[] PROGMEM = "bar"'
|
||||
)
|
||||
))
|
||||
(cg.RawStatement("foo && bar"), "foo && bar"),
|
||||
(cg.ExpressionStatement("foo"), '"foo";'),
|
||||
(cg.ExpressionStatement(42), "42;"),
|
||||
(cg.LineComment("The point of foo is..."), "// The point of foo is..."),
|
||||
(
|
||||
cg.LineComment("Help help\nI'm being repressed"),
|
||||
"// Help help\n// I'm being repressed",
|
||||
),
|
||||
(
|
||||
cg.ProgmemAssignmentExpression(ct.uint16, "foo", "bar", None),
|
||||
'static const uint16_t foo[] PROGMEM = "bar"',
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_str__simple(self, target: cg.Statement, expected: str):
|
||||
actual = str(target)
|
||||
|
||||
|
@@ -15,11 +15,9 @@ def test_gpio_pin_expression__conf_is_none(monkeypatch):
|
||||
|
||||
|
||||
def test_gpio_pin_expression__new_pin(monkeypatch):
|
||||
target = ch.gpio_pin_expression({
|
||||
const.CONF_NUMBER: 42,
|
||||
const.CONF_MODE: "input",
|
||||
const.CONF_INVERTED: False
|
||||
})
|
||||
target = ch.gpio_pin_expression(
|
||||
{const.CONF_NUMBER: 42, const.CONF_MODE: "input", const.CONF_INVERTED: False}
|
||||
)
|
||||
|
||||
actual = next(target)
|
||||
|
||||
@@ -71,10 +69,13 @@ def test_register_component__with_setup_priority(monkeypatch):
|
||||
add_mock = Mock()
|
||||
monkeypatch.setattr(ch, "add", add_mock)
|
||||
|
||||
target = ch.register_component(var, {
|
||||
const.CONF_SETUP_PRIORITY: "123",
|
||||
const.CONF_UPDATE_INTERVAL: "456",
|
||||
})
|
||||
target = ch.register_component(
|
||||
var,
|
||||
{
|
||||
const.CONF_SETUP_PRIORITY: "123",
|
||||
const.CONF_UPDATE_INTERVAL: "456",
|
||||
},
|
||||
)
|
||||
|
||||
actual = next(target)
|
||||
|
||||
|
@@ -6,69 +6,89 @@ from hypothesis.provisional import ip_addresses
|
||||
from esphome import helpers
|
||||
|
||||
|
||||
@pytest.mark.parametrize("preferred_string, current_strings, expected", (
|
||||
("foo", [], "foo"),
|
||||
# TODO: Should this actually start at 1?
|
||||
("foo", ["foo"], "foo_2"),
|
||||
("foo", ("foo",), "foo_2"),
|
||||
("foo", ("foo", "foo_2"), "foo_3"),
|
||||
("foo", ("foo", "foo_2", "foo_2"), "foo_3"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"preferred_string, current_strings, expected",
|
||||
(
|
||||
("foo", [], "foo"),
|
||||
# TODO: Should this actually start at 1?
|
||||
("foo", ["foo"], "foo_2"),
|
||||
("foo", ("foo",), "foo_2"),
|
||||
("foo", ("foo", "foo_2"), "foo_3"),
|
||||
("foo", ("foo", "foo_2", "foo_2"), "foo_3"),
|
||||
),
|
||||
)
|
||||
def test_ensure_unique_string(preferred_string, current_strings, expected):
|
||||
actual = helpers.ensure_unique_string(preferred_string, current_strings)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", (
|
||||
("foo", "foo"),
|
||||
("foo\nbar", "foo\nbar"),
|
||||
("foo\nbar\neek", "foo\n bar\neek"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", "foo"),
|
||||
("foo\nbar", "foo\nbar"),
|
||||
("foo\nbar\neek", "foo\n bar\neek"),
|
||||
),
|
||||
)
|
||||
def test_indent_all_but_first_and_last(text, expected):
|
||||
actual = helpers.indent_all_but_first_and_last(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", (
|
||||
("foo", [" foo"]),
|
||||
("foo\nbar", [" foo", " bar"]),
|
||||
("foo\nbar\neek", [" foo", " bar", " eek"]),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", [" foo"]),
|
||||
("foo\nbar", [" foo", " bar"]),
|
||||
("foo\nbar\neek", [" foo", " bar", " eek"]),
|
||||
),
|
||||
)
|
||||
def test_indent_list(text, expected):
|
||||
actual = helpers.indent_list(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", (
|
||||
("foo", " foo"),
|
||||
("foo\nbar", " foo\n bar"),
|
||||
("foo\nbar\neek", " foo\n bar\n eek"),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"text, expected",
|
||||
(
|
||||
("foo", " foo"),
|
||||
("foo\nbar", " foo\n bar"),
|
||||
("foo\nbar\neek", " foo\n bar\n eek"),
|
||||
),
|
||||
)
|
||||
def test_indent(text, expected):
|
||||
actual = helpers.indent(text)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("string, expected", (
|
||||
("foo", '"foo"'),
|
||||
("foo\nbar", '"foo\\012bar"'),
|
||||
("foo\\bar", '"foo\\134bar"'),
|
||||
('foo "bar"', '"foo \\042bar\\042"'),
|
||||
('foo 🐍', '"foo \\360\\237\\220\\215"'),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"string, expected",
|
||||
(
|
||||
("foo", '"foo"'),
|
||||
("foo\nbar", '"foo\\012bar"'),
|
||||
("foo\\bar", '"foo\\134bar"'),
|
||||
('foo "bar"', '"foo \\042bar\\042"'),
|
||||
("foo 🐍", '"foo \\360\\237\\220\\215"'),
|
||||
),
|
||||
)
|
||||
def test_cpp_string_escape(string, expected):
|
||||
actual = helpers.cpp_string_escape(string)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("host", (
|
||||
"127.0.0", "localhost", "127.0.0.b",
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"host",
|
||||
(
|
||||
"127.0.0",
|
||||
"localhost",
|
||||
"127.0.0.b",
|
||||
),
|
||||
)
|
||||
def test_is_ip_address__invalid(host):
|
||||
actual = helpers.is_ip_address(host)
|
||||
|
||||
@@ -82,13 +102,16 @@ def test_is_ip_address__valid(value):
|
||||
assert actual is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize("var, value, default, expected", (
|
||||
("FOO", None, False, False),
|
||||
("FOO", None, True, True),
|
||||
("FOO", "", False, False),
|
||||
("FOO", "Yes", False, True),
|
||||
("FOO", "123", False, True),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"var, value, default, expected",
|
||||
(
|
||||
("FOO", None, False, False),
|
||||
("FOO", None, True, True),
|
||||
("FOO", "", False, False),
|
||||
("FOO", "Yes", False, True),
|
||||
("FOO", "123", False, True),
|
||||
),
|
||||
)
|
||||
def test_get_bool_env(monkeypatch, var, value, default, expected):
|
||||
if value is None:
|
||||
monkeypatch.delenv(var, raising=False)
|
||||
@@ -100,10 +123,7 @@ def test_get_bool_env(monkeypatch, var, value, default, expected):
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
(None, False),
|
||||
("Yes", True)
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", ((None, False), ("Yes", True)))
|
||||
def test_is_hassio(monkeypatch, value, expected):
|
||||
if value is None:
|
||||
monkeypatch.delenv("ESPHOME_IS_HASSIO", raising=False)
|
||||
@@ -185,20 +205,23 @@ class Test_copy_file_if_changed:
|
||||
assert src.read_text() == dst.read_text()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("file1, file2, expected", (
|
||||
# Same file
|
||||
("file-a.txt", "file-a.txt", True),
|
||||
# Different files, different size
|
||||
("file-a.txt", "file-b_1.txt", False),
|
||||
# Different files, same size
|
||||
("file-a.txt", "file-c.txt", False),
|
||||
# Same files
|
||||
("file-b_1.txt", "file-b_2.txt", True),
|
||||
# Not a file
|
||||
("file-a.txt", "", False),
|
||||
# File doesn't exist
|
||||
("file-a.txt", "file-d.txt", False),
|
||||
))
|
||||
@pytest.mark.parametrize(
|
||||
"file1, file2, expected",
|
||||
(
|
||||
# Same file
|
||||
("file-a.txt", "file-a.txt", True),
|
||||
# Different files, different size
|
||||
("file-a.txt", "file-b_1.txt", False),
|
||||
# Different files, same size
|
||||
("file-a.txt", "file-c.txt", False),
|
||||
# Same files
|
||||
("file-b_1.txt", "file-b_2.txt", True),
|
||||
# Not a file
|
||||
("file-a.txt", "", False),
|
||||
# File doesn't exist
|
||||
("file-a.txt", "file-d.txt", False),
|
||||
),
|
||||
)
|
||||
def test_file_compare(fixture_path, file1, file2, expected):
|
||||
path1 = fixture_path / "helpers" / file1
|
||||
path2 = fixture_path / "helpers" / file2
|
||||
|
@@ -15,12 +15,12 @@ from esphome import pins
|
||||
|
||||
|
||||
MOCK_ESP8266_BOARD_ID = "_mock_esp8266"
|
||||
MOCK_ESP8266_PINS = {'X0': 16, 'X1': 5, 'X2': 4, 'LED': 2}
|
||||
MOCK_ESP8266_PINS = {"X0": 16, "X1": 5, "X2": 4, "LED": 2}
|
||||
MOCK_ESP8266_BOARD_ALIAS_ID = "_mock_esp8266_alias"
|
||||
MOCK_ESP8266_FLASH_SIZE = pins.FLASH_SIZE_2_MB
|
||||
|
||||
MOCK_ESP32_BOARD_ID = "_mock_esp32"
|
||||
MOCK_ESP32_PINS = {'Y0': 12, 'Y1': 8, 'Y2': 3, 'LED': 9, "A0": 8}
|
||||
MOCK_ESP32_PINS = {"Y0": 12, "Y1": 8, "Y2": 3, "LED": 9, "A0": 8}
|
||||
MOCK_ESP32_BOARD_ALIAS_ID = "_mock_esp32_alias"
|
||||
|
||||
UNKNOWN_PLATFORM = "STM32"
|
||||
@@ -68,10 +68,13 @@ def core_esp32(core):
|
||||
|
||||
|
||||
class Test_lookup_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("X1", 5),
|
||||
("MOSI", 13),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp8266_pin(self, core_esp8266, value, expected):
|
||||
actual = pins._lookup_pin(value)
|
||||
|
||||
@@ -84,11 +87,14 @@ class Test_lookup_pin:
|
||||
|
||||
assert actual == 4
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y1", 8),
|
||||
("A0", 8),
|
||||
("MOSI", 23),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_pin(self, core_esp32, value, expected):
|
||||
actual = pins._lookup_pin(value)
|
||||
|
||||
@@ -102,7 +108,9 @@ class Test_lookup_pin:
|
||||
assert actual == 3
|
||||
|
||||
def test_invalid_pin(self, core_esp8266):
|
||||
with pytest.raises(Invalid, match="Cannot resolve pin name 'X42' for board _mock_esp8266."):
|
||||
with pytest.raises(
|
||||
Invalid, match="Cannot resolve pin name 'X42' for board _mock_esp8266."
|
||||
):
|
||||
pins._lookup_pin("X42")
|
||||
|
||||
def test_unsupported_platform(self, core):
|
||||
@@ -113,13 +121,16 @@ class Test_lookup_pin:
|
||||
|
||||
|
||||
class Test_translate_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
(2, 2),
|
||||
("3", 3),
|
||||
("GPIO4", 4),
|
||||
("TX", 1),
|
||||
("Y0", 12),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_values(self, core_esp32, value, expected):
|
||||
actual = pins._translate_pin(value)
|
||||
|
||||
@@ -137,7 +148,9 @@ class Test_validate_gpio_pin:
|
||||
|
||||
assert actual == 22
|
||||
|
||||
@pytest.mark.parametrize("value, match", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, match",
|
||||
(
|
||||
(-1, "ESP32: Invalid pin number: -1"),
|
||||
(40, "ESP32: Invalid pin number: 40"),
|
||||
(6, "This pin cannot be used on ESP32s and"),
|
||||
@@ -150,7 +163,8 @@ class Test_validate_gpio_pin:
|
||||
(29, "The pin GPIO29 is not usable on ESP32s"),
|
||||
(30, "The pin GPIO30 is not usable on ESP32s"),
|
||||
(31, "The pin GPIO31 is not usable on ESP32s"),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_esp32_invalid_pin(self, core_esp32, value, match):
|
||||
with pytest.raises(Invalid, match=match):
|
||||
pins.validate_gpio_pin(value)
|
||||
@@ -168,14 +182,17 @@ class Test_validate_gpio_pin:
|
||||
|
||||
assert actual == 12
|
||||
|
||||
@pytest.mark.parametrize("value, match", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, match",
|
||||
(
|
||||
(-1, "ESP8266: Invalid pin number: -1"),
|
||||
(18, "ESP8266: Invalid pin number: 18"),
|
||||
(6, "This pin cannot be used on ESP8266s and"),
|
||||
(7, "This pin cannot be used on ESP8266s and"),
|
||||
(8, "This pin cannot be used on ESP8266s and"),
|
||||
(11, "This pin cannot be used on ESP8266s and"),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_esp8266_invalid_pin(self, core_esp8266, value, match):
|
||||
with pytest.raises(Invalid, match=match):
|
||||
pins.validate_gpio_pin(value)
|
||||
@@ -196,18 +213,19 @@ class Test_validate_gpio_pin:
|
||||
|
||||
|
||||
class Test_input_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
("X0", 16),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", (("X0", 16),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.input_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y0", 12),
|
||||
(17, 17),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.input_pin(value)
|
||||
|
||||
@@ -226,18 +244,19 @@ class Test_input_pin:
|
||||
|
||||
|
||||
class Test_input_pullup_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
("X0", 16),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", (("X0", 16),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.input_pullup_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y0", 12),
|
||||
(17, 17),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.input_pullup_pin(value)
|
||||
|
||||
@@ -256,18 +275,19 @@ class Test_input_pullup_pin:
|
||||
|
||||
|
||||
class Test_output_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
("X0", 16),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", (("X0", 16),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.output_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
("Y0", 12),
|
||||
(17, 17),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.output_pin(value)
|
||||
|
||||
@@ -291,18 +311,19 @@ class Test_output_pin:
|
||||
|
||||
|
||||
class Test_analog_pin:
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
(17, 17),
|
||||
))
|
||||
@pytest.mark.parametrize("value, expected", ((17, 17),))
|
||||
def test_valid_esp8266_values(self, core_esp8266, value, expected):
|
||||
actual = pins.analog_pin(value)
|
||||
|
||||
assert actual == expected
|
||||
|
||||
@pytest.mark.parametrize("value, expected", (
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
(
|
||||
(32, 32),
|
||||
(39, 39),
|
||||
))
|
||||
),
|
||||
)
|
||||
def test_valid_esp32_values(self, core_esp32, value, expected):
|
||||
actual = pins.analog_pin(value)
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
""" Tests for the wizard.py file """
|
||||
"""Tests for the wizard.py file."""
|
||||
|
||||
import esphome.wizard as wz
|
||||
import pytest
|
||||
@@ -14,7 +14,7 @@ def default_config():
|
||||
"board": "test_board",
|
||||
"ssid": "test_ssid",
|
||||
"psk": "test_psk",
|
||||
"password": ""
|
||||
"password": "",
|
||||
}
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ def test_sanitize_quotes_replaces_with_escaped_char():
|
||||
The sanitize_quotes function should replace double quotes with their escaped equivalents
|
||||
"""
|
||||
# Given
|
||||
input_str = "\"key\": \"value\""
|
||||
input_str = '"key": "value"'
|
||||
|
||||
# When
|
||||
output_str = wz.sanitize_double_quotes(input_str)
|
||||
|
||||
# Then
|
||||
assert output_str == "\\\"key\\\": \\\"value\\\""
|
||||
assert output_str == '\\"key\\": \\"value\\"'
|
||||
|
||||
|
||||
def test_config_file_fallback_ap_includes_descriptive_name(default_config):
|
||||
@@ -55,7 +55,7 @@ def test_config_file_fallback_ap_includes_descriptive_name(default_config):
|
||||
config = wz.wizard_file(**default_config)
|
||||
|
||||
# Then
|
||||
assert f"ssid: \"Test Node Fallback Hotspot\"" in config
|
||||
assert 'ssid: "Test Node Fallback Hotspot"' in config
|
||||
|
||||
|
||||
def test_config_file_fallback_ap_name_less_than_32_chars(default_config):
|
||||
@@ -70,7 +70,7 @@ def test_config_file_fallback_ap_name_less_than_32_chars(default_config):
|
||||
config = wz.wizard_file(**default_config)
|
||||
|
||||
# Then
|
||||
assert f"ssid: \"A Very Long Name For This Node\"" in config
|
||||
assert 'ssid: "A Very Long Name For This Node"' in config
|
||||
|
||||
|
||||
def test_config_file_should_include_ota(default_config):
|
||||
@@ -115,7 +115,9 @@ def test_wizard_write_sets_platform(default_config, tmp_path, monkeypatch):
|
||||
assert f"platform: {default_config['platform']}" in generated_config
|
||||
|
||||
|
||||
def test_wizard_write_defaults_platform_from_board_esp8266(default_config, tmp_path, monkeypatch):
|
||||
def test_wizard_write_defaults_platform_from_board_esp8266(
|
||||
default_config, tmp_path, monkeypatch
|
||||
):
|
||||
"""
|
||||
If the platform is not explicitly set, use "ESP8266" if the board is one of the ESP8266 boards
|
||||
"""
|
||||
@@ -133,7 +135,9 @@ def test_wizard_write_defaults_platform_from_board_esp8266(default_config, tmp_p
|
||||
assert "platform: ESP8266" in generated_config
|
||||
|
||||
|
||||
def test_wizard_write_defaults_platform_from_board_esp32(default_config, tmp_path, monkeypatch):
|
||||
def test_wizard_write_defaults_platform_from_board_esp32(
|
||||
default_config, tmp_path, monkeypatch
|
||||
):
|
||||
"""
|
||||
If the platform is not explicitly set, use "ESP32" if the board is not one of the ESP8266 boards
|
||||
"""
|
||||
@@ -167,7 +171,9 @@ def test_safe_print_step_prints_step_number_and_description(monkeypatch):
|
||||
|
||||
# Then
|
||||
# Collect arguments to all safe_print() calls (substituting "" for any empty ones)
|
||||
all_args = [call.args[0] if len(call.args) else "" for call in wz.safe_print.call_args_list]
|
||||
all_args = [
|
||||
call.args[0] if len(call.args) else "" for call in wz.safe_print.call_args_list
|
||||
]
|
||||
|
||||
assert any(step_desc == arg for arg in all_args)
|
||||
assert any(f"STEP {step_num}" in arg for arg in all_args)
|
||||
@@ -212,7 +218,7 @@ def test_strip_accents_removes_diacritics():
|
||||
"""
|
||||
|
||||
# Given
|
||||
input_str = u"Kühne"
|
||||
input_str = "Kühne"
|
||||
expected_str = "Kuhne"
|
||||
|
||||
# When
|
||||
@@ -264,7 +270,7 @@ def test_wizard_accepts_default_answers_esp8266(tmpdir, monkeypatch, wizard_answ
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -286,7 +292,7 @@ def test_wizard_accepts_default_answers_esp32(tmpdir, monkeypatch, wizard_answer
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -306,14 +312,16 @@ def test_wizard_offers_better_node_name(tmpdir, monkeypatch, wizard_answers):
|
||||
# Given
|
||||
wizard_answers[0] = "Küche #2"
|
||||
expected_name = "kuche_2"
|
||||
monkeypatch.setattr(wz, "default_input", MagicMock(side_effect=lambda _, default: default))
|
||||
monkeypatch.setattr(
|
||||
wz, "default_input", MagicMock(side_effect=lambda _, default: default)
|
||||
)
|
||||
|
||||
config_file = tmpdir.join("test.yaml")
|
||||
input_mock = MagicMock(side_effect=wizard_answers)
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -336,7 +344,7 @@ def test_wizard_requires_correct_platform(tmpdir, monkeypatch, wizard_answers):
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -358,7 +366,7 @@ def test_wizard_requires_correct_board(tmpdir, monkeypatch, wizard_answers):
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
@@ -380,7 +388,7 @@ def test_wizard_requires_valid_ssid(tmpdir, monkeypatch, wizard_answers):
|
||||
monkeypatch.setattr("builtins.input", input_mock)
|
||||
monkeypatch.setattr(wz, "safe_print", lambda t=None: 0)
|
||||
monkeypatch.setattr(wz, "sleep", lambda _: 0)
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
monkeypatch.setattr(wz, "wizard_write", MagicMock())
|
||||
|
||||
# When
|
||||
retval = wz.wizard(str(config_file))
|
||||
|
Reference in New Issue
Block a user