Skip to content

Commit 4ac7e90

Browse files
rsashankkingjunoyuktasarode
committed
core/views: Add support for copying code blocks.
Introduces support for copying code blocks in the message information popup. Makes use of the CodeBlockButton class and its methods. Tests added. Co-authored-by: kingjuno <[email protected]> Co-authored-by: yuktasarode <[email protected]>
1 parent 4068756 commit 4ac7e90

File tree

3 files changed

+203
-1
lines changed

3 files changed

+203
-1
lines changed

tests/ui_tools/test_popups.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ def mock_external_classes(self, mocker: MockerFixture, msg_box: MessageBox) -> N
468468
topic_links=OrderedDict(),
469469
message_links=OrderedDict(),
470470
time_mentions=list(),
471+
code_blocks=list(),
471472
title="Full Rendered Message",
472473
)
473474

@@ -520,6 +521,7 @@ def test_keypress_show_msg_info(
520521
topic_links=OrderedDict(),
521522
message_links=OrderedDict(),
522523
time_mentions=list(),
524+
code_blocks=list(),
523525
)
524526

525527

@@ -544,6 +546,7 @@ def mock_external_classes(self, mocker: MockerFixture, msg_box: MessageBox) -> N
544546
topic_links=OrderedDict(),
545547
message_links=OrderedDict(),
546548
time_mentions=list(),
549+
code_blocks=list(),
547550
title="Full Raw Message",
548551
)
549552

@@ -596,6 +599,7 @@ def test_keypress_show_msg_info(
596599
topic_links=OrderedDict(),
597600
message_links=OrderedDict(),
598601
time_mentions=list(),
602+
code_blocks=list(),
599603
)
600604

601605

@@ -619,6 +623,7 @@ def mock_external_classes(self, mocker: MockerFixture) -> None:
619623
topic_links=OrderedDict(),
620624
message_links=OrderedDict(),
621625
time_mentions=list(),
626+
code_blocks=list(),
622627
title="Edit History",
623628
)
624629

@@ -667,6 +672,7 @@ def test_keypress_show_msg_info(
667672
topic_links=OrderedDict(),
668673
message_links=OrderedDict(),
669674
time_mentions=list(),
675+
code_blocks=list(),
670676
)
671677

672678
@pytest.mark.parametrize(
@@ -944,6 +950,7 @@ def mock_external_classes(
944950
OrderedDict(),
945951
OrderedDict(),
946952
list(),
953+
list(),
947954
)
948955

949956
def test_init(self, message_fixture: Message) -> None:
@@ -962,6 +969,7 @@ def test_pop_up_info_order(self, message_fixture: Message) -> None:
962969
topic_links=topic_links,
963970
message_links=message_links,
964971
time_mentions=list(),
972+
code_blocks=list(),
965973
)
966974
msg_links = msg_info_view.button_widgets
967975
assert msg_links == [message_links, topic_links]
@@ -1010,6 +1018,7 @@ def test_keypress_edit_history(
10101018
topic_links=OrderedDict(),
10111019
message_links=OrderedDict(),
10121020
time_mentions=list(),
1021+
code_blocks=list(),
10131022
)
10141023
size = widget_size(msg_info_view)
10151024

@@ -1021,6 +1030,7 @@ def test_keypress_edit_history(
10211030
topic_links=OrderedDict(),
10221031
message_links=OrderedDict(),
10231032
time_mentions=list(),
1033+
code_blocks=list(),
10241034
)
10251035
else:
10261036
self.controller.show_edit_history.assert_not_called()
@@ -1039,6 +1049,7 @@ def test_keypress_full_rendered_message(
10391049
topic_links=OrderedDict(),
10401050
message_links=OrderedDict(),
10411051
time_mentions=list(),
1052+
code_blocks=list(),
10421053
)
10431054
size = widget_size(msg_info_view)
10441055

@@ -1049,6 +1060,7 @@ def test_keypress_full_rendered_message(
10491060
topic_links=OrderedDict(),
10501061
message_links=OrderedDict(),
10511062
time_mentions=list(),
1063+
code_blocks=list(),
10521064
)
10531065

10541066
@pytest.mark.parametrize("key", keys_for_command("FULL_RAW_MESSAGE"))
@@ -1065,6 +1077,7 @@ def test_keypress_full_raw_message(
10651077
topic_links=OrderedDict(),
10661078
message_links=OrderedDict(),
10671079
time_mentions=list(),
1080+
code_blocks=list(),
10681081
)
10691082
size = widget_size(msg_info_view)
10701083

@@ -1075,6 +1088,7 @@ def test_keypress_full_raw_message(
10751088
topic_links=OrderedDict(),
10761089
message_links=OrderedDict(),
10771090
time_mentions=list(),
1091+
code_blocks=list(),
10781092
)
10791093

10801094
@pytest.mark.parametrize(
@@ -1176,6 +1190,7 @@ def test_height_reactions(
11761190
OrderedDict(),
11771191
OrderedDict(),
11781192
list(),
1193+
list(),
11791194
)
11801195
# 12 = 7 labels + 2 blank lines + 1 'Reactions' (category)
11811196
# + 4 reactions (excluding 'Message Links').
@@ -1229,6 +1244,118 @@ def test_create_link_buttons(
12291244
assert link_w._wrapped_widget.attr_map == expected_attr_map
12301245
assert link_width == expected_link_width
12311246

1247+
@pytest.mark.parametrize(
1248+
[
1249+
"initial_code_block",
1250+
"expected_code",
1251+
"expected_attr_map",
1252+
"expected_focus_map",
1253+
],
1254+
[
1255+
(
1256+
[
1257+
(
1258+
"Python",
1259+
[
1260+
("pygments:k", "def"),
1261+
("pygments:w", " "),
1262+
("pygments:nf", "main"),
1263+
("pygments:p", "()"),
1264+
("pygments:w", "\n "),
1265+
("pygments:nb", "print"),
1266+
("pygments:p", "("),
1267+
("pygments:s2", '"Hello"'),
1268+
("pygments:p", ")"),
1269+
("pygments:w", "\n"),
1270+
],
1271+
)
1272+
],
1273+
'1: Python\ndef main()\n print("Hello")...',
1274+
{None: "popup_contrast"},
1275+
{None: "selected"},
1276+
),
1277+
(
1278+
[
1279+
(
1280+
"JavaScript",
1281+
[
1282+
("pygments:nx", "console"),
1283+
("pygments:p", "."),
1284+
("pygments:nx", "log"),
1285+
("pygments:p", "("),
1286+
("pygments:s2", '"Hello, world!"'),
1287+
("pygments:p", ");"),
1288+
("pygments:w", "\n"),
1289+
],
1290+
)
1291+
],
1292+
'1: JavaScript\nconsole.log("Hello, world!");',
1293+
{None: "popup_contrast"},
1294+
{None: "selected"},
1295+
),
1296+
(
1297+
[
1298+
(
1299+
"C++",
1300+
[
1301+
("pygments:cp", "#include"),
1302+
("pygments:w", " "),
1303+
("pygments:cpf", "<iostream>"),
1304+
("pygments:w", "\n\n"),
1305+
("pygments:kt", "int"),
1306+
("pygments:w", " "),
1307+
("pygments:nf", "main"),
1308+
("pygments:p", "()"),
1309+
("pygments:w", " "),
1310+
("pygments:p", "{"),
1311+
("pygments:w", "\n"),
1312+
("pygments:w", " "),
1313+
("pygments:n", "std"),
1314+
("pygments:o", "::"),
1315+
("pygments:n", "cout"),
1316+
("pygments:w", " "),
1317+
("pygments:o", "<<"),
1318+
("pygments:w", " "),
1319+
("pygments:s", '"Hello World!"'),
1320+
("pygments:p", ";"),
1321+
("pygments:w", "\n"),
1322+
("pygments:w", " "),
1323+
("pygments:k", "return"),
1324+
("pygments:w", " "),
1325+
("pygments:mi", "0"),
1326+
("pygments:p", ";"),
1327+
("pygments:w", "\n"),
1328+
("pygments:p", "}"),
1329+
("pygments:w", "\n"),
1330+
],
1331+
)
1332+
],
1333+
"1: C++\n#include <iostream>\n\nint main() {...",
1334+
{None: "popup_contrast"},
1335+
{None: "selected"},
1336+
),
1337+
],
1338+
ids=[
1339+
"with_python_code_block_two_lines",
1340+
"with_javascript_code_block_one_line",
1341+
"with_cpp_code_block_more_than_two_lines",
1342+
],
1343+
)
1344+
def test_create_code_block_buttons(
1345+
self,
1346+
initial_code_block: List[Tuple[str, List[Tuple[str, str]]]],
1347+
expected_code: str,
1348+
expected_attr_map: Dict[None, str],
1349+
expected_focus_map: Dict[None, str],
1350+
) -> None:
1351+
[code_w], _ = self.msg_info_view.create_code_block_buttons(
1352+
self.controller, initial_code_block
1353+
)
1354+
1355+
assert code_w._wrapped_widget.original_widget.text == expected_code
1356+
assert code_w._wrapped_widget.focus_map == expected_focus_map
1357+
assert code_w._wrapped_widget.attr_map == expected_attr_map
1358+
12321359

12331360
class TestStreamInfoView:
12341361
@pytest.fixture(autouse=True)

zulipterminal/core.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ def show_msg_info(
264264
topic_links: Dict[str, Tuple[str, int, bool]],
265265
message_links: Dict[str, Tuple[str, int, bool]],
266266
time_mentions: List[Tuple[str, str]],
267+
code_blocks: List[Tuple[str, List[Tuple[str, str]]]],
267268
) -> None:
268269
msg_info_view = MsgInfoView(
269270
self,
@@ -272,6 +273,7 @@ def show_msg_info(
272273
topic_links,
273274
message_links,
274275
time_mentions,
276+
code_blocks,
275277
)
276278
self.show_pop_up(msg_info_view, "area:msg")
277279

@@ -342,6 +344,7 @@ def show_full_rendered_message(
342344
topic_links: Dict[str, Tuple[str, int, bool]],
343345
message_links: Dict[str, Tuple[str, int, bool]],
344346
time_mentions: List[Tuple[str, str]],
347+
code_blocks: List[Tuple[str, List[Tuple[str, str]]]],
345348
) -> None:
346349
self.show_pop_up(
347350
FullRenderedMsgView(
@@ -350,6 +353,7 @@ def show_full_rendered_message(
350353
topic_links,
351354
message_links,
352355
time_mentions,
356+
code_blocks,
353357
f"Full rendered message {SCROLL_PROMPT}",
354358
),
355359
"area:msg",
@@ -361,6 +365,7 @@ def show_full_raw_message(
361365
topic_links: Dict[str, Tuple[str, int, bool]],
362366
message_links: Dict[str, Tuple[str, int, bool]],
363367
time_mentions: List[Tuple[str, str]],
368+
code_blocks: List[Tuple[str, List[Tuple[str, str]]]],
364369
) -> None:
365370
self.show_pop_up(
366371
FullRawMsgView(
@@ -369,6 +374,7 @@ def show_full_raw_message(
369374
topic_links,
370375
message_links,
371376
time_mentions,
377+
code_blocks,
372378
f"Full raw message {SCROLL_PROMPT}",
373379
),
374380
"area:msg",
@@ -380,6 +386,7 @@ def show_edit_history(
380386
topic_links: Dict[str, Tuple[str, int, bool]],
381387
message_links: Dict[str, Tuple[str, int, bool]],
382388
time_mentions: List[Tuple[str, str]],
389+
code_blocks: List[Tuple[str, List[Tuple[str, str]]]],
383390
) -> None:
384391
self.show_pop_up(
385392
EditHistoryView(
@@ -388,6 +395,7 @@ def show_edit_history(
388395
topic_links,
389396
message_links,
390397
time_mentions,
398+
code_blocks,
391399
f"Edit History {SCROLL_PROMPT}",
392400
),
393401
"area:msg",

0 commit comments

Comments
 (0)