# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Recipe for testing LUCI configs."""

from typing import Generator

from PB.recipes.pigweed.luci_config import InputProperties
from recipe_engine import post_process, recipe_test_api

DEPS = [
    'fuchsia/validate_lucicfg',
    'pigweed/checkout',
    'recipe_engine/properties',
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    """Run lucicfg validate on changed starlark files."""

    checkout = api.checkout(props.checkout_options)
    api.validate_lucicfg(checkout.root, props.validate_lucicfg_options)


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    def properties():
        props = InputProperties()
        props.checkout_options.CopyFrom(api.checkout.git_options())
        props.validate_lucicfg_options.CopyFrom(api.validate_lucicfg.options())
        return api.properties(props)

    yield (
        api.test('starlark')
        + properties()
        + api.checkout.try_test_data()
        + api.post_process(post_process.DropExpectation)
    )
