1# Copyright (C) 2023 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
16load(":cc_yacc_library.bzl", "cc_yacc_static_library")
17
18def _yacc_generates_c_output_test_impl(ctx):
19    env = analysistest.begin(ctx)
20
21    actions = analysistest.target_actions(env)
22
23    asserts.equals(
24        env,
25        1,
26        len(actions),
27        "Incorrect number of actions",
28    )
29
30    action_outputs = actions[0].outputs.to_list()
31
32    asserts.equals(
33        env,
34        len(ctx.attr.expected_output_filenames),
35        len(action_outputs),
36        "Incorrect number of action outputs",
37    )
38
39    for i in range(0, len(ctx.attr.expected_output_filenames)):
40        asserts.equals(
41            env,
42            ctx.attr.expected_output_filenames[i],
43            action_outputs[i].basename,
44        )
45
46    return analysistest.end(env)
47
48_yacc_generates_c_output_test = analysistest.make(
49    _yacc_generates_c_output_test_impl,
50    attrs = {
51        "expected_output_filenames": attr.string_list(),
52    },
53)
54
55def _yacc_generates_c_output():
56    subject_name = "yacc_generates_c_output"
57
58    # Test the internal _cc_yacc_parser_gen created by cc_yacc_static_library
59    test_subject_name = subject_name + "_parser"
60    test_name = subject_name + "_test"
61
62    cc_yacc_static_library(
63        name = subject_name,
64        src = "foo.y",
65        tags = ["manual"],
66    )
67    _yacc_generates_c_output_test(
68        name = test_name,
69        target_under_test = test_subject_name,
70        expected_output_filenames = ["foo.c", "foo.h"],
71    )
72    return test_name
73
74def _yacc_generates_cpp_output():
75    subject_name = "yacc_generates_cpp_output"
76
77    # Test the internal _cc_yacc_parser_gen created by cc_yacc_static_library
78    test_subject_name = subject_name + "_parser"
79    test_name = subject_name + "_test"
80
81    cc_yacc_static_library(
82        name = subject_name,
83        src = "foo.yy",
84        tags = ["manual"],
85    )
86    _yacc_generates_c_output_test(
87        name = test_name,
88        target_under_test = test_subject_name,
89        expected_output_filenames = ["foo.cpp", "foo.h"],
90    )
91    return test_name
92
93def _yacc_generates_implicit_header_outputs():
94    subject_name = "yacc_generates_implicit_headers"
95
96    # Test the internal _cc_yacc_parser_gen created by cc_yacc_static_library
97    test_subject_name = subject_name + "_parser"
98    test_name = subject_name + "_test"
99
100    cc_yacc_static_library(
101        name = subject_name,
102        src = "foo.y",
103        gen_location_hh = True,
104        gen_position_hh = True,
105        tags = ["manual"],
106    )
107    _yacc_generates_c_output_test(
108        name = test_name,
109        target_under_test = test_subject_name,
110        expected_output_filenames = ["foo.c", "foo.h", "location.hh", "position.hh"],
111    )
112    return test_name
113
114def cc_yacc_static_library_test_suite(name):
115    native.test_suite(
116        name = name,
117        tests = [
118            _yacc_generates_c_output(),
119            _yacc_generates_cpp_output(),
120            _yacc_generates_implicit_header_outputs(),
121        ],
122    )
123