Coverage for src/robotide/publish/__init__.py: 100%

5 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2008-2015 Nokia Networks 

2# Copyright 2016- Robot Framework Foundation 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15 

16"""Message publishing and subscribing. 

17 

18.. contents:: 

19 :depth: 2 

20 :local: 

21 

22Introduction 

23------------ 

24 

25RIDE uses messages for communication when something of interest happens, for 

26example a suite is loaded or item is selected in the tree. This module provides 

27means both for subscribing to listen to those messages and for sending them. 

28Messages are used for communication between the different components of the 

29core application, but their main usage is notifying plugins about various events. 

30Plugins can also send messages themselves, and also create custom messages, if 

31they have a need. 

32 

33Subscribing 

34----------- 

35 

36The core application uses the global `PUBLISHER` object (an instance of the 

37`Publisher` class) for subscribing to and unsubscribing from the messages. 

38Plugins should use the helper methods of the `Plugin` class instead of using 

39the `PUBLISHER` directly. 

40 

41Message topics 

42~~~~~~~~~~~~~~ 

43 

44Regardless the method, subscribing to messages requires a message topic. 

45Topics can be specified using the actual message classes in 

46`robotide.publish.messages` module or with their dot separated topic strings. 

47It is, for example, equivalent to use the `RideTreeSelection` class and a 

48string ``ride.tree.selection``. Topic strings can normally, but not always, be 

49mapped directly to the class names. 

50 

51The topic strings represents a hierarchy where the dots separate the hierarchy 

52levels. All messages with a topic at or below the given level will match the 

53subscribed topic. For example, subscribing to the ``ride.notebook`` topic means 

54that `RideNotebookTabChanged` or any other message with a topic starting with 

55``ride.notebook`` will match. 

56 

57Listeners 

58~~~~~~~~~ 

59 

60Another thing needed when subscribing is a listener, which must be a callable 

61accepting one argument. When the corresponding message is published, the listener 

62will be called with an instance of the message class as an argument. That instance 

63contains the topic and possibly some additional information in its attributes. 

64 

65The following example demonstrates how a plugin can subscribe to an event. 

66In this example the ``on_tree_selection`` method is the listener and the 

67``message`` it receives is an instance of the `RideTreeSelection` class. 

68:: 

69 

70 from robotide.pluginapi import Plugin, RideTreeSelection 

71 

72 class MyFancyPlugin(Plugin): 

73 def activate(self): 

74 self.subscribe(self.on_tree_selection, RideTreeSelection) 

75 

76 def on_tree_selection(self, message): 

77 print(message.topic, message.node) 

78 

79Unsubscribing 

80~~~~~~~~~~~~~ 

81 

82Unsubscribing from a single message requires passing the same topic and listener 

83to the unsubscribe method that were used for subscribing. Additionally both 

84the `PUBLISHER` object and the `Plugin` class provide a method for unsubscribing 

85all listeners registered by someone. 

86 

87 

88Publishing messages 

89------------------- 

90 

91Both the core application and plugins can publish messages using message 

92classes in the `publish.messages` module directly. Sending a message is as easy 

93as creating an instance of the class and calling its ``publish`` method. What 

94parameters are need when the instance is created depends on the message. 

95 

96Custom messages 

97~~~~~~~~~~~~~~~ 

98 

99Most of the messages in the `publish.messages` module are to be sent only by 

100the core application. If plugins need their own messages, for example for 

101communication between different plugins, they can easily create custom messages 

102by extending the `RideMessage` base class:: 

103 

104 from robotide.pluginapi import Plugin, RideMessage 

105 

106 class FancyImportantMessage(RideMessage): 

107 data = ['importance'] 

108 

109 class MyFancyPlugin(Plugin): 

110 def important_action(self): 

111 # some code ... 

112 MyImportantMessage(importance='HIGH').publish() 

113 

114Plugins interested about this message can subscribe to it using either 

115the class ``FancyImportantMessage`` or its automatically generated title 

116``fancy.important``. Notice also that all the messages are exposed also through 

117the `robotide.pluginapi` module and plugins should import them there. 

118""" 

119 

120 

121import os 1ab

122 

123from .messages import * 1ab

124from .publisher import PUBLISHER 1ab

125 

126 

127def get_html_message(name): 1ab

128 return open(os.path.join( 1c

129 os.path.dirname(__file__), 'htmlmessages', '{}.html'.format(name))).read()