Browse Source

Add test on tweet stats

theenglishway (time) 7 năm trước cách đây
mục cha
commit
cf042871d8
3 tập tin đã thay đổi với 39 bổ sung17 xóa
  1. 13 3
      tests/conftest.py
  2. 7 1
      tests/test_parser.py
  3. 19 13
      twhatter/parser/tweet.py

+ 13 - 3
tests/conftest.py

@@ -28,10 +28,11 @@ def tweet_limit():
 class TweetInfo(NamedTuple):
     """Class to hold information about a tweet that is already known"""
     id: int
-    # Name of the original author
     screen_name: str
     user_id: int
-    # Name of the retweeter user
+    comments_nb: int = None
+    retweets_nb: int = None
+    likes_nb: int = None
     retweeter: str = None
 
 @pytest.fixture(scope="session")
@@ -57,7 +58,16 @@ def tweet_collection():
             screen_name="Senficon",
             user_id=14861745,
             retweeter="the_english_way"
-        )
+        ),
+        'stats': TweetInfo(
+            id=1039969574555471873,
+            screen_name="BurgerQuizOff",
+            user_id=949604705772228608,
+            retweeter="the_english_way",
+            comments_nb=12,
+            retweets_nb=176,
+            likes_nb=556
+        ),
     }
 
 

+ 7 - 1
tests/test_parser.py

@@ -18,6 +18,7 @@ class TestTweet:
         "plain",
         "reaction_tweet",
         "with_link",
+        "stats",
     ])
     def test_plain_tweet(self, raw_tweet_factory, tweet_collection, tweet_type):
         tweet_info = tweet_collection[tweet_type]
@@ -26,4 +27,9 @@ class TestTweet:
         assert t
 
         for field, value in tweet_info._asdict().items():
-            assert getattr(t, field) == value
+            # It would be rather complicated to keep some test fixtures values
+            # accurate (e.g. number of likes, retweets, ...) so for most
+            # of them, the expected values are not set on purpose and therefore
+            # not tested
+            if value is not None:
+                assert getattr(t, field) == value

+ 19 - 13
twhatter/parser/tweet.py

@@ -12,20 +12,26 @@ class Tweet:
     screen_name: str
     #: ID of the tweet's original author
     user_id: int
+    #: Number of comments
+    comments_nb: int
+    #: Number of retweets
+    retweets_nb: int
+    #: Number of likes
+    likes_nb: int
+
     timestamp: datetime
-    replies: int
-    retweets: int
-    likes: int
     text: str = field(repr=False)
+
     #: Handle of the tweet's retweeter
     retweeter: str = None
+    #: The soup extracted from the raw HTML
     soup: InitVar[BeautifulSoup] = None
 
     def __post_init__(self, soup):
         self.soup = soup
 
     @staticmethod
-    def _extract_data(soup, distinct_span, data_kw):
+    def _extract_from_span(soup, distinct_span, data_kw):
         return (
             soup.find('span', distinct_span)
                 .find('span', attrs={data_kw: True})
@@ -69,28 +75,28 @@ class Tweet:
         return soup.find('strong', 'fullname').text
 
     @classmethod
-    def extract_retweets(cls, soup):
-        return cls._extract_data(
+    def extract_retweets_nb(cls, soup):
+        return int(cls._extract_from_span(
             soup,
             'ProfileTweet-action--retweet',
             'data-tweet-stat-count'
-        )
+        ))
 
     @classmethod
-    def extract_replies(cls, soup):
-        return cls._extract_data(
+    def extract_comments_nb(cls, soup):
+        return int(cls._extract_from_span(
             soup,
             'ProfileTweet-action--reply',
             'data-tweet-stat-count'
-        )
+        ))
 
     @classmethod
-    def extract_likes(cls, soup):
-        return cls._extract_data(
+    def extract_likes_nb(cls, soup):
+        return int(cls._extract_from_span(
             soup,
             'ProfileTweet-action--favorite',
             'data-tweet-stat-count'
-        )
+        ))
 
     @staticmethod
     def extract_text(soup):