Coverage for tests/test_interface.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-02 11:07 +0100

1"""Tests for the `certus.interface` module.""" 

2 

3from unittest import mock 

4 

5import hypothesis as hyp 

6import hypothesis.strategies as st 

7 

8from certus import interface 

9 

10from . import common 

11 

12 

13def test_from_google_no_candidates(): 

14 """Check we get nothing back without some candidates.""" 

15 result = mock.Mock(chosen_candidates=None) 

16 assert interface.from_google(result) == [] 

17 

18 

19def _check_google_candidate_nodes(candidates, nodes, clamp): 

20 """Check a set of nodes derived from a Google result.""" 

21 assert isinstance(nodes, list) 

22 assert len(nodes) == clamp.call_count == len(candidates) 

23 assert all(isinstance(node, interface.core.Token) for node in nodes) 

24 

25 position = 0 

26 for can, node, call in zip(candidates, nodes, clamp.call_args_list): 

27 assert can.token == node.value 

28 assert can.log_probability == node.logprob 

29 assert position == node.start 

30 position += len(can.token) 

31 

32 assert call == mock.call(node.logprob, upper=0.0) 

33 

34 

35@hyp.given(st.lists(st.tuples(st.text(), common.ST_LOGPROBS))) 

36def test_from_google_all_candidates(params): 

37 """ 

38 Check we get a list of nodes back from a log-probability result set. 

39 

40 We mock the clamp utility here, telling it to pass the 

41 log-probability through unchanged. Then we check the nodes match the 

42 result set, and that the clamp utility is called for each element. 

43 """ 

44 result = mock.Mock( 

45 chosen_candidates=[ 

46 mock.Mock(token=text, log_probability=logprob) for text, logprob in params 

47 ] 

48 ) 

49 

50 with mock.patch.object(interface.utils, "clamp") as clamp: 

51 clamp.side_effect = lambda val, *_, **__: val 

52 nodes = interface.from_google(result) 

53 

54 _check_google_candidate_nodes(result.chosen_candidates, nodes, clamp) 

55 

56 

57@hyp.given(st.lists(st.tuples(st.none() | st.text(), st.none() | common.ST_LOGPROBS))) 

58def test_from_google_some_candidates(params): 

59 """ 

60 Check we skip over empty candidates when building our node list. 

61 

62 We mock the clamp utility here, telling it to pass the 

63 log-probability through unchanged. Then we check the nodes match the 

64 complete elements of the result set, and that the clamp utility is 

65 only called for them. 

66 """ 

67 result = mock.Mock( 

68 chosen_candidates=[ 

69 mock.Mock(token=text, log_probability=logprob) for text, logprob in params 

70 ] 

71 ) 

72 

73 with mock.patch.object(interface.utils, "clamp") as clamp: 

74 clamp.side_effect = lambda val, *_, **__: val 

75 nodes = interface.from_google(result) 

76 

77 complete = [ 

78 c 

79 for c in result.chosen_candidates 

80 if c.token is not None and c.log_probability is not None 

81 ] 

82 

83 _check_google_candidate_nodes(complete, nodes, clamp)