Repository: openlawlibrary/pygls
Pull request #90 (2020-01-06 00:18:11)

types: add __repr__ and __eq__ support to Range and Location
## Description 

This helps debugging and simplify testing, where we can just assert that ranges or locations are equals.

## Code review checklist (for code reviewer to complete)

- [x] Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR)
- [x] Title summarizes what is changing
- [x] Commit messages are meaningful (see [this][commit messages] for details)
- [x] Tests have been included and/or updated, as appropriate
- [ ] Docstrings have been included and/or updated, as appropriate
- [ ] Standalone docs have been updated accordingly
- [x] [CONTRIBUTORS.md][contributors] was updated, as appropriate
- [x] Changelog has been updated, as needed (see [CHANGELOG.md][changelog])

[changelog]: https://github.com/openlawlibrary/pygls/blob/master/CHANGELOG.md
[commit messages]: https://chris.beams.io/posts/git-commit/
[contributors]: https://github.com/openlawlibrary/pygls/blob/master/CONTRIBUTORS.md


danixeee: @perrinjerome Great, thank you. Could you just update [CHANGELOG.md](https://github.com/openlawlibrary/pygls/blob/master/CHANGELOG.md) and [CONTRIBUTORS.md](https://github.com/openlawlibrary/pygls/blob/master/CONTRIBUTORS.md) files, so I can approve / merge this one?
perrinjerome: Thanks @danixeee  ! I added commits to update changelog and contributors.
perrinjerome: It seems build failed on AppVeyor, there's "Build execution time has reached the maximum allowed time for your plan (60 minutes).", maybe we should retry the build ? ( I cannot do this )

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 602dba1..7c7cc49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning][semver].
 
 ## [Unreleased]
 
+### Added
+
+- Add comparisons and repr support to Range and Location types ([#90])
+
+[#90]: https://github.com/openlawlibrary/pygls/pull/90
+
 ## [0.8.1] - 09/05/2019
 
 ### Changed
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index b2c181f..21372a2 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -3,6 +3,7 @@
 - [@augb](https://github.com/augb)
 - [Daniel Elero](https://github.com/danixeee)
 - [Denis Loginov](https://github.com/dinvlad)
+- [Jérome Perrin](https://github.com/perrinjerome)
 - [Max O'Cull](https://github.com/Maxattax97)
 - [Samuel Roeca](https://github.com/pappasam)
 - [Tomoya Tanjo](https://github.com/tom-tan)
diff --git a/pygls/types.py b/pygls/types.py
index b2cd2ed..19f7c28 100644
--- a/pygls/types.py
+++ b/pygls/types.py
@@ -686,6 +686,15 @@ class Location:
         self.uri = uri
         self.range = range
 
+    def __eq__(self, other):
+        return (
+            isinstance(other, Location)
+            and self.uri == other.uri
+            and self.range == other.range)
+
+    def __repr__(self):
+        return "{}:{}".format(self.uri, self.range)
+
 
 class LocationLink:
     def __init__(self,
@@ -753,9 +762,10 @@ class Position:
         self.character = character
 
     def __eq__(self, other):
-        if self.line == other.line and self.character == other.character:
-            return True
-        return False
+        return (
+            isinstance(other, Position)
+            and self.line == other.line
+            and self.character == other.character)
 
     def __ge__(self, other):
         line_gt = self.line > other.line
@@ -824,6 +834,15 @@ class Range:
         self.start = start
         self.end = end
 
+    def __eq__(self, other):
+        return (
+            isinstance(other, Range)
+            and self.start == other.start
+            and self.end == other.end)
+
+    def __repr__(self):
+        return '{}-{}'.format(self.start, self.end)
+
 
 class ReferenceContext:
     def __init__(self, include_declaration: bool):


Test patch:
diff --git a/tests/test_types.py b/tests/test_types.py
new file mode 100644
index 0000000..8728314
--- /dev/null
+++ b/tests/test_types.py
@@ -0,0 +1,49 @@
+############################################################################
+# Original work Copyright 2018 Palantir Technologies, Inc.                 #
+# Original work licensed under the MIT License.                            #
+# See ThirdPartyNotices.txt in the project root for license information.   #
+# All modifications Copyright (c) Open Law Library. All rights reserved.   #
+#                                                                          #
+# Licensed under the Apache License, Version 2.0 (the "License")           #
+# you may not use this file except in compliance with the License.         #
+# You may obtain a copy of the License at                                  #
+#                                                                          #
+#     http: // www.apache.org/licenses/LICENSE-2.0                         #
+#                                                                          #
+# Unless required by applicable law or agreed to in writing, software      #
+# distributed under the License is distributed on an "AS IS" BASIS,        #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and      #
+# limitations under the License.                                           #
+############################################################################
+from pygls.types import (Position, Range, Location)
+
+
+def test_position():
+    assert Position(1, 2) == Position(1, 2)
+    assert Position(1, 2) != Position(2, 2)
+    assert Position(1, 2) <= Position(2, 2)
+    assert Position(2, 2) >= Position(2, 0)
+    assert Position(1, 2) != 'something else'
+    assert "1:2" == repr(Position(1, 2))
+
+
+def test_range():
+    assert Range(Position(1, 2), Position(3, 4)) \
+        == Range(Position(1, 2), Position(3, 4))
+    assert Range(Position(0, 2), Position(3, 4)) \
+        != Range(Position(1, 2), Position(3, 4))
+    assert Range(Position(0, 2), Position(3, 4)) != 'something else'
+    assert "1:2-3:4" == repr(Range(Position(1, 2), Position(3, 4)))
+
+
+def test_location():
+    assert Location(uri="file:///document.txt", range=Range(Position(1, 2), Position(3, 4))) \
+        == Location(uri="file:///document.txt", range=Range(Position(1, 2), Position(3, 4)))
+    assert Location(uri="file:///document.txt", range=Range(Position(1, 2), Position(3, 4))) \
+        != Location(uri="file:///another.txt", range=Range(Position(1, 2), Position(3, 4)))
+    assert Location(uri="file:///document.txt", range=Range(Position(1, 2), Position(3, 4))) \
+        != 'something else'
+    assert "file:///document.txt:1:2-3:4" == repr(Location(
+                uri="file:///document.txt",
+                range=Range(Position(1, 2), Position(3, 4))))