diff --git a/rtv/content.py b/rtv/content.py index e3ee69f..cac7358 100644 --- a/rtv/content.py +++ b/rtv/content.py @@ -92,6 +92,7 @@ class Content(object): data['type'] = 'MoreComments' data['count'] = comment.count data['body'] = 'More comments' + data['hidden'] = True else: author = getattr(comment, 'author', '[deleted]') name = getattr(author, 'name', '[deleted]') @@ -114,6 +115,7 @@ class Content(object): data['gold'] = comment.gilded > 0 data['permalink'] = permalink data['stickied'] = stickied + data['hidden'] = False return data @@ -154,6 +156,7 @@ class Content(object): data['gold'] = sub.gilded > 0 data['nsfw'] = sub.over_18 data['stickied'] = sub.stickied + data['hidden'] = False data['index'] = None # This is filled in later by the method caller if sub.url.split('/r/')[-1] == sub.permalink.split('/r/')[-1]: @@ -317,7 +320,8 @@ class SubmissionContent(Content): 'cache': cache, 'count': count, 'level': data['level'], - 'body': 'Hidden'} + 'body': 'Hidden', + 'hidden': True} self._comment_data[index:index + len(cache)] = [comment] diff --git a/rtv/objects.py b/rtv/objects.py index 7e3fab7..8317cb8 100644 --- a/rtv/objects.py +++ b/rtv/objects.py @@ -315,7 +315,8 @@ class Navigator(object): valid_page_cb, page_index=0, cursor_index=0, - inverted=False): + inverted=False, + top_item_height=None): """ Params: valid_page_callback (func): This function, usually `Content.get`, @@ -331,11 +332,16 @@ class Navigator(object): inverted - The page is drawn from the bottom of the screen, starting with the page index, up to the top of the screen. + top_item_height (int): If this is set to a non-null value + The number of columns that the top-most item + should utilize if non-inverted. This is used for a special mode + where all items are drawn non-inverted except for the top one. """ self.page_index = page_index self.cursor_index = cursor_index self.inverted = inverted + self.top_item_height = top_item_height self._page_cb = valid_page_cb @property @@ -396,15 +402,21 @@ class Navigator(object): # Flip the orientation and reset the cursor self.flip(self.cursor_index) self.cursor_index = 0 + self.top_item_height = None redraw = True else: if self.cursor_index > 0: self.cursor_index -= 1 + if self.top_item_height and self.cursor_index == 0: + # Selecting the partially displayed item + self.top_item_height = None + redraw = True else: self.page_index -= self.step if self._is_valid(self.absolute_index): # We have reached the beginning of the page - move the # index + self.top_item_height = None redraw = True else: self.page_index += self.step @@ -478,6 +490,7 @@ class Navigator(object): self.page_index += (self.step * n_windows) self.cursor_index = n_windows self.inverted = not self.inverted + self.top_item_height = None def _is_valid(self, page_index): """ diff --git a/rtv/page.py b/rtv/page.py index 53ac2c8..a5c8184 100644 --- a/rtv/page.py +++ b/rtv/page.py @@ -327,29 +327,46 @@ class Page(object): # If not inverted, align the first submission with the top and draw # downwards. If inverted, align the first submission with the bottom # and draw upwards. + cancel_inverted = True current_row = (win_n_rows - 1) if inverted else 0 available_rows = (win_n_rows - 1) if inverted else win_n_rows + top_item_height = None if inverted else self.nav.top_item_height for data in self.content.iterate(page_index, step, win_n_cols - 2): subwin_n_rows = min(available_rows, data['n_rows']) + subwin_inverted = inverted + if top_item_height is not None: + # Special case: draw the page as non-inverted, except for the + # top element. This element will be drawn as inverted with a + # restricted height + subwin_n_rows = min(subwin_n_rows, top_item_height) + subwin_inverted = True + top_item_height = None subwin_n_cols = win_n_cols - data['offset'] start = current_row - subwin_n_rows if inverted else current_row subwindow = window.derwin( subwin_n_rows, subwin_n_cols, start, data['offset']) - attr = self._draw_item(subwindow, data, inverted) + attr = self._draw_item(subwindow, data, subwin_inverted) self._subwindows.append((subwindow, attr)) available_rows -= (subwin_n_rows + 1) # Add one for the blank line current_row += step * (subwin_n_rows + 1) if available_rows <= 0: + # Indicate the page is full and we can keep the inverted screen. + cancel_inverted = False break - else: - # If the page is not full we need to make sure that it is NOT + + if len(self._subwindows) == 1: + # Never draw inverted if only one subwindow. The top of the + # subwindow should always be aligned with the top of the screen. + cancel_inverted = True + + if cancel_inverted and self.nav.inverted: + # In some cases we need to make sure that the screen is NOT # inverted. Unfortunately, this currently means drawing the whole # page over again. Could not think of a better way to pre-determine # if the content will fill up the page, given that it is dependent # on the size of the terminal. - if self.nav.inverted: - self.nav.flip((len(self._subwindows) - 1)) - self._draw_content() + self.nav.flip((len(self._subwindows) - 1)) + self._draw_content() self._row = n_rows diff --git a/rtv/submission.py b/rtv/submission.py index 091ddf5..fd4c954 100644 --- a/rtv/submission.py +++ b/rtv/submission.py @@ -33,11 +33,19 @@ class SubmissionPage(Page): current_index = self.nav.absolute_index self.content.toggle(current_index) + + # This logic handles a display edge case after a comment toggle. We want + # to make sure that when we re-draw the page, the cursor stays at its + # current absolute position on the screen. In order to do this, apply + # a fixed offset if, while inverted, we either try to hide the bottom + # comment or toggle any of the middle comments. if self.nav.inverted: - # Reset the navigator so that the cursor is at the bottom of the - # page. This is a workaround to handle if folding the comment - # causes the cursor index to go out of bounds. - self.nav.page_index, self.nav.cursor_index = current_index, 0 + data = self.content.get(current_index) + if data['hidden'] or self.nav.cursor_index != 0: + window = self._subwindows[-1][0] + n_rows, _ = window.getmaxyx() + self.nav.flip(len(self._subwindows) - 1) + self.nav.top_item_height = n_rows @SubmissionController.register(Command('SUBMISSION_EXIT')) def exit_submission(self): @@ -155,6 +163,16 @@ class SubmissionPage(Page): valid_rows = range(0, n_rows) offset = 0 if not inverted else -(data['n_rows'] - n_rows) + # If there isn't enough space to fit the comment body on the screen, + # replace the last line with a notification. + split_body = data['split_body'] + if data['n_rows'] > n_rows: + # Only when there is a single comment on the page and not inverted + if not inverted and len(self._subwindows) == 0: + cutoff = data['n_rows'] - n_rows + 1 + split_body = split_body[:-cutoff] + split_body.append('(Not enough space to display)') + row = offset if row in valid_rows: @@ -178,7 +196,7 @@ class SubmissionPage(Page): text, attr = self.term.stickied self.term.add_line(win, text, attr=attr) - for row, text in enumerate(data['split_body'], start=offset+1): + for row, text in enumerate(split_body, start=offset+1): if row in valid_rows: self.term.add_line(win, text, row, 1) diff --git a/tests/cassettes/test_submission_comment_not_enough_space.yaml b/tests/cassettes/test_submission_comment_not_enough_space.yaml new file mode 100644 index 0000000..da74209 --- /dev/null +++ b/tests/cassettes/test_submission_comment_not_enough_space.yaml @@ -0,0 +1,173 @@ +interactions: +- request: + body: null + headers: + Accept: ['*/*'] + Accept-Encoding: ['gzip, deflate, compress'] + User-Agent: [!!python/unicode rtv test suite PRAW/3.3.0 Python/2.7.6 Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty] + method: !!python/unicode GET + uri: https://www.reddit.com/r/Python/comments/2xmo63.json + response: + body: + string: !!binary | + H4sIAE6GGFcC/+1djXPbNrL/VxDfzTmZkyWR1Gc6nU7apBd30o9Jc5fXl3T0IBGSEJEEww856s39 + 7293AVKULNkWSSm+1G1napHE12L3t4vFYvHu32cLGbhnT9nZKxknMpidNdiZyxMOj/595it3zuM5 + vsbnk7n03EgE8PvdumDibJRxlc8lfnI2k8k8HTcnyscPxjwIhDsar+BVkHoePPKFK/lI+GOBFf37 + P/AoTseRcF2ZYAW/rJK5CrBwLLxpIj4lo3nie+sKssdZBz25EHHhdTqbiTiBVmMV4UfmeRqLaBSJ + EB7i1+9+p6omaSRG1KX1l54MFqOpx2U0Mu2YF5KGbn/yVY+GP42UPzIUMZ/MgFg0sDb84BEQb0k/ + kygVSExPThb0YMq9GJ/oHkHHeKyCwjB4CmSIsL2JXEpP/sETqYJROOd/iBG1vtXrgPsCP0+c0bqH + 8URF+NTuDrHOMIzUcms+4EE0sgaFLs2l69J8Zw9gRv1xwCVOApE8n7CRJknSHdkf5+0VvoNeJRsj + LJBzEsejicfja+Pc/95VV0QWpCdw5k0zuMVUXFN+TWhfLblnKL1uAARgspAbn+K8rj+Q8QhZbuu9 + Hrn5JBSRz3GcSIxW1NI83AIh8EWQxC09IS0+CukFsFXkywA6s5TiCsg/BQqMI3UVgyyONGVbxNpq + i1tgasQom9Ts4QSGpEludeyuPexYPbuJ9EojmrF5koTx01ZrLZotX07mXHgXHv+DR60oWWJrG1Ox + yfkfUx7xAKCi2G4iE49Y7hnT42LZuJgeF4NxsWxczIj4usOjNJlkne51nazTIU6uZtg0XKpEjCLk + fXjYbg578DRI/VFGWnja6cCzpYy32A6/WjNLxk0a71IZz+ljfPyf/yAjccAUFDfz4VhMNZH1Fw1W + B2ZaG2VuEqIduLmPf0m8TA1F0d+CRSCFJ+nBw0geRvIwkttHQj3caTVsaRZd6SS0hysnxUK3GAG3 + q/wxd0GxJSqKsbqQA4ny0VsjaGmQ9sf4KtfvWHyXdp+oIMGnUSxBQSX4Bjs1Vi7+efabiFkylzGL + 5yr1XHalogW7Aj3BuOcxUBgM6vwAXYnZ43cqmQOmhypMPR6xf333K4OOsTgNcTjCZTxmV8Lzfn+c + KZxQhs1wFfKmVC0RtDwA/ThpRWIqYEATge9HMogTaKuJNt5flpP4wtT35EnzffA+uJyylUqhVT5Z + 8JlgrowYdlf54gp6I9hYBKBM5jAKwZCwLFIqaWAh5svZPGFzmC2WKPbuQ+qH8Fmk0hkMj03FFfOB + emyuVBhX6LT4xP3QE/ETNk4TBiTD/iUS6BeqOJZjTzRxqq7ZRYdYPjhfmRl89jcv+cqVS0bff/3+ + zHffn/1tlnyFz0P845BZxUKczWF8UFNpGhQmTvfljryCrbc4FnjSpL+p/zjx+WDq44B6hppNtx7n + jUy1Ht1+1iiOmv6GmcVfJN2710W5pU9QkIEOQcHomu2+w7zdtBednuM4PTK9bjAAr5tsjtPpmnK7 + rKrGTnN9p1FmLL672WGHIXKGk5UR+RfugW2rflBzmoLrkGxFK5t0XVVIdlUmvSS2aEJvS+03J8aT + u3SpMh9vqLRSfGx1e50yfGz3Tbl7y8c5c1Xm49ssC2vRs8hzk7Oxg+VL8PE/YbnoAddwBOAwFEHc + YDxYqUCwCQ8MDBpkRWhcSs4AbJ8i+DP456/4K/8AeO3vd1nHNmd6iXlC6Sg70B36LhJZzRPl0t/l + qWDEMKtIt6YbKCehmwhXRkIdqztol5DQtt035eqRUOcYIpoJTmURdflSAbMt1R4Jnff6blFCrbKa + 5qVYPWIzJHcG4w12hWzMxwrMFZ8v0G2DIL9mQQ42C9heLBQKjCBi8CRa4UdYRAZgA8UBD79Bln73 + WnhiyYOEJSkgDvRBW9lodQkgPYkcMTBYQ0ncmsooTi4S6YsLNFYvwCyTZHM9eU/ceEKZPiZpdsh9 + 1vaGdXowmfQYrhGd2iMrtKqO3lQOZRCgbbfb1uEIYPcd25SrBQEse9Old088Dn9i34mlBjNeC3zu + 2y7ZgaSqo8IikpYF0jdzHixA61+eg472lFqAtMN6kyzmRMF6MFJXp/YB5H36GyxXv/qLM/zqhr5V + BoZs9koDg9Xp29r/fxgwDLpDU64WYDiK8Z6xWWXWfucCtgMBft/Dz9uWQVl+3mjnhDybt1udH4uS + XY4f7W63FD92TLn7y48Zm1Tmx7tB7c79aAsrKsGaLyW6HhrkGj5fChaCaZWomSB3IxhYPi6TzG6k + sdz00mzKJ9DXBN176y3J18RIBf9dvoF5BfoUgJFdJuTziI0xiK4P5AFY4LnsI0ErZ2MeC5flfBlD + KbAQXaFBdiwmHKYHnl2BVYYfKh+6i81Txy7ZhJy0PEn4ZI5+SuiGn35isYhjICw1tRAC7UzycY75 + ZDGDDsPjK7ABBHUQq4NvtduVaqduTOmzWPoS3bBrr69ozprsGSjr4Hsh3CcN8k9C2RVzpRucJ5mn + dk2qjEYwTF/qjmV7sGgawwoUnZuXP/5MffTBUmXSxyrQFAWGSB4hBWikntL+WJg1XCizKXQBB6Xp + gX7bWbqKC87bU+tOw2R7DPW1Rr0f/Pdl8mBO5PvGi5V104aWLqGb7GG37/RL6KZeb2jK1aObrIdF + 1MNIHkbyMJLPPJKDnQ324pM1x0InsoD1/tYfcR9f5W5brKiEBfwK1vAxQ2KQdgP9l4L65TGLRKw8 + qAx1tNPsNC3chnBB0805aPYQqQX/Z2OPBwvQdlP5icwJ+JRRYzBErfVEAERhaQg1woRqVydW6DSZ + 9ipQOdqUnwsvfJQb4zOVJAL9nLgNHomPqYgT/fFSIYdRf9aamtwlPoeB8MCMA7+V2rpB3ykoZtq8 + X5srYOfICfYtVipontwvfP+Ifxcj9dB5KbqMKs1PVVspF9SytpIzsAfDEg5np9tpm3K12ErWEdbx + OaJURrHXwhcu3xPYYLeVTzhfFbhQFoBX9FRnPP02s9avhIzcBiwTggnKFsdYGeQ4dFkaiQPG2yVq + bR0olgEQZzxesIsLCjhCAz4EmQto2QDLGtcFIeBJCpXA8gGahgqvCwH+RE43UQ8zZYqPBfuQwmqC + QydgcRWdOhDjeCS8K4yclLqV4WND55aBj541aA9LwIfjtE25+wsfmVxXho+7G0FWuJTrYLWz8h7q + N8g48B9o1HSWOSWM2yWGZb7LI1jby3HEo1WTvQ/Mfip8HDf1Z00VzVokH7bVHgyQ658rEzQIrCqn + oLuR1bHiKfQpU9PQQX8sIqam+aEH4yk4B4lI0T9xalQ4lBhYcHun+QbKUGO3fkbyeW2XuQAlFamb + A1FO5crosKHYyqBDZ9AflolnsYZDU64WdDjKJkEmqZXR4UbjwgrDCcW5ZIBQNtrsH0jlBuk3cpei + oeoLFqAP9VvtV8wtXNJdICzwsS9i9JumYZO9eykicY5SFMOUiSCeq6SZB6zIpvRnaURhGFPR/V/r + h1kzDGZPTizq1Ye5S/j3DE63jWTJhW+LPLuFvowwbmqGMsJoO5ZVIozZHnYcU64WYTxKbFkmJZWF + 8QBVrZbOpCiZePKujGS+FKsGoni2dKV1czBV6IMHgxHYEp/86/JH4NTABfrH7KsnZNGTqUpRVWAc + RujumcDkaaNRRBHUNV6xKNXm5/uzTOOJJMWQ/iws6/2ZXq7OYQXsqyXZmtlJAdrocOWUgv0TMJQn + RBnadsFQTh6ZVbm2qfGMM9YM/cI9MqNpo2TZgpHBzEQkmWYHDXcUoJSX4hDNp8hhF+YgA4xhNsNF + vczPaYABPJWf4HOQ5wZY1jCPYL0LlF+2gGeoNzPRhz6e+ya4FD6MtA0ObQQph77GpELNkQmfB/A/ + BIWT76SVmfw9BsRh/ECQ9TFVUHg3X6w/OAp/FPavbuCTwlfH55e8sRJ8Ux3fi4q+FL7bdpmlmD10 + OnUuxXr3ctPrYBe4FQ5nvVpUypu5+PbbO+qQsq6j30TYAMRAEUFWjYGztMQ32a8CyiJy0Jul9HMk + abLXL37NNo9RToUPAq1ODYG19r26GJppLy2G1nBgO2XE0GqbcrWI4TE8Ijm7VpaJvWueXbFQfSxa + QigucREN6o6YZ4pBGLQrkEWjo6JCHYthnsxfAagn85wPM42Zn7Z5E/GJoMCHxxQvEYkJarwJhrMA + ZydPnurvGPseW3p/1krjqAXs2gK19h6GA5Al2LCBmgsZE2Yz9cxhE12Ogfrk7ghqjVajUMkgeXwO + Zb/+2mq2uXXeYOcw3lh5mN8ikmES4yP44PzJ4ye72vbkuKVVu9PstDD7Q64pW+EC02jEQA7QaK3R + SAaAyCNQzXlPuxiBBn3d7tO6txHYC1GA9Bohx0ZynCJJH+OPJ83tco8xGgYEHaXtCN21e459S3+z + DouQOncMosESa92La5TCJClN41k+UusDat20URi65jb2NYNyFOgzGj2m7ugXI5yVBsO0LR7M3tfv + zkf0aDQ6BzzwxFJ4X7ezHl9SBS9IOthPKqsbv3fZOZp457Q6yaQvM/qwdhLFiadAz2sDEqyvWAif + ZFCfnYSR6P2KbVc+hk49A6xhr2SQfqJvXjy/fPOUfQ+GLW6w5bFJT3VUmLEAAQAjOZUTNPbQwabN + 6g2TGi1vV4JIIwPHtJFIR5HnrQ+tRctDL70npkkLlVwrDVsRRjudWk/WAmc7lg7Xz9TdDeuIcdeL + hCLerZ9u4h4+XmMf/srxb1tuH6/9mTkG5o8auir8cwsTd32SdQj/Nli5q++lhO/aSG/GzYqYebxu + 34afu7DziL25jqN7MfSovdiFp4diac57GabmDzax9UZczcsgmuY/jI27+whr0TNQAYt3IAZVeQs8 + 7yn2eRG78upgY71WanXQ7zuljvEMhqZcLauD/heySJ8vYDiNGhYkP4x5FK06ve7dliRlfb3ZTuRE + Ka/ZbOoIqCt0NU1x248zDELXMUQnti4O6FllKcpmrawU2cNet9Qau9fv17nG/mJcXfZC1CJFzj96 + z7pvHWfw4m5iVHYz8yc5EcCkTLqCe8SVyJ1ce3LZ019ocfBGKTbmLruio+bnCaYUSnSWJ3ly4/3W + Hu/Rl5uDyBX/1mAqS2TGAWUlEiylgV3mOOCw3TblapFI5wuRyGAm63E+v5JJ4okXoQowNWnjLkJZ + NuTo2ZU+4u2zSRphI96qeOoJg9aQ9uy7VxjaQtnN9J68y/2A1rKxicSD8XhQOACZoa0n/BQWntLF + RBFNPCEVkpEKZR6xp6cOMTDjXFvkpx5vZWnPuKu8tFvdTomgYXtg9025WqT9fiapOFzaw/jDtBZp + n3jy4kMawOQdV9T/oZROmogbN7jpjHyMfI+KbR3rbo4BSNqLB5b+u6Vj6qXPFmK1Xsxl0nGYIBOd + y4txiTHkIn+HsVQW0owpSgupDebu/v3gs++U7yPYvEJXB/aQOGOH0A6dgannQWgLQvtRuPUkrfh1 + LiM1l7Mjy+wlJVwKVMISVC/oV5mrK+ZjFPolo2O++IwcKzrgnJj+xxVoojBRIS4OqTTuxIoIWF5g + KDqtE9EJi2eHQYnFMO7ZzBPaNg1FBBX6GDiBamzsCZ9OIIsgU5Vkqv8EHdH9m3gK7WIP88XhX0aH + JnwcM+Ny0uHwoGFNDEjhqDX2BjqCISwU5Ye/0ZXXZD9Bz1UA/TOpGsHydiPuc5Ai0r2uQM6HBn3Q + w0K4RAfuJRfQsj54DfNPLrJpJKCGNEQD3mWvn/3IfGDCaKXXHBjJg3Q0QT1bf57eWLmvs75nufNF + MMKesd3OG5V1RoZJ5XVGtzcc7NUZ+w27YW9gyn3BOuJPfCDYinqLD1iourZLBPd/ARt19FwspYd1 + 7oiLihzPzhn5rHxc1FsOgkpiDMunNJxFmPEDN0f1tsVTukTkhHB8a38qQ0A2UeUhYDDslAgTd9pt + y5SrBQKOEr+UsdXxubhOy+250spKmkztHPT2TEcAwOpjJhJ9fpBNIsAfSiz6AlUl5X6XFBunX7Es + aSaPEwELFjrOMLa//f7V5Bfa1TqhIBw2pj0adc8w8f32CY6dY944ubXzC2q4nvMbG5BWTjB7ZdLQ + 28PhoOY09PdQNx+u0eKZpM2+ylgQrwJ3TLbA8SAAt7fPYzCmQTDA2gZWecTIgfFBjRvMTV0TM5Wg + m2UiooRLtHExAQLGuqP5ay6c0Ll30wRPuegcDf83SaNYxP+XnYDUNjzFDGEAQJ6lC88WBMzc7nCg + r6YyXiABcvfLzYTYAxaX6/KH0whryaIsNLmolezRYaSrDCUZ65aGEsex2iWgxGl3HFPuAUoKUJL0 + e59qgZIfxWLOfXlcLLnUaeESmFtQsCGUYSblSX4CCXRhDCt1F/NxT9NTy/rhHawsUdkMlpeoLshG + GYnq2abcFyxRf+KFs2217XYt2HDAydRUzGs5VfRsHCsvTYS3esQu8by0B/1zV3h304LO4MEi9pfX + z97iDgruluh0BXMeuSir0LFCTB8mx9T+RTzgCIu6KZ9g+KHgOnlmLD+HWfEZRlgVq3KOKo1VnaFd + xsnn2O1OnU6+o6zwM9avLG4hCIVI4/agTQlyjqeOn5k8QSoUAXqFYBaEPvOG7m6dM2idsSDQB4IR + oL5hlNIpEFA1+dWBYcn+DLSFqr3VlwVTl1gVI6Eox0gSrYhdFTrydSi6aLKnz08tghXGn1v0ZehQ + CKa6kR5VBXYTjssIrNPv37CTu19g24Phw87tdYxYufpy9soYocerIstqEy2OBxJZdC5dsXNJHuRT + q8pdXagsGtlUlBaNTjeLHzxMNKyeXWfc4f0UjT+x3W0FliB+qyzkB9jd/ge+jquDxwOsqIS0v+Rz + zmIVRWCVfi+ER1vNpJjmYrKg27JQCeozTHj2BV3gnJIZebi9PTW2JpmsM7PLrRPYx5TXAqxVfaaG + opvoEnn4kA7LFLIRguVK2T4y7dtk+qpZ5io0IrQ9jL911eNUYgN55BSdMYonEU8m8wZLdKZWzDOS + f0GXAYDSNjFWHBUxppHHtB14zhH3CB6dGOb+C2hfMFxONAeVcT6TxtI4b7XbVgkTyB5YtilXC84P + jrFmyWCjMlS9BvN25SsY0f9cXoeoOu2R337+J/v1zc+vXrAff2OXz188oxzXP2By0gVMLtBZhzpf + ZrHNmOWZ/OJ4AEIb5Oc+RRZxNkP/vQjoxgroyiziwPMRsh5JEvI/HnJgz64E8i2mRprDaqEARWS/ + c4xC4sGMPPiCOF1nRsRwTpTWR+zEWHKdSkVBKuxNHEa4QuR5LQTcXgjdgZCVAWFDVZYBhPag1KXc + dn9Y96XcD4bfEUdysOFnW+HHem6CPsDw+2gtr4qwWtbhisGJz978SGI+LRofdLMP6md9r8/aAiFj + gVLQx+lsJmI6Dn1imKup11UxJZ/50pjSbXfsMulqbVhN1piu9iiO0YxFK4vFxU9SXlyXg13WRVkx + +A2jlDEqaAoGM20CLpWknH+viQnoSNUEEAJdgmSzZqkPyTxHk5X5K8rJUNB5FCIU6bsY0MInYz1R + 8K3SV0Vkd39h2oasWgxFBrbHJ+hTPHXm6ntMiariugmaZcTV7pTy/djDbq2+n4dbvh5G8jCSh5F8 + 7pEcbCpb8aqm+3H2xi3pcLWB2rjYq6zTQZ77sNQNAo5piih1LyklfQHTrjghWDXPUrqECa+Tot+U + B4jxK7469f6JLCzbaxxFZTWcMUFpNex0Or0Sh8GddrdnytWiho9yyUPGupUlhH8Axoh0ko1dImL3 + 10sXJBAWLiEixSgVOqmnj+vhrQS4M8716TjKhr3OtqUYVMVNBL0+LKcvZzMrNIyvx+Ra6GkjL1Ae + fUdn44KV9iQLoF3z1C624w644Bm7deDVBbEIk6UE0e70S1x767SdnilXiyAeZfmaCUhlQbyC9c0C + GHCOp1P3SGO0CgZ1KKzn5oQLsRVyFIaTUQAZ0FlFqyy/XShDs/dC+zWczsGceqlZrbPVub+IgKW4 + 3xqWcQgD91s1O4Tr5/6MIStz/y1qKIr+WJ8fRgJh4RKMf8mkz2d4AkLisZVEYGpLulwrd2iQb4Ky + a79OluwixVPUEbIEuwhznMXX+va+7IL2lb5GTAZhqo+IKX32u3jIG6NUfsLz5976Knh4hFxMMZ0b + XC2SyWdQWmvyFA617CdTUboK20Y3UG5PiWvEzJuvn6iVIWEDhstBQs8p489t2wNTrhZIOIpCzES1 + MiTcvHb7mEYbiFBWFb5VXG8A5CaU1Ikl9LQix0HT0eob7WkES5PPcBfBHKjCLA1iIukGvBML64E9 + L5iMe0dQXTKKOF1OMtpOiXAKkAzblKtFMo6iLDOWrSwZ+5VlnZsdb0xcJdfu+Sa65yXld4ylucoJ + uwStZ7c5FViRcqqgVSY+iUma0B1KDDPCC+6SU39FRxKgProSEjQE3m9pIjVilR111BKH/ghKHG8q + xz7jA32ZkohOridPTpo9WvM6tQpSfjvVKov7BgiXEXe73+uXUIT2cDAw5WoR94edkuOO5GAPsG0t + evUsLA4Iloim7fXp5bPywLl2/dDZeM5myMAUJ9Uw7tSA6Qu+wTydgRpOx6eOJi32sWDp362vVXEj + n93SuNFtW/3O4bjh2JZjytWFG/WbCRkbVmb9RbQKgZIjjJ27zvL1mgqFeyLXejFLM0AxmJeFE4ma + yVBLujoomCFgofJzVQJtTaVJufLYU7AcbeRKrAG26pSnXoInsTWfNVABquBJttSbpniLfZO9ff7b + m01XFXGA1e0Od/giaxWu28ixR5t/FgpVleVN1Cwjy/awPyy1TdMemnJ1yfKDDfAwkjuM5HBrZuz5 + 9WwSvFYrGMFLMPs90DiNbUwn5doLhpT3qyqov9UnVun8BWeTOY/87EbgR4yuUduKc8dcNTHM1axB + 507wLRkZuIjRcV8AZvSDpWF2rkSHXJrTJPjSF7gFImP/mwNXdTQt5UH7zsPdjkqvfdhVITlnt9KQ + 3OtZ9n7z6uzy+Su6R2MHKDt9x5SsC5RrN7ByAaksjXdfW9h2d1KLu/IV5eUnJjU7Dtm12WCn0w3V + WcpGdO8h89Ht2YlSXn5UKwLDHgYbYL4INPkDcQXFqEkoh7dI6xpMxvAGsTSGgiTRCg2Wv4Jp4Srz + FV6wtX1BN370M1ga0ZVEymfFp8rz1BWZIPhhlOo7svAMB6a6i5+2WqHEekLelKolgpYH7BUnLVMt + jLKJ4oxmkXmEm37vSQLujhOG0OWRYnMOihsVp52LPWbkrdOzp9xhM4bFNnIZ3nn6NDUPKkI9pmyH + W3NfGSo3lGUZqOwOrG4Z69UeOqZcLUB5DId1DlqVgfIWs6XOpehLsUK1bfyzwbW1F7u42LzqCBNx + o6QD641BCOccdL05AUibIyh2F9hclr1DsxLp71CfaaMs4xNcVMVsJYBJUXZQhkJPYMbuGdALzQTd + Eby8EqrL9jK1jCFq0EWo32zh6zXphQGg2B5wFer7s6yO/EZefRUoSoy/dd2zPpib4xQe1IPJ1U+A + MjddBbkuhR08FJYrmm+1zPvWAcb7Ov97APwAlqCB0pWiWfXrJ5ssgo/XbIK/6mWVygi+YVmVQnDL + apczdm3bMSVrwfD76YE4fLVri5pSso8/8CgQ6rgKYxohg+SAcWpH/Hbz1eXBUL+CPHTbpbKw2X1T + 7guWhj+xF8tZTuq6Dezu6+ZPV/GyDin/FROn5FlaXeHxFSzB2AfcQJ+Za2SMqaCVk9H1l7+Q9xxf + w3gkxnBfcTrzkKljMDf0Pj1aCyCzIKtafcuwoLJDXB0my3wjBJ1maQhMIDBSQOXXvOiccNn6y8WW + 0QbBvnCGzXiYYy5AlxNZJnsbzO5w2Gj6JSZXoBrxMGV8aqw70SRcN4/Gnpos0Lgxhm7eox2EM+S6 + hsPbdWxv3BT9gnXMbLVRXJv+Q8azzSbXyh6ok3LkKKuTOgPbsXfs2t2mkzqgzUy5unRS/avsDOIq + w6oax2DwixFoDfj3OqDWaTW9lE1KlMOzZUqg1Li5PsENLA4dXV2TU7Oo2pAMIy4UQiWn15xgEndS + 08D9Bl1msCxr4JOdrRixg2pohvR6a3c3Tn2IgehVWF7+19KtKhZsavQyWGA7ve7+9dpeLHCGnYEp + VxcW3EP79GCr7tOHGa/njvXvPEx0+4KDIjsu9lDU41ICs+v79MwuGvwilwpw+foOctB8TbQdfJHw + 5ollvnQ/q8pYPqclZaw/GDr99uFh2P1BrzM05eqSsdv17e//D2oSXs0W1QAA + headers: + access-control-allow-origin: ['*'] + access-control-expose-headers: ['X-Reddit-Tracking, X-Moose'] + cache-control: ['max-age=0, must-revalidate'] + cf-ray: [296f3f0aeb072858-SJC] + connection: [keep-alive] + content-encoding: [gzip] + content-length: ['7683'] + content-type: [application/json; charset=UTF-8] + date: ['Thu, 21 Apr 2016 07:50:39 GMT'] + server: [cloudflare-nginx] + set-cookie: ['__cfduid=d8e1d83c8cfa76ac404e21fc7d924dc961461225038; expires=Fri, + 21-Apr-17 07:50:38 GMT; path=/; domain=.reddit.com; HttpOnly', 'loid=hCXBgtTCOflyUpYHv9; + Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 21-Apr-2018 07:50:38 + GMT; secure', 'loidcreated=2016-04-21T07%3A50%3A38.582Z; Domain=reddit.com; + Max-Age=63071999; Path=/; expires=Sat, 21-Apr-2018 07:50:38 GMT; secure'] + strict-transport-security: [max-age=15552000; includeSubDomains; preload] + vary: [accept-encoding] + x-content-type-options: [nosniff] + x-frame-options: [SAMEORIGIN] + x-moose: [majestic] + x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=wUoXo%2B%2BbEgovlSTbKrPiRzy5CGl5PaWJAwmKAdLtVFDt9zGb%2FmDNZzDIUNfJZ7SEiQl6UK0WZns%3D'] + x-ua-compatible: [IE=edge] + x-xss-protection: [1; mode=block] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/test_content.py b/tests/test_content.py index 0cdf783..f111910 100644 --- a/tests/test_content.py +++ b/tests/test_content.py @@ -101,7 +101,8 @@ def test_content_submission(reddit, terminal): assert content.get(40)['type'] == 'Comment' for data in content.iterate(-1, 1): - assert all(k in data for k in ('object', 'n_rows', 'offset', 'type')) + assert all(k in data for k in ('object', 'n_rows', 'offset', 'type', + 'hidden')) # All text should be converted to unicode by this point for val in data.values(): assert not isinstance(val, six.binary_type) @@ -121,11 +122,14 @@ def test_content_submission(reddit, terminal): data = content.get(2) assert data['type'] == 'HiddenComment' assert data['count'] == 3 + assert data['hidden'] is True assert data['level'] >= content.get(3)['level'] assert len(content._comment_data) == 43 # Toggling again expands the children content.toggle(2) + data = content.get(2) + assert data['hidden'] is False assert len(content._comment_data) == 45 @@ -195,8 +199,9 @@ def test_content_subreddit(reddit, terminal): assert content.get(0)['type'] == 'Submission' for data in content.iterate(0, 1): - assert all(k in data for k in ('object', 'n_rows', 'offset', 'type', - 'index', 'title', 'split_title')) + assert all(k in data for k in ( + 'object', 'n_rows', 'offset', 'type', 'index', 'title', + 'split_title', 'hidden')) # All text should be converted to unicode by this point for val in data.values(): assert not isinstance(val, six.binary_type) @@ -227,6 +232,7 @@ def test_content_subreddit_load_more(reddit, terminal): assert data['index'] == i + 1 assert data['title'].startswith(six.text_type(i + 1)) + def test_content_subreddit_from_name(reddit, terminal): name = '/r/python' diff --git a/tests/test_objects.py b/tests/test_objects.py index 84bb016..1d2b6f7 100644 --- a/tests/test_objects.py +++ b/tests/test_objects.py @@ -346,11 +346,13 @@ def test_objects_navigator_properties(): assert nav.step == 1 assert nav.position == (0, 0, False) assert nav.absolute_index == 0 + assert nav.top_item_height is None - nav = Navigator(valid_page_cb, 5, 2, True) + nav = Navigator(valid_page_cb, 5, 2, True, 10) assert nav.step == -1 assert nav.position == (5, 2, True) assert nav.absolute_index == 3 + assert nav.top_item_height == 10 def test_objects_navigator_move(): @@ -360,6 +362,7 @@ def test_objects_navigator_move(): raise IndexError() nav = Navigator(valid_page_cb) + nav.top_item_height = 5 # Try to scroll up past the first item valid, redraw = nav.move(-1, 2) @@ -375,6 +378,7 @@ def test_objects_navigator_move(): # Scroll down, reach last item on the page and flip the screen valid, redraw = nav.move(1, 3) + assert nav.top_item_height is None assert nav.page_index == 2 assert nav.cursor_index == 0 assert nav.inverted diff --git a/tests/test_submission.py b/tests/test_submission.py index c9f8feb..57d6922 100644 --- a/tests/test_submission.py +++ b/tests/test_submission.py @@ -111,6 +111,24 @@ def test_submission_pager(submission_page, terminal): assert terminal.open_pager.called +def test_submission_comment_not_enough_space(submission_page, terminal): + + # The first comment is 10 lines, shrink the screen so that it won't fit. + # Setting the terminal to 10 lines means that there will only be 8 lines + # available (after subtracting the header and footer) to draw the comment. + terminal.stdscr.nlines = 10 + + # Select the first comment + with mock.patch.object(submission_page, 'clear_input_queue'): + submission_page.move_cursor_down() + + submission_page.draw() + + text = '(Not enough space to display)'.encode('ascii') + window = terminal.stdscr.subwin + window.subwin.addstr.assert_any_call(7, 1, text) + + def test_submission_vote(submission_page, refresh_token): # Log in