Repository: psychopy/psychopy

Issue:
404 errors on some of the page in the HELP menus
Version used
- psychopy: 2021.2.3

https://www.psychopy.org/builder/builder.html
https://www.psychopy.org/api/api.html


Discussion:

Resolving patch:
diff --git a/psychopy/app/urls.py b/psychopy/app/urls.py
--- a/psychopy/app/urls.py
+++ b/psychopy/app/urls.py
@@ -6,7 +6,7 @@
 urls = dict()
 
 # links based on string names
-urls['builder'] = "https://www.psychopy.org/builder/builder.html"
+urls['builder'] = "https://www.psychopy.org/builder"
 urls['builder.loops'] = "https://www.psychopy.org/builder/flow.html#loops"
 # NB. builder components get their urls defined by the component code
 # (so a custom component can have a url)
@@ -24,7 +24,7 @@
 
 # links keyed by wxIDs (e.g. menu item IDs)
 urls['psychopyHome'] = "https://www.psychopy.org/"
-urls['psychopyReference'] = "https://www.psychopy.org/api/api.html"
+urls['psychopyReference'] = "https://www.psychopy.org/api"
 urls['coderTutorial'] = "https://www.psychopy.org/coder/tutorial1.html"
 urls['builderHelp'] = urls['builder']
 urls['builderDemos'] = "http://code.google.com/p/psychopy/downloads/list?can=2&q=demos"


Test patch:
diff --git a/psychopy/tests/test_visual/test_color.py b/psychopy/tests/test_misc/test_color.py
similarity index 100%
rename from psychopy/tests/test_visual/test_color.py
rename to psychopy/tests/test_misc/test_color.py
diff --git a/psychopy/tests/test_misc/test_layout.py b/psychopy/tests/test_misc/test_layout.py
new file mode 100644
--- /dev/null
+++ b/psychopy/tests/test_misc/test_layout.py
@@ -0,0 +1,49 @@
+import numpy
+from psychopy import layout, visual
+
+
+class TestVector:
+    def setup(self):
+        self.win = visual.Window(size=(128, 64), monitor="testMonitor")
+
+    def teardown(self):
+        self.win.close()
+        del self.win
+
+    def test_values(self):
+        """
+        Check that Vector objects with various values return as intended in a variety of unit spaces.
+        """
+        # List of objects with their intended values in various spaces
+        cases = [
+            # (1, 1) height
+            (layout.Vector((1, 1), 'height', self.win),
+             {'pix': (64, 64), 'height': (1, 1), 'norm': (1, 2), 'cm': (1.875, 1.875)}),
+            # (1, 1) norm
+            (layout.Vector((1, 1), 'norm', self.win),
+             {'pix': (64, 32), 'height': (1, 0.5), 'norm': (1, 1), 'cm': (1.875, 0.9375)}),
+            # (1, 1) pix
+            (layout.Vector((1, 1), 'pix', self.win),
+             {'pix': (1, 1), 'height': (1/64, 1/64), 'norm': (1/64, 1/32), 'cm': (1.875/64, 1.875/64)}),
+            # (1, 1) cm
+            (layout.Vector((1, 1), 'cm', self.win),
+             {'pix': (64/1.875, 64/1.875), 'height': (1/1.875, 1/1.875), 'norm': (1/1.875, 1/0.9375), 'cm': (1, 1)}),
+            # Check ratio of pt to cm
+            (layout.Vector(1, 'pt', self.win),
+             {'pt': 1, 'cm': 0.03527778}),
+            # Negative values
+            (layout.Vector((-1, -1), 'height', self.win),
+             {'pix': (-64, -64), 'height': (-1, -1), 'norm': (-1, -2), 'cm': (-1.875, -1.875)}),
+        ]
+
+        # Check that each object returns the correct value in each space specified
+        for obj, ans in cases:
+            for space in ans:
+                # Convert both value and answer to numpy arrays and round to 5dp
+                val = numpy.array(getattr(obj, space)).round(5)
+                thisAns = numpy.array(ans[space]).round(5)
+                # Check that they match
+                assert (val == thisAns).all(), (
+                    f"Vector of {obj._requested} in {obj._requestedUnits} should return {ans[space]} in {space} units, "
+                    f"but instead returned {val}"
+                )