From b61023ad0bf6ad4221257ed9c3e7fc484549f371 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Wed, 6 Sep 2023 23:03:05 -0400 Subject: [PATCH] Multiple input test files (#258) * Initial infrastructure to deal with multiple input test files. * Simply copy testSameFileSameName() tests. Put them in different files. * Make variable final. * Add test case with class with same name. * More tests. * Test varying hybridizations. * Reuse ctor. * Test varying tensor parameterization. * Change the way we find FUTs. * Fix spelling. * Test normal functions with same attributes. * Test normal functions with different attributes. * Add containing module name to FUT. * More tests with varying attributes. * Ensure the FUT is non-null. Not sure if this will appease the CI or not. --- .../hybridize/core/analysis/Function.java | 4 + .../testDifferentFileSameName/in/A.py | 8 + .../testDifferentFileSameName/in/B.py | 8 + .../in/requirements.txt | 1 + .../testDifferentFileSameName10/in/A.py | 10 + .../testDifferentFileSameName10/in/B.py | 10 + .../in/requirements.txt | 1 + .../testDifferentFileSameName2/in/A.py | 6 + .../testDifferentFileSameName2/in/B.py | 6 + .../in/requirements.txt | 1 + .../testDifferentFileSameName3/in/A.py | 8 + .../testDifferentFileSameName3/in/B.py | 8 + .../in/requirements.txt | 1 + .../testDifferentFileSameName4/in/A.py | 12 + .../testDifferentFileSameName4/in/B.py | 12 + .../in/requirements.txt | 1 + .../testDifferentFileSameName5/in/A.py | 12 + .../testDifferentFileSameName5/in/B.py | 12 + .../in/requirements.txt | 1 + .../testDifferentFileSameName6/in/A.py | 12 + .../testDifferentFileSameName6/in/B.py | 8 + .../in/requirements.txt | 1 + .../testDifferentFileSameName7/in/A.py | 12 + .../testDifferentFileSameName7/in/B.py | 12 + .../in/requirements.txt | 1 + .../testDifferentFileSameName8/in/A.py | 10 + .../testDifferentFileSameName8/in/B.py | 10 + .../in/requirements.txt | 1 + .../testDifferentFileSameName9/in/A.py | 10 + .../testDifferentFileSameName9/in/B.py | 6 + .../in/requirements.txt | 1 + .../hybridize/tests/FunctionUnderTest.java | 44 ++- .../HybridizeFunctionRefactoringTest.java | 285 ++++++++++++++++-- 33 files changed, 501 insertions(+), 34 deletions(-) create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/requirements.txt create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/A.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/B.py create mode 100644 edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/requirements.txt diff --git a/edu.cuny.hunter.hybridize.core/src/edu/cuny/hunter/hybridize/core/analysis/Function.java b/edu.cuny.hunter.hybridize.core/src/edu/cuny/hunter/hybridize/core/analysis/Function.java index b99d3c084..d65036f85 100644 --- a/edu.cuny.hunter.hybridize.core/src/edu/cuny/hunter/hybridize/core/analysis/Function.java +++ b/edu.cuny.hunter.hybridize.core/src/edu/cuny/hunter/hybridize/core/analysis/Function.java @@ -684,6 +684,10 @@ public argumentsType getParameters() { return getFunctionDefinition().getFunctionDef().args; } + public int getNumberOfParameters() { + return getFunctionDefinition().getFunctionDef().args.args.length; + } + public RefactoringStatus getStatus() { return this.status; } diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/A.py new file mode 100644 index 000000000..e5ee19aa3 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/A.py @@ -0,0 +1,8 @@ +class Test: + + def b(self): + pass + + +if __name__ == '__main__': + Test().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/B.py new file mode 100644 index 000000000..0f73216c9 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/B.py @@ -0,0 +1,8 @@ +class Test2: + + def b(self): + pass + + +if __name__ == '__main__': + Test2().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/requirements.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName/in/requirements.txt @@ -0,0 +1 @@ + diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/A.py new file mode 100644 index 000000000..ddba4cbd8 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/A.py @@ -0,0 +1,10 @@ +import tensorflow as tf + + +@tf.function +def b(a): + pass + + +if __name__ == '__main__': + b(tf.ones([1, 2])) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/B.py new file mode 100644 index 000000000..eb2ca0c66 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/B.py @@ -0,0 +1,10 @@ +import tensorflow as tf + + +@tf.function +def b(a): + pass + + +if __name__ == '__main__': + b(5) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName10/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/A.py new file mode 100644 index 000000000..60efcceac --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/A.py @@ -0,0 +1,6 @@ +def b(): + pass + + +if __name__ == '__main__': + b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/B.py new file mode 100644 index 000000000..60efcceac --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/B.py @@ -0,0 +1,6 @@ +def b(): + pass + + +if __name__ == '__main__': + b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/requirements.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName2/in/requirements.txt @@ -0,0 +1 @@ + diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/A.py new file mode 100644 index 000000000..e5ee19aa3 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/A.py @@ -0,0 +1,8 @@ +class Test: + + def b(self): + pass + + +if __name__ == '__main__': + Test().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/B.py new file mode 100644 index 000000000..e5ee19aa3 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/B.py @@ -0,0 +1,8 @@ +class Test: + + def b(self): + pass + + +if __name__ == '__main__': + Test().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/requirements.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName3/in/requirements.txt @@ -0,0 +1 @@ + diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/A.py new file mode 100644 index 000000000..5a83ccb95 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/A.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test: + + @tf.function + def b(self): + pass + + +if __name__ == '__main__': + Test().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/B.py new file mode 100644 index 000000000..f8cafc40a --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/B.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test2: + + @tf.function + def b(self): + pass + + +if __name__ == '__main__': + Test2().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName4/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/A.py new file mode 100644 index 000000000..a98fcbc0d --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/A.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test: + + @tf.function + def b(self, a): + pass + + +if __name__ == '__main__': + Test().b(tf.ones([1, 2])) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/B.py new file mode 100644 index 000000000..89bd861f6 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/B.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test2: + + @tf.function + def b(self, a): + pass + + +if __name__ == '__main__': + Test2().b(tf.ones([1, 2])) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName5/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/A.py new file mode 100644 index 000000000..5a83ccb95 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/A.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test: + + @tf.function + def b(self): + pass + + +if __name__ == '__main__': + Test().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/B.py new file mode 100644 index 000000000..0f73216c9 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/B.py @@ -0,0 +1,8 @@ +class Test2: + + def b(self): + pass + + +if __name__ == '__main__': + Test2().b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName6/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/A.py new file mode 100644 index 000000000..a98fcbc0d --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/A.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test: + + @tf.function + def b(self, a): + pass + + +if __name__ == '__main__': + Test().b(tf.ones([1, 2])) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/B.py new file mode 100644 index 000000000..1fe9ef71d --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/B.py @@ -0,0 +1,12 @@ +import tensorflow as tf + + +class Test2: + + @tf.function + def b(self, a): + pass + + +if __name__ == '__main__': + Test2().b(5) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName7/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/A.py new file mode 100644 index 000000000..eb2ca0c66 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/A.py @@ -0,0 +1,10 @@ +import tensorflow as tf + + +@tf.function +def b(a): + pass + + +if __name__ == '__main__': + b(5) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/B.py new file mode 100644 index 000000000..3d57ef7a2 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/B.py @@ -0,0 +1,10 @@ +import tensorflow as tf + + +@tf.function +def b(): + pass + + +if __name__ == '__main__': + b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName8/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/A.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/A.py new file mode 100644 index 000000000..eb2ca0c66 --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/A.py @@ -0,0 +1,10 @@ +import tensorflow as tf + + +@tf.function +def b(a): + pass + + +if __name__ == '__main__': + b(5) diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/B.py b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/B.py new file mode 100644 index 000000000..60efcceac --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/B.py @@ -0,0 +1,6 @@ +def b(): + pass + + +if __name__ == '__main__': + b() diff --git a/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/requirements.txt b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/requirements.txt new file mode 100644 index 000000000..b154f958f --- /dev/null +++ b/edu.cuny.hunter.hybridize.tests/resources/HybridizeFunction/testDifferentFileSameName9/in/requirements.txt @@ -0,0 +1 @@ +tensorflow==2.9.3 diff --git a/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/FunctionUnderTest.java b/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/FunctionUnderTest.java index 08bc5dc2b..0758059ab 100644 --- a/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/FunctionUnderTest.java +++ b/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/FunctionUnderTest.java @@ -28,7 +28,12 @@ public class FunctionUnderTest { private String name; /** - * The names of the parameteres of this function under test. + * The name of the containing module. + */ + private String moduleName; + + /** + * The names of the parameters of this function under test. */ private List parameters = new ArrayList<>(); @@ -37,6 +42,11 @@ public class FunctionUnderTest { */ private boolean hybrid; + /** + * True iff this {@link FunctionUnderTest} likely has a tensor parameter. + */ + private boolean likelyHasTensorParameter; + public FunctionUnderTest(String name) { this.name = name; } @@ -47,10 +57,26 @@ public FunctionUnderTest(String name, boolean hybrid) { } public FunctionUnderTest(String name, String... parameters) { - this.name = name; + this(name); this.addParameters(parameters); } + public FunctionUnderTest(String name, boolean hybrid, String... parameters) { + this(name, hybrid); + this.addParameters(parameters); + } + + public FunctionUnderTest(String name, boolean hybrid, boolean likelyHasTensorParameter, String... parameters) { + this(name, hybrid, parameters); + this.likelyHasTensorParameter = likelyHasTensorParameter; + } + + public FunctionUnderTest(String name, String moduleName, boolean hybrid, boolean likelyHasTensorParameter, String... parameters) { + this(name, hybrid, parameters); + this.moduleName = moduleName; + this.likelyHasTensorParameter = likelyHasTensorParameter; + } + public boolean addParameters(String... parameters) { return this.parameters.addAll(Arrays.asList(parameters)); } @@ -59,6 +85,10 @@ public String getName() { return name; } + public String getModuleName() { + return this.moduleName; + } + public List getParameters() { return Collections.unmodifiableList(parameters); } @@ -67,9 +97,13 @@ public boolean isHybrid() { return hybrid; } + public boolean getLikelyHasTensorParameter() { + return likelyHasTensorParameter; + } + @Override public int hashCode() { - return Objects.hash(name, parameters, hybrid); + return Objects.hash(name, moduleName, parameters, hybrid, likelyHasTensorParameter); } @Override @@ -81,7 +115,9 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; FunctionUnderTest other = (FunctionUnderTest) obj; - return Objects.equals(name, other.name) && Objects.equals(parameters, other.parameters) && Objects.equals(hybrid, other.hybrid); + return Objects.equals(name, other.name) && Objects.equals(moduleName, other.moduleName) + && Objects.equals(parameters, other.parameters) && Objects.equals(hybrid, other.hybrid) + && Objects.equals(likelyHasTensorParameter, other.likelyHasTensorParameter); } /** diff --git a/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/HybridizeFunctionRefactoringTest.java b/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/HybridizeFunctionRefactoringTest.java index 067426975..0f6d3171d 100644 --- a/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/HybridizeFunctionRefactoringTest.java +++ b/edu.cuny.hunter.hybridize.tests/test cases/edu/cuny/hunter/hybridize/tests/HybridizeFunctionRefactoringTest.java @@ -284,6 +284,7 @@ protected static String getSystemPythonpathPaths() { */ private static void installRequirements(Path path) throws IOException, InterruptedException { Path requirements = path.resolve("requirements.txt"); + assertTrue("Requirements file must be present.", requirements.toFile().exists()); // install requirements. runCommand("python3.10", "-m", "pip", "install", "-r", requirements.toString()); @@ -421,20 +422,22 @@ public static void tearDown() { PythonModuleManager.setTesting(false); } - private Entry createPythonNodeFromTestFile(String fileName) throws IOException, MisconfigurationException { - return this.createPythonNodeFromTestFile(fileName, true); + private Entry createPythonNodeFromTestFile(String fileNameWithoutExtension) + throws IOException, MisconfigurationException { + return this.createPythonNodeFromTestFile(fileNameWithoutExtension, true); } - private Entry createPythonNodeFromTestFile(String fileName, boolean input) + private Entry createPythonNodeFromTestFile(String fileNameWithoutExtension, boolean input) throws IOException, MisconfigurationException { - String inputTestFileName = this.getInputTestFileName(fileName); + String inputTestFileName = this.getInputTestFileName(fileNameWithoutExtension); - String contents = input ? this.getFileContents(inputTestFileName) : this.getFileContents(this.getOutputTestFileName(fileName)); + String contents = input ? this.getFileContents(inputTestFileName) + : this.getFileContents(this.getOutputTestFileName(fileNameWithoutExtension)); Path path = getAbsolutionPath(inputTestFileName); File file = path.toFile(); - return createPythonNode(fileName, file, contents); + return createPythonNode(fileNameWithoutExtension, file, contents); } @Override @@ -450,17 +453,31 @@ public void genericbefore() throws Exception { RefactoringCore.getUndoManager().flush(); - String inputTestFileName = this.getInputTestFileName("A"); - Path inputTestFileAbsolutionPath = getAbsolutionPath(inputTestFileName); + String inputTestFileName = this.getInputTestFileName("A"); // There must at least be an A.py file. + Path inputTestFileAbsolutePath = getAbsolutionPath(inputTestFileName); + Path inputTestFileDirectoryAbsolutePath = inputTestFileAbsolutePath.getParent(); - boolean validSourceFile = PythonPathHelper.isValidSourceFile(inputTestFileAbsolutionPath.toString()); - assertTrue("Source file must be valid.", validSourceFile); + // install dependencies. + installRequirements(inputTestFileDirectoryAbsolutePath); - Path inputTestFileDirectoryAbsolutePath = inputTestFileAbsolutionPath.getParent(); + // the number of Python files executed. + int filesRun = 0; - // Run the Python test file. - installRequirements(inputTestFileDirectoryAbsolutePath); - runPython(inputTestFileAbsolutionPath); + File[] pythonFilesInTestFileDirectory = inputTestFileDirectoryAbsolutePath.toFile().listFiles((dir, name) -> name.endsWith(".py")); + + // for each Python file in the test file directory. + for (File file : pythonFilesInTestFileDirectory) { + Path path = file.toPath(); + + boolean validSourceFile = PythonPathHelper.isValidSourceFile(path.toString()); + assertTrue("Source file must be valid.", validSourceFile); + + // Run the Python test file. + runPython(path); + ++filesRun; + } + + assertTrue("Must have executed at least A.py.", filesRun > 0); // Project Python path. String projectPath = inputTestFileDirectoryAbsolutePath.toString(); @@ -480,13 +497,16 @@ public void genericbefore() throws Exception { } /** - * Returns the refactoring available {@link FunctionDef}s found in the test file A.py. The {@link IDocument} represents the contents of - * A.py. + * Returns the refactoring available {@link FunctionDef}s found in the test file X.py, where X is fileNameWithoutExtension. The + * {@link IDocument} represents the contents of X.py. * - * @return The refactoring available {@link FunctionDef}s in A.py represented by the {@link IDocument}. + * @param fileNameWithoutExtension The name of the test file excluding the file extension. + * @return The refactoring available {@link FunctionDef}s in X.py, where X is fileNameWithoutExtension, represented by the + * {@link IDocument}. */ - private Entry> getDocumentToAvailableFunctionDefinitions() throws Exception { - Entry pythonNodeToDocument = this.createPythonNodeFromTestFile("A"); + private Entry> getDocumentToAvailableFunctionDefinitions(String fileNameWithoutExtension) + throws Exception { + Entry pythonNodeToDocument = this.createPythonNodeFromTestFile(fileNameWithoutExtension); // extract function definitions. FunctionExtractor functionExtractor = new FunctionExtractor(); @@ -505,18 +525,20 @@ private Entry> getDocumentToAvailableFunction /** * Returns the {@link Function}s in the test file. * + * @param fileNameWithoutExtension The name of the test file excluding the file extension. * @return The set of {@link Function}s analyzed. */ - private Set getFunctions() throws Exception { - File inputTestFile = this.getInputTestFile(); + private Set getFunctions(String fileNameWithoutExtension) throws Exception { + File inputTestFile = this.getInputTestFile(fileNameWithoutExtension); - Entry> documentToAvailableFunctionDefs = this.getDocumentToAvailableFunctionDefinitions(); + Entry> documentToAvailableFunctionDefs = this + .getDocumentToAvailableFunctionDefinitions(fileNameWithoutExtension); IDocument document = documentToAvailableFunctionDefs.getKey(); Collection availableFunctionDefs = documentToAvailableFunctionDefs.getValue(); Set inputFunctionDefinitions = availableFunctionDefs.stream() - .map(f -> new FunctionDefinition(f, "A", inputTestFile, document, nature)).collect(Collectors.toSet()); + .map(f -> new FunctionDefinition(f, fileNameWithoutExtension, inputTestFile, document, nature)).collect(Collectors.toSet()); HybridizeFunctionRefactoringProcessor processor = new HybridizeFunctionRefactoringProcessor(inputFunctionDefinitions); @@ -529,12 +551,22 @@ private Set getFunctions() throws Exception { } /** - * Return the {@link File} representing A.py. + * Returns the {@link Function}s in the test file A.py. * - * @return The {@link File} representing A.py. + * @return The set of {@link Function}s analyzed. + */ + private Set getFunctions() throws Exception { + return getFunctions("A"); + } + + /** + * Return the {@link File} representing X.py, where X is fileNameWithoutExtension. + * + * @param fileNameWithoutExtension The filename not including the file extension. + * @return The {@link File} representing X.py, where X is fileNameWithoutExtension. */ - private File getInputTestFile() { - String fileName = this.getInputTestFileName("A"); + private File getInputTestFile(String fileNameWithoutExtension) { + String fileName = this.getInputTestFileName(fileNameWithoutExtension); Path path = getAbsolutionPath(fileName); File file = path.toFile(); assertTrue("Test file must exist.", file.exists()); @@ -564,7 +596,6 @@ public void testAmbiguousDefinition() throws Exception { assertNotNull(function); assertFalse(function.isHybrid()); assertFalse(function.getLikelyHasTensorParameter()); - } } @@ -881,7 +912,8 @@ public void testGetDecoratorFQN2() throws Exception { } private void testGetDecoratorFQNInternal() throws Exception { - Entry> documentToAvailableFunctionDefinitions = this.getDocumentToAvailableFunctionDefinitions(); + Entry> documentToAvailableFunctionDefinitions = this + .getDocumentToAvailableFunctionDefinitions("A"); Collection functionDefinitions = documentToAvailableFunctionDefinitions.getValue(); assertNotNull(functionDefinitions); @@ -903,7 +935,7 @@ private void testGetDecoratorFQNInternal() throws Exception { String representationString = NodeUtils.getFullRepresentationString(decoratorFunction); assertEquals("tf.function", representationString); - File inputTestFile = this.getInputTestFile(); + File inputTestFile = this.getInputTestFile("A"); IDocument document = documentToAvailableFunctionDefinitions.getKey(); @@ -1164,6 +1196,199 @@ public void testSameFileSameName2() throws Exception { assertEquals(1, functionNames.size()); } + private void testDifferentFileSameNameHelper(int expectedNumberOfFunctions, int expectedNumberOfFunctionNames, boolean expectedIsHybrid, + boolean expectedHasTensorParameter) throws Exception { + final String[] testFileNamesWithoutExtensions = { "A", "B" }; + Set functions = new HashSet<>(); + + for (String fileName : testFileNamesWithoutExtensions) { + Set functionsFromFile = this.getFunctions(fileName); + assertNotNull(functionsFromFile); + assertEquals(1, functionsFromFile.size()); + + functions.addAll(functionsFromFile); + } + + assertEquals(expectedNumberOfFunctions, functions.size()); + + for (Function func : functions) { + assertNotNull(func); + + assertEquals(expectedIsHybrid, func.isHybrid()); + assertEquals(expectedHasTensorParameter, func.getLikelyHasTensorParameter()); + } + + Set functionNames = new HashSet<>(); + + for (Function func : functions) { + assertNotNull(func); + functionNames.add(func.getIdentifer()); + } + + assertEquals(expectedNumberOfFunctionNames, functionNames.size()); + } + + private void testDifferentFileSameNameHelper(Set functionsToTest, int expectedNumberOfFunctionNames) + throws Exception { + final String[] testFileNamesWithoutExtensions = { "A", "B" }; + Set functions = new HashSet<>(); + + for (String fileName : testFileNamesWithoutExtensions) { + Set functionsFromFile = this.getFunctions(fileName); + assertNotNull(functionsFromFile); + assertEquals(1, functionsFromFile.size()); + + functions.addAll(functionsFromFile); + } + + assertEquals(functionsToTest.size(), functions.size()); + + for (Function func : functions) { + assertNotNull(func); + + // find the corresponding FUT. + FunctionUnderTest fut = null; + int foundCount = 0; + + for (FunctionUnderTest funcUnderTest : functionsToTest) { + if (funcUnderTest.getName().equals(func.getIdentifer()) + && (funcUnderTest.getModuleName() == null || funcUnderTest.getModuleName().equals(func.getContainingModuleName())) + && funcUnderTest.getParameters().size() == func.getNumberOfParameters()) { + // found it. + fut = funcUnderTest; + ++foundCount; + } + } + + assertNotNull("Can't finding matching fuction test specification for: " + func + ".", fut); + assertEquals("Ambiguous FUTs.", 1, foundCount); + + fut.compareTo(func); + + assertEquals(fut.isHybrid(), func.isHybrid()); + assertEquals(fut.getLikelyHasTensorParameter(), func.getLikelyHasTensorParameter()); + } + + Set functionNames = new HashSet<>(); + + for (Function func : functions) { + assertNotNull(func); + functionNames.add(func.getIdentifer()); + } + + assertEquals(expectedNumberOfFunctionNames, functionNames.size()); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName() throws Exception { + testDifferentFileSameNameHelper(2, 2, false, false); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName2() throws Exception { + // NOTE: Both of these functions have the same qualified name. + testDifferentFileSameNameHelper(2, 1, false, false); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName3() throws Exception { + // NOTE: Both of these functions have the same qualified name. + testDifferentFileSameNameHelper(2, 1, false, false); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName4() throws Exception { + testDifferentFileSameNameHelper(2, 2, true, false); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName5() throws Exception { + testDifferentFileSameNameHelper(2, 2, true, true); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName6() throws Exception { + Set functionsToTest = new LinkedHashSet<>(); + + functionsToTest.add(new FunctionUnderTest("Test.b", true, false, "self")); + functionsToTest.add(new FunctionUnderTest("Test2.b", false, false, "self")); + + testDifferentFileSameNameHelper(functionsToTest, 2); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName7() throws Exception { + Set functionsToTest = new LinkedHashSet<>(); + + functionsToTest.add(new FunctionUnderTest("Test.b", true, true, "self", "a")); + functionsToTest.add(new FunctionUnderTest("Test2.b", true, false, "self", "a")); + + testDifferentFileSameNameHelper(functionsToTest, 2); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName8() throws Exception { + Set functionsToTest = new LinkedHashSet<>(); + + functionsToTest.add(new FunctionUnderTest("b", true, false, "a")); + functionsToTest.add(new FunctionUnderTest("b", true, false)); + + // NOTE: Both of these functions have the same qualified name. + testDifferentFileSameNameHelper(functionsToTest, 1); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName9() throws Exception { + Set functionsToTest = new LinkedHashSet<>(); + + functionsToTest.add(new FunctionUnderTest("b", true, false, "a")); + functionsToTest.add(new FunctionUnderTest("b", false, false)); + + // NOTE: Both of these functions have the same qualified name. + testDifferentFileSameNameHelper(functionsToTest, 1); + } + + /** + * Tests #104. This simply tests whether two functions with the same names in different files are processed individually. + */ + @Test + public void testDifferentFileSameName10() throws Exception { + Set functionsToTest = new LinkedHashSet<>(); + + functionsToTest.add(new FunctionUnderTest("b", "A", true, true, "a")); + functionsToTest.add(new FunctionUnderTest("b", "B", true, false, "a")); + + // NOTE: Both of these functions have the same qualified name. + testDifferentFileSameNameHelper(functionsToTest, 1); + } + @Test public void testFunctionEquality() throws Exception { Set functions = this.getFunctions();