Project

General

Profile

action #67639

coordination #36712: [saga] Use YaST specific framework for GUI testing

coordination #62726: [functional][y][epic] Create separate Ruby Gem representing libyui Client API

[functional][y][timeboxed:12h] Enable reuse of code for libyui_client widgets

Added by JERiveraMoya over 1 year ago. Updated 12 months ago.

Status:
Resolved
Priority:
Normal
Assignee:
Target version:
-
Start date:
2020-06-03
Due date:
2020-06-16
% Done:

0%

Estimated time:

Description

After development in #66415 it was detected that with the current design we will be creating more code repeated every time we implement functionality in widgets, for example:

  • setting/getting text from textbox and numberbox
  • items
  • actions

Inheritance could still be used in some cases, but other more complex one proposal could be to create 'real inclusion' (with mixin (kind of easy way to use inclusion strategy that is possible in ruby there could be collision in names so it might not be the best way) instead of inheritance, so basically having some ItemController class where we could have all those different and shared methods and each object would pick the ones that needs. Same could be done for and ActionController because for example label does not have any action. In the case of ItemController could be an offline class with no rest calls, just passing items, in the case of ActionController we might need to provide it with possibility to make the rest call, which might need some extra reorganization of our base class for widget so we can delegate that code.

We should also rely on knowledge of internals on the server side. We should base our architecture on the way widgets work.

https://github.com/jknphy/libyui_client/pull/11/files

libyui_uml.png (93 KB) libyui_uml.png ybonatakis, 2020-06-12 05:23
9952

History

#1 Updated by JERiveraMoya over 1 year ago

  • Description updated (diff)

#2 Updated by riafarov over 1 year ago

  • Category set to Infrastructure

#3 Updated by riafarov over 1 year ago

  • Subject changed from [functional][y] Enable reuse of code for libyui_client widgets to [functional][y][timeboxed:12h] Enable reuse of code for libyui_client widgets
  • Description updated (diff)
  • Category changed from Infrastructure to Spike/Research
  • Status changed from New to Workable

#4 Updated by ybonatakis over 1 year ago

  • Assignee set to ybonatakis

#5 Updated by ybonatakis over 1 year ago

  • Status changed from Workable to In Progress

#6 Updated by ybonatakis over 1 year ago

9952

*Actions
The idea is to decouple the dependency on the action and take is out of the class. Each class can carry its own action(s) context. And because there are widgets that can perform more than one actions the Strategy pattern cannot apply with the normal implementation.
In case that each subclass had one action we could implement the above pattern creating another field in the base class that the action could be inherited and act. the Subclass would have only to pass itself in the methods.
With the current proposal, it removes the coupling in the base class and extends the action modules, so it can act independently. The Actions class has only one variable. I have named it context(name is under consideration, dont stick on it), that has the params to pass in the request. As that, it is a hash. the main item is :action. Set also attr_accessor to :context, such as the each class can append its items(See textbox.rb)

*Items
All items functions have some things in common. We have complex data structure, they dig for :label and items returns always an Array. We can unify the logic and pass this in the base class. Classes that use different key, like table.rb can override the function. I provide a function that acts on Arrays and i tested among all the examples.

*setting/getting values
I did not spend too much time on it because i had not understood the exact usecase for it.
However, in my understanding the text in textbox with the above changes can easily(and with variety of ways) be set. for instance i used the following code in set function

def set(value)
  @edit_action.context.merge!(value: value) # or edit_action.context[:value] = 'val'
  @edit_action.execute(self)
  self
end

Note that the Actions class uses attr_accessor :context to make the variable accessible.
My idea here is that as those values are just another context, no more action is required.

Finally i provide UML that i hope can make some things cleat in a visual way

#7 Updated by ybonatakis over 1 year ago

  • Status changed from Feedback to Resolved

In addition to the meeting i want to add the following clarifications.
The strategy pattern solves the problem to dynamically swap the algorithms used in an application. it provides a means to define a family of algorithms. And it lets the algorithm vary independently from clients that use them while it hides details of an algorithm's implementation
The Command pattern is a Behavior pattern and as such it encapsulates a much smaller level of detail than an algorithm0

In fact if you notice the proposal Action.rb it implements the command pattern in a way. Instead of having an Interface where from you create a family of actions, the actions are defined as Constants where i think this is how you would do it in the ruby world. But by its own it does not uncouple the action calls from the design.

[0] https://i.stack.imgur.com/wTO3S.jpg

Also available in: Atom PDF