|
94 | 94 | X(ConstantDef) \ |
95 | 95 | X(EnumDef) \ |
96 | 96 | X(Function) \ |
| 97 | + X(FuzzTestFunction) \ |
97 | 98 | X(Impl) \ |
98 | 99 | X(Import) \ |
99 | 100 | X(Let) \ |
@@ -3843,6 +3844,8 @@ class Range : public Expr { |
3843 | 3844 | // #[test] |
3844 | 3845 | // fn test_foo() { ... } |
3845 | 3846 | // ``` |
| 3847 | +// TODO: davidplass - Add an optional parameter Expr to allow re-using as a |
| 3848 | +// FuzzTestFunction or QuickCheck. |
3846 | 3849 | class TestFunction : public AstNode { |
3847 | 3850 | public: |
3848 | 3851 | static std::string_view GetDebugTypeName() { return "test function"; } |
@@ -3879,6 +3882,73 @@ class TestFunction : public AstNode { |
3879 | 3882 | Function& fn_; |
3880 | 3883 | }; |
3881 | 3884 |
|
| 3885 | +// Represents a fuzz test construct. |
| 3886 | +// |
| 3887 | +// These are specified with an annotation as follows: |
| 3888 | +// |
| 3889 | +// ```dslx |
| 3890 | +// #[fuzz_test] |
| 3891 | +// fn test_foo() { ... } |
| 3892 | +// ``` |
| 3893 | +// |
| 3894 | +// or with a domains argument: |
| 3895 | +// |
| 3896 | +// ```dslx |
| 3897 | +// #[fuzz_test(domains=`...`)] |
| 3898 | +// fn test_foo() { ... } |
| 3899 | +// ``` |
| 3900 | +// TODO: davidplass - Migrate this into TestFunction, after adding an optional |
| 3901 | +// parameter to TestFunction to capture the domain tuple. |
| 3902 | +// TODO: davidplass - make this a ModuleMember. |
| 3903 | +class FuzzTestFunction : public AstNode { |
| 3904 | + public: |
| 3905 | + static std::string_view GetDebugTypeName() { return "fuzz test function"; } |
| 3906 | + |
| 3907 | + FuzzTestFunction(Module* owner, Span span, Function& fn, |
| 3908 | + std::optional<Expr*> domains) |
| 3909 | + : AstNode(owner), |
| 3910 | + span_(std::move(span)), |
| 3911 | + fn_(fn), |
| 3912 | + domains_(std::move(domains)) {} |
| 3913 | + |
| 3914 | + ~FuzzTestFunction() override; |
| 3915 | + |
| 3916 | + AstNodeKind kind() const override { return AstNodeKind::kFuzzTestFunction; } |
| 3917 | + NameDef* name_def() const { return fn_.name_def(); } |
| 3918 | + |
| 3919 | + absl::Status Accept(AstNodeVisitor* v) const override { |
| 3920 | + return v->HandleFuzzTestFunction(this); |
| 3921 | + } |
| 3922 | + |
| 3923 | + std::vector<AstNode*> GetChildren(bool want_types) const override { |
| 3924 | + return {&fn_}; |
| 3925 | + } |
| 3926 | + |
| 3927 | + std::string_view GetNodeTypeName() const override { |
| 3928 | + return "FuzzTestFunction"; |
| 3929 | + } |
| 3930 | + std::string ToString() const override { |
| 3931 | + if (domains_.has_value()) { |
| 3932 | + return absl::StrFormat("#[fuzz_test(domains=`%s`)]\n%s", |
| 3933 | + (*domains_)->ToString(), fn_.ToString()); |
| 3934 | + } |
| 3935 | + return absl::StrFormat("#[fuzz_test]\n%s", fn_.ToString()); |
| 3936 | + } |
| 3937 | + |
| 3938 | + Function& fn() const { return fn_; } |
| 3939 | + std::optional<Span> GetSpan() const override { return span(); } |
| 3940 | + const Span& span() const { return span_; } |
| 3941 | + |
| 3942 | + const std::string& identifier() const { return fn_.name_def()->identifier(); } |
| 3943 | + |
| 3944 | + const std::optional<Expr*>& domains() const { return domains_; } |
| 3945 | + |
| 3946 | + private: |
| 3947 | + const Span span_; |
| 3948 | + Function& fn_; |
| 3949 | + const std::optional<Expr*> domains_; |
| 3950 | +}; |
| 3951 | + |
3882 | 3952 | enum class QuickCheckTestCasesTag { |
3883 | 3953 | kExhaustive, |
3884 | 3954 | kCounted, |
@@ -3914,6 +3984,8 @@ class QuickCheckTestCases { |
3914 | 3984 | }; |
3915 | 3985 |
|
3916 | 3986 | // Represents a function to be quick-check'd. |
| 3987 | +// TODO: davidplass - Migrate this into TestFunction, since QuickCheck is an |
| 3988 | +// attribute which can capture the quick check test cases. |
3917 | 3989 | class QuickCheck : public AstNode { |
3918 | 3990 | public: |
3919 | 3991 | static std::string_view GetDebugTypeName() { return "quickcheck"; } |
|
0 commit comments