telegram-bot-ruby icon indicating copy to clipboard operation
telegram-bot-ruby copied to clipboard

Add rake task to keep track of API updates

Open ivanovaleksey opened this issue 8 years ago • 13 comments

Hi @atipugin,

while working on #118 I found myself spending most of the time on verifying if particular Type or Method is up to date with documentation (the whole thing is very error prone).

So I consider implementing some handy tool to automate the job and avoid silly mistakes. I added rake task telegram:check. The current behaviour is comparing actual API with the one in the gem.

$ rake telegram:check
Missing types are:
 - WebhookInfo
 - VideoNote
 - UserProfilePhotos
 - ChatMember
 - ResponseParameters
 - InputFile
 - InlineQueryResult
 - LabeledPrice
 - Invoice
 - ShippingAddress
 - OrderInfo
 - ShippingOption
 - SuccessfulPayment
 - ShippingQuery
 - PreCheckoutQuery

Missing methods are:
 - sendVideoNote
 - deleteMessage
 - sendInvoice
 - answerShippingQuery
 - answerPreCheckoutQuery

Currently it shows only "whole" missing objects but I consider adding ability to examine particular type on attributes-level. For instance, we can add parameter to the rake task

$ rake telegram:check Message

The above should check attributes of Types::Message.

The solution might be a little dirty because we need to parse HTML and there are no particular section for all the types and all the methods in documentation (they are mixed altogether). But it seems work for now.

What do you think about it? Maybe you have some suggestions about naming and structuring?

Thank you.

ivanovaleksey avatar May 21 '17 06:05 ivanovaleksey

Hi @ivanovaleksey. I thought about same thing some time ago. I agree what checking all these methods and types is annoying.

Your solution looks good. One thing i'd like to change is a task name. It's sounds too generic right now. Maybe something like telegram:bot:check_missing?

atipugin avatar May 21 '17 12:05 atipugin

Yes, I think telegram:bot:check_missing is more suitable. And what do you think about task for checking particular types? How do we name it, telegram:bot:check_attributes?

I think it can receive types to be checked, and if no arguments are specified it should check all the types. For instance,

$ rake telegram:bot:check_attributes['Message Update']
# check attributes for types: Message and Update

$ rake telegram:bot:check_attributes
# check attributes for all types

ivanovaleksey avatar May 21 '17 13:05 ivanovaleksey

check_attributes sounds good. Will you implement it in this PR?

atipugin avatar May 22 '17 08:05 atipugin

Yes, I plan to implement both tasks in this PR. check_attributes turns out more complicated. I am not sure about it's functionality but I would like it to perform the following checks:

  • Compare expected and actual attributes list (if there are some added/removed)
  • Compare types of those attributes

I am not sure if Telegram could remove any attribute from a Type or change it's type. But potentially it could be done, so I would like to be able to detect such changes.

What do you think? It is unnecessary sophistication?

ivanovaleksey avatar May 22 '17 09:05 ivanovaleksey

@atipugin I thought there might be not only missing types/methods but also "extra" (outdated, Telegram API doesn't describe them and we do). That is why I came up with three separate tasks for each entity:

  • telegram:bot:check_attributes
  • telegram:bot:check_methods
  • telegram:bot:check_types
$ telegram:bot:check_types
Missing:
 - WebhookInfo
 - VideoNote
 - ...

Extra:
 - Foo # demo
$ rake telegram:bot:check_methods
Missing:
 - sendVideoNote
 - deleteMessage
 - ...

Extra:
 - fooMethod # demo
$ rake telegram:bot:check_attributes\['Message User'\]
Message:
  Missing:
   - video_note
   - new_chat_members
   - invoice
   - successful_payment

User:
  Missing:
   - language_code

  Extra:
   - foo # demo

  Type mismatch:
   - first_name: expect String, got Integer # demo

check_attributes task compares attributes for types that present both in API and the gem.

So one can call check_types to determine which types are missed/outdated and then check_attributes to examine both-present types.

ivanovaleksey avatar May 22 '17 14:05 ivanovaleksey

Yeah, these tasks looks great, much more specific and informative.

atipugin avatar May 23 '17 10:05 atipugin

I will try to finish this PR today.

ivanovaleksey avatar May 23 '17 12:05 ivanovaleksey

Why telegram:bot:check_attributes\['Message User'\] and not something like telegram:bot:check_attributes Message User ...?

Defman21 avatar May 23 '17 12:05 Defman21

@Defman21 I thought about it but for now check_attributes is plain rake task. As far as I know rake task's parameters should be specified in square brackets after task's name. Could you provide a code that allows to call check_attributes Message User?

P. S. Square brackets are escaped with backslashes because I use zsh. If you use bash you can omit backslashes, i.e. check_attributes['Message User'].

ivanovaleksey avatar May 23 '17 12:05 ivanovaleksey

You can use ARGV for that. (here's an example code: https://stackoverflow.com/questions/3586997/how-to-pass-multiple-parameters-to-rake-task#5956137) I didn't know that rake uses [] for arguments, which is, from my point of view, a strange decision. Feel free to leave it as is because the link I provided (and the code example) is a hacky way to implement what I said.

Defman21 avatar May 23 '17 13:05 Defman21

Square brackets is a proper way to pass agruments to rake tasks.

atipugin avatar May 23 '17 14:05 atipugin

@atipugin I noticed one thing with Virtus gem which spoils attribute types matching. InlineKeyboardMarkup type has attribute :inline_keyboard, Array[Array[InlineKeyboardButton]].

But attribute inspection shows nothing about InlineKeyboardButton, just Array of Array:

Telegram::Bot::Types::InlineKeyboardMarkup.attribute_set.first
=> # Virtus::Attribute::Collection type=Axiom::Types::Array (Array) options={:accessor=>:public, :default=>#<Proc:0x007fbd1485ba28 ....

And it isn't actually coerced to InlineKeyboardButton (it is Array of Array of hashes, surprise to me):

Telegram::Bot::Types::InlineKeyboardMarkup.new inline_keyboard: [[{ text: '1st button text' }, { text: '2nd button text' }]]
=> #<Telegram::Bot::Types::InlineKeyboardMarkup:0x007ff906c66270
 @inline_keyboard=[[{:text=>"1st button text"}, {:text=>"2nd button text"}]]>

So right now I don't see any way to extract real type of inline_keyboard attribute. I didn't work with Virtus outside of the gem, do you any workarounds here? Is it a Virtus bug?

UPDATE I have oped an issue on Virtus gem: https://github.com/solnic/virtus/issues/374

I wonder can we use dry-rb/dry-types and dry-rb/dry-struct instead of Virtus (is seems to me like this gem slowly dies). I created gist, seems like it works just fine.

ivanovaleksey avatar May 23 '17 14:05 ivanovaleksey

Hmm, that's strange. Even after digging into Virtus source code i still can't figure out how access attribute type.

I agree that virtus is dying and dry-types might be a good alternative, but i've never used it before, need some time to play with it.

Let's release new api changes first and then return to this issue, as migration to dry-types will take a time.

atipugin avatar May 23 '17 15:05 atipugin

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar Feb 19 '23 15:02 github-actions[bot]