Fix T93642: value used as transform offset is ignored in some modes
[blender.git] / source / blender / compositor / tests / COM_NodeOperation_test.cc
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2021, Blender Foundation.
17  */
18
19 #include "testing/testing.h"
20
21 #include "COM_ConstantOperation.h"
22
23 namespace blender::compositor::tests {
24
25 class NonHashedOperation : public NodeOperation {
26  public:
27   NonHashedOperation(int id)
28   {
29     set_id(id);
30     add_output_socket(DataType::Value);
31     set_width(2);
32     set_height(3);
33   }
34 };
35
36 class NonHashedConstantOperation : public ConstantOperation {
37   float constant_;
38
39  public:
40   NonHashedConstantOperation(int id)
41   {
42     set_id(id);
43     add_output_socket(DataType::Value);
44     set_width(2);
45     set_height(3);
46     constant_ = 1.0f;
47   }
48
49   const float *get_constant_elem() override
50   {
51     return &constant_;
52   }
53
54   void set_constant(float value)
55   {
56     constant_ = value;
57   }
58 };
59
60 class HashedOperation : public NodeOperation {
61  private:
62   int param1;
63   float param2;
64
65  public:
66   HashedOperation(NodeOperation &input, int width, int height)
67   {
68     add_input_socket(DataType::Value);
69     add_output_socket(DataType::Color);
70     set_width(width);
71     set_height(height);
72     param1 = 2;
73     param2 = 7.0f;
74
75     get_input_socket(0)->set_link(input.get_output_socket());
76   }
77
78   void set_param1(int value)
79   {
80     param1 = value;
81   }
82
83   void hash_output_params() override
84   {
85     hash_params(param1, param2);
86   }
87 };
88
89 static void test_non_equal_hashes_compare(NodeOperationHash &h1,
90                                           NodeOperationHash &h2,
91                                           NodeOperationHash &h3)
92 {
93   if (h1 < h2) {
94     if (h3 < h1) {
95       EXPECT_TRUE(h3 < h2);
96     }
97     else if (h3 < h2) {
98       EXPECT_TRUE(h1 < h3);
99     }
100     else {
101       EXPECT_TRUE(h1 < h3);
102       EXPECT_TRUE(h2 < h3);
103     }
104   }
105   else {
106     EXPECT_TRUE(h2 < h1);
107   }
108 }
109
110 TEST(NodeOperation, generate_hash)
111 {
112   /* Constant input. */
113   {
114     NonHashedConstantOperation input_op1(1);
115     input_op1.set_constant(1.0f);
116     EXPECT_EQ(input_op1.generate_hash(), std::nullopt);
117
118     HashedOperation op1(input_op1, 6, 4);
119     std::optional<NodeOperationHash> hash1_opt = op1.generate_hash();
120     EXPECT_NE(hash1_opt, std::nullopt);
121     NodeOperationHash hash1 = *hash1_opt;
122
123     NonHashedConstantOperation input_op2(1);
124     input_op2.set_constant(1.0f);
125     HashedOperation op2(input_op2, 6, 4);
126     NodeOperationHash hash2 = *op2.generate_hash();
127     EXPECT_EQ(hash1, hash2);
128
129     input_op2.set_constant(3.0f);
130     hash2 = *op2.generate_hash();
131     EXPECT_NE(hash1, hash2);
132   }
133
134   /* Non constant input. */
135   {
136     NonHashedOperation input_op(1);
137     EXPECT_EQ(input_op.generate_hash(), std::nullopt);
138
139     HashedOperation op1(input_op, 6, 4);
140     HashedOperation op2(input_op, 6, 4);
141     NodeOperationHash hash1 = *op1.generate_hash();
142     NodeOperationHash hash2 = *op2.generate_hash();
143     EXPECT_EQ(hash1, hash2);
144     op1.set_param1(-1);
145     hash1 = *op1.generate_hash();
146     EXPECT_NE(hash1, hash2);
147
148     HashedOperation op3(input_op, 11, 14);
149     NodeOperationHash hash3 = *op3.generate_hash();
150     EXPECT_NE(hash2, hash3);
151     EXPECT_NE(hash1, hash3);
152
153     test_non_equal_hashes_compare(hash1, hash2, hash3);
154     test_non_equal_hashes_compare(hash3, hash2, hash1);
155     test_non_equal_hashes_compare(hash2, hash3, hash1);
156     test_non_equal_hashes_compare(hash3, hash1, hash2);
157
158     NonHashedOperation input_op2(2);
159     HashedOperation op4(input_op2, 11, 14);
160     NodeOperationHash hash4 = *op4.generate_hash();
161     EXPECT_NE(hash3, hash4);
162
163     input_op2.set_id(1);
164     hash4 = *op4.generate_hash();
165     EXPECT_EQ(hash3, hash4);
166   }
167 }
168
169 }  // namespace blender::compositor::tests