shep 0.1.0.pre.alpha0 → 0.2.0.pre.alpha0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -1
  3. data/Rakefile +1 -0
  4. data/doc/Shep/Entity/Account.html +22 -37
  5. data/doc/Shep/Entity/Context.html +8 -9
  6. data/doc/Shep/Entity/CustomEmoji.html +11 -15
  7. data/doc/Shep/Entity/MediaAttachment.html +13 -19
  8. data/doc/Shep/Entity/Notification.html +11 -15
  9. data/doc/Shep/Entity/Status.html +34 -61
  10. data/doc/Shep/Entity/StatusSource.html +9 -11
  11. data/doc/Shep/Entity/Status_Application.html +11 -10
  12. data/doc/Shep/Entity/Status_Mention.html +10 -13
  13. data/doc/Shep/Entity/Status_Tag.html +8 -9
  14. data/doc/Shep/Entity.html +156 -141
  15. data/doc/Shep/Error/Caller.html +4 -4
  16. data/doc/Shep/Error/Http.html +13 -13
  17. data/doc/Shep/Error/RateLimit.html +176 -0
  18. data/doc/Shep/Error/Remote.html +3 -4
  19. data/doc/Shep/Error/Server.html +5 -4
  20. data/doc/Shep/Error/Type.html +6 -8
  21. data/doc/Shep/Error.html +5 -5
  22. data/doc/Shep/Session.html +895 -570
  23. data/doc/Shep.html +20 -5
  24. data/doc/_index.html +10 -3
  25. data/doc/class_list.html +1 -1
  26. data/doc/file.README.html +52 -33
  27. data/doc/file_list.html +1 -1
  28. data/doc/index.html +117 -239
  29. data/doc/method_list.html +9 -1
  30. data/doc/top-level-namespace.html +2 -2
  31. data/lib/shep/entity_base.rb +6 -1
  32. data/lib/shep/exceptions.rb +5 -0
  33. data/lib/shep/session.rb +292 -146
  34. data/lib/shep/version.rb +4 -0
  35. data/lib/shep.rb +1 -1
  36. data/run_rake_test.example.sh +12 -5
  37. data/shep.gemspec +4 -2
  38. data/spec/session_reader_1_unauth_spec.rb +20 -17
  39. data/spec/session_reader_2_auth_spec.rb +17 -19
  40. data/spec/session_writer_spec.rb +4 -11
  41. data/spec/session_zzz_tricky_spec.rb +136 -0
  42. data/spec/spec_helper.rb +12 -3
  43. metadata +12 -9
data/lib/shep.rb CHANGED
@@ -11,9 +11,9 @@ require 'fileutils'
11
11
 
12
12
  # SHEP: Simple Http intErface to Pmastodon
13
13
  module Shep
14
-
15
14
  end
16
15
 
16
+ require_relative 'shep/version'
17
17
  require_relative 'shep/exceptions'
18
18
  require_relative 'shep/typeboxes'
19
19
  require_relative 'shep/entity_base'
@@ -5,12 +5,15 @@ set -e
5
5
  # needed to run the full suite of tests. Actual values have been
6
6
  # replaced with nonsense.
7
7
  #
8
- # If none of these are set, only offline tests will be run
8
+ # If none of these are set, only offline tests will be run.
9
+ #
10
+ # Put your test command on the command line to invoke it; otherwise,
11
+ # it will run `rake test`.
9
12
 
10
13
 
11
14
  #
12
15
  # Set these to enable basic read tests:
13
- #
16
+ #
14
17
 
15
18
  # The host
16
19
  #export SHEP_TEST_HOST="mastodon.anti.social"
@@ -24,7 +27,7 @@ set -e
24
27
  # Set these if you also have an account that you wish to use for
25
28
  # testing. This will only read from the account (we hope), but it's
26
29
  # probably not a good idea to use an account you care about.
27
- #
30
+ #
28
31
 
29
32
  #export SHEP_ACCOUNT=54321
30
33
  #export SHEP_TOKEN=JDJidvpsdvjapojSDFvfvafWER3qrwDVe4
@@ -41,6 +44,10 @@ set -e
41
44
 
42
45
  #export SHEP_TEST_ALL=1
43
46
 
44
-
45
47
  cd $(dirname "$0")/shep
46
- rake test
48
+
49
+ if [ -z "$1" ]; then
50
+ rake test
51
+ else
52
+ eval "$@"
53
+ fi
data/shep.gemspec CHANGED
@@ -1,6 +1,8 @@
1
+ require_relative "lib/shep/version"
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = 'shep'
3
- s.version = '0.1.0-alpha0'
5
+ s.version = Shep::Version
4
6
  s.date = '2023-06-03'
5
7
  s.summary = "An alternate interface to the Mastodon Web API"
6
8
  s.description = <<-EOF
@@ -24,5 +26,5 @@ EOF
24
26
  s.add_development_dependency 'rake', '~> 13.0.6'
25
27
 
26
28
  s.homepage = 'https://codeberg.org/suetanvil/shep'
27
- s.license = 'AGPL with linking exemption'
29
+ s.license = 'AGPL-3.0-only with linking exception'
28
30
  end
@@ -2,16 +2,16 @@
2
2
  require_relative 'spec_helper'
3
3
  require_relative '../lib/shep'
4
4
 
5
+ require "stringio"
6
+
5
7
  include Shep
6
8
 
7
9
 
8
10
  describe Session, :anonymous do
9
11
  include_context :uses_temp_dir
10
12
 
11
-
12
-
13
13
  it "retrieves account information." do
14
- ss = Session.new(host: HOST)
14
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
15
15
  acct = ss.fetch_account(READ_ACCOUNT)
16
16
 
17
17
  expect( acct.class ) .to be Entity::Account
@@ -24,7 +24,7 @@ describe Session, :anonymous do
24
24
  end
25
25
 
26
26
  it "keeps track of rate limit information." do
27
- ss = Session.new(host: HOST)
27
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
28
28
  acct = ss.fetch_account(READ_ACCOUNT)
29
29
 
30
30
  expect( ss.rate_limit.remaining ) .to be <= ss.rate_limit.limit
@@ -34,7 +34,7 @@ describe Session, :anonymous do
34
34
  end
35
35
 
36
36
  it "retrieves followers and following accounts." do
37
- ss = Session.new(host: HOST)
37
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
38
38
 
39
39
  following = ss.each_following(READ_ACCOUNT, limit: 10).to_a
40
40
  expect( following.size ) .to be <= 10
@@ -47,7 +47,7 @@ describe Session, :anonymous do
47
47
  end
48
48
 
49
49
  it "retrieves statuses." do
50
- ss = Session.new(host: HOST)
50
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
51
51
 
52
52
  sts_all = ss.each_status(READ_ACCOUNT, limit: 50).to_a
53
53
  expect( sts_all.size ) .to be > 0
@@ -76,15 +76,20 @@ describe Session, :anonymous do
76
76
 
77
77
 
78
78
  it "does more account stuff." do
79
- ss = Session.new(host: HOST)
79
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
80
80
 
81
81
  acct1 = ss.fetch_account_by_username(READ_ACCOUNT_HANDLE)
82
82
  acct2 = ss.fetch_account(acct1.id)
83
83
  expect( acct1 ) .to eq acct2
84
+
85
+ # If it's missing, you should get nil back. (Funny prank idea: create
86
+ # this account just to mess with me.)
87
+ bogus = ss.fetch_account_by_username("bogus_account_not_here_alsidjfals")
88
+ expect( bogus ) .to be nil
84
89
  end
85
90
 
86
91
  it "fetches individual statuses." do
87
- ss = Session.new(host: HOST)
92
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
88
93
 
89
94
  count = 0
90
95
  ss.each_status(READ_ACCOUNT, limit: 5) {|ref_status|
@@ -96,7 +101,7 @@ describe Session, :anonymous do
96
101
  end
97
102
 
98
103
  it "leaves optional session fields nil if no token is given." do
99
- ss = Session.new(host: HOST)
104
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
100
105
  statuses = ss.each_status(READ_ACCOUNT, limit: 1).to_a
101
106
 
102
107
  expect( statuses.size ) .to be > 0
@@ -110,7 +115,7 @@ describe Session, :anonymous do
110
115
  end
111
116
 
112
117
  it "fetches status contexts." do
113
- ss = Session.new(host: HOST)
118
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
114
119
 
115
120
  # Search for the first status to have a reply
116
121
  match_status = nil
@@ -137,7 +142,7 @@ describe Session, :anonymous do
137
142
  end
138
143
 
139
144
  it "fetches accounts that boosted and/or favourited a status." do
140
- ss = Session.new(host: HOST)
145
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
141
146
 
142
147
  status_count = 0
143
148
  boosted_found = 0
@@ -175,9 +180,8 @@ describe Session, :anonymous do
175
180
  expect( boosters_found ) .to be > 0
176
181
  end
177
182
 
178
-
179
183
  it "retrieves groups of items via block as well as enumerator." do
180
- ss = Session.new(host: HOST)
184
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
181
185
 
182
186
  count = 0
183
187
  ss.each_following(READ_ACCOUNT, limit: 10) { count += 1 }
@@ -192,9 +196,8 @@ describe Session, :anonymous do
192
196
  expect( count ) .to be > 0
193
197
  end
194
198
 
195
- # TODO: move to own describe block.
196
199
  it "retrieves status' media attachments." do
197
- ss = Session.new(host: HOST)
200
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
198
201
 
199
202
  # Find the earliest status with one or more media attachments
200
203
  candidate = nil
@@ -242,7 +245,7 @@ describe Session, :anonymous do
242
245
 
243
246
 
244
247
  it "retrieves the site's public timeline." do
245
- ss = Session.new(host: HOST)
248
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
246
249
 
247
250
  caturday = "caturday"
248
251
 
@@ -282,7 +285,7 @@ describe Session, :anonymous do
282
285
  it "retrieves posts by tag." do
283
286
  caturday = "caturday"
284
287
 
285
- ss = Session.new(host: HOST)
288
+ ss = Session.new(host: HOST, ua_comment: "(integration test)")
286
289
 
287
290
  # Find the latest 100 toots. This assumes an average distribution
288
291
  # that may not happen on the actual live server, in which case
@@ -7,8 +7,9 @@ require_relative '../lib/shep'
7
7
  include Shep
8
8
 
9
9
  describe Session, :account do
10
+
10
11
  it "fetches status sources." do
11
- ss = Session.new(host: HOST, token: TOKEN)
12
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
12
13
  statuses = ss.each_status(WRITE_ACCOUNT, limit: 1).to_a
13
14
  expect( statuses.empty? ) .to be false
14
15
  stat0 = statuses[0]
@@ -22,13 +23,13 @@ describe Session, :account do
22
23
  end
23
24
 
24
25
  it "reads the home timeline" do
25
- ss = Session.new(host: HOST, token: TOKEN)
26
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
26
27
  statuses = ss.each_home_status(limit: 10).to_a
27
28
  expect( statuses.size ) .to be > 0
28
29
  end
29
30
 
30
31
  it "reads notifications" do
31
- ss = Session.new(host: HOST, token: TOKEN)
32
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
32
33
 
33
34
  ntfns = ss.each_notification(limit: 10).to_a
34
35
  expect( ntfns.size ) .to be > 0
@@ -72,25 +73,22 @@ describe Session, :account do
72
73
  }.call
73
74
  end
74
75
 
75
- skip "dismisses notifications" do
76
- ss = Session.new(host: HOST, token: TOKEN)
76
+ it "timeline retrivals support max_id:" do
77
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
77
78
 
78
- # We dismiss the first notification, then confirm that it is no
79
- # longer there. Since this is not repeatable, we skip it by
80
- # default and manually enable it when we want to test it.
79
+ range_fn = proc { |&action|
80
+ group_1 = action.call(limit: 10).to_a
81
+ expect(group_1.size) .to eq 10 # not an error, but we can't continue if false
81
82
 
82
- ntfns = ss.each_notification(limit: 10).to_a
83
- expect( ntfns.size ) .to be > 0
84
- first = ntfns[0]
83
+ group_2 = action.call(limit: 5, max_id: group_1[4].id).to_a
84
+ expect( group_2.size ) .to be > 0 # not an error but...
85
85
 
86
- ss.dismiss_notification(first.id)
86
+ expect( group_2 ) .to eq group_1[5..]
87
+ }
87
88
 
88
- ntfns2 = ss.each_notification(limit: 10).to_a
89
- expect( ntfns2.size ) .to eq ntfns.size - 1
90
- expect( ntfns2[0] ) .to_not eq first
89
+ range_fn.call{|**kwargs| ss.each_status(READ_ACCOUNT, **kwargs)}
90
+ range_fn.call{|**kwargs| ss.each_public_status(**kwargs)}
91
+ range_fn.call{|**kwargs| ss.each_tag_status("caturday", **kwargs)}
92
+ range_fn.call{|**kwargs| ss.each_home_status(**kwargs)}
91
93
  end
92
-
93
-
94
- # skip "" do ; end
95
-
96
94
  end
@@ -6,8 +6,6 @@ require_relative '../lib/shep'
6
6
 
7
7
  include Shep
8
8
 
9
- POST_UUID = "fc49e486-d445-4ca7-9d6d-a27c89c5c471" #SecureRandom.uuid
10
-
11
9
  describe Session, :account_limited do
12
10
  include_context :uses_temp_dir
13
11
 
@@ -18,7 +16,7 @@ describe Session, :account_limited do
18
16
  it "posts statuses" do
19
17
  testpost = "Test post #{POST_UUID} "
20
18
 
21
- ss = Session.new(host: HOST, token: TOKEN)
19
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
22
20
 
23
21
  visibilities = %w{public unlisted private direct}
24
22
  for vis in visibilities
@@ -46,7 +44,7 @@ describe Session, :account_limited do
46
44
  end
47
45
 
48
46
  it "posts status with media" do
49
- ss = Session.new(host: HOST, token: TOKEN)
47
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
50
48
 
51
49
  file1 = File.join(File.dirname(__FILE__), "data", "smallimg.jpg")
52
50
  file2 = File.join(File.dirname(__FILE__), "data", "smallish.jpg")
@@ -82,7 +80,7 @@ describe Session, :account_limited do
82
80
  end
83
81
 
84
82
  it "edits statuses" do
85
- ss = Session.new(host: HOST, token: TOKEN)
83
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
86
84
 
87
85
  base_text = "edited msg #{POST_UUID}\n#{Time.now}\n-"
88
86
  post = ss.post_status(base_text, language: "en")
@@ -160,7 +158,7 @@ describe Session, :account_limited do
160
158
  end
161
159
 
162
160
  it "deletes statuses" do
163
- ss = Session.new(host: HOST, token: TOKEN)
161
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
164
162
 
165
163
  # Test for the test itself
166
164
  expect( @new_posts.size ) .to be > 0
@@ -175,9 +173,4 @@ describe Session, :account_limited do
175
173
 
176
174
  @new_posts = []
177
175
  end
178
-
179
-
180
- # skip "" do ; end
181
- # skip "" do ; end
182
-
183
176
  end
@@ -0,0 +1,136 @@
1
+
2
+ # These are the things that are hard or slow to test, so they need to
3
+ # be run by hand, possibly with some external intervention.
4
+
5
+
6
+ require_relative 'spec_helper'
7
+ require_relative '../lib/shep'
8
+
9
+ include Shep
10
+
11
+
12
+ # Test `dismiss_notification`; this permanently dismisses the most
13
+ # recent notification so you will need to first confirm that a)
14
+ # there's a notification present and b) it's one you don't care about.
15
+ describe Session, :tricky_del_notification do
16
+ it "expects to be configured for writing" do
17
+ expect(WRITE_ACCOUNT) .to_not be nil
18
+ end
19
+
20
+ it "dismisses notifications" do
21
+ ss = Session.new(host: HOST, token: TOKEN, ua_comment: "(integration test)")
22
+
23
+ # We dismiss the first notification, then confirm that it is no
24
+ # longer there. Since this is not repeatable, we skip it by
25
+ # default and manually enable it when we want to test it.
26
+
27
+ ntfns = ss.each_notification(limit: 10).to_a
28
+ expect( ntfns.size ) .to be > 0
29
+ first = ntfns[0]
30
+
31
+ ss.dismiss_notification(first.id)
32
+
33
+ ntfns2 = ss.each_notification(limit: 10).to_a
34
+ expect( ntfns2.size ) .to eq ntfns.size - 1
35
+ expect( ntfns2[0] ) .to_not eq first
36
+ end
37
+ end
38
+
39
+
40
+ # These tests exhaust the ratelimit of the delete API endpoint several
41
+ # times. Running these two tests takes a long time and leaves us with
42
+ # no more deletes.
43
+ describe Session, :tricky_ratelimit do
44
+
45
+ it "expects to be configured for writing" do
46
+ expect(WRITE_ACCOUNT) .to_not be nil
47
+ end
48
+
49
+ it "retries when the rate limit is reached" do
50
+ # Enables retry mode and sets rlhook as the hook function to call,
51
+ # then posts and deletes status until the hook as been called.
52
+ # Afterward, we make one more try.
53
+
54
+ rlhook_called = false
55
+ rlhook = proc do |rl|
56
+ rlhook_called = true
57
+
58
+ delay = (rl.reset - Time.now).round
59
+ STDOUT.puts "Waiting #{delay}s for rate limit to reset."
60
+
61
+ # We stop at the 3 second mark so the underlying delay will also
62
+ # kick in.
63
+ while rl.reset - 3 >= Time.now
64
+ STDOUT.print "\r #{(rl.reset - Time.now).round} seconds "
65
+ STDOUT.flush
66
+ sleep 1
67
+ end
68
+
69
+ STDOUT.puts "\nDone!"
70
+ end
71
+
72
+ ss = Session.new(host: HOST,
73
+ token: TOKEN,
74
+ ua_comment: "(integration test; rate limit reached)",
75
+
76
+ rate_limit_retry: true,
77
+ retry_hook: rlhook,
78
+
79
+ logger: :info
80
+ )
81
+
82
+ post_and_del = proc do
83
+ testpost = "test post for deleting9 #{POST_UUID} #{Time.now}"
84
+ post = ss.post_status(testpost)
85
+ delpost = ss.delete_status(post.id)
86
+
87
+ expect( post.id ) .to eq delpost.id
88
+
89
+ STDOUT.print "."
90
+ STDOUT.flush
91
+ end
92
+
93
+
94
+ limit = nil
95
+ count = 0
96
+ while !rlhook_called
97
+ post_and_del.call
98
+
99
+ # First pass, we fetch the deletion limit
100
+ limit = ss.rate_limit.limit unless limit
101
+
102
+ count += 1
103
+ expect( count ) .to be < (2*limit + 1)
104
+ end
105
+
106
+ # Ensure we did at least one iteration
107
+ expect( count ) .to be >= 1
108
+ expect( rlhook_called ) .to be true
109
+
110
+ # And ensure that we can do another post/delete cycle
111
+ post_and_del.call
112
+ expect( ss.rate_limit.remaining ) .to be > 0
113
+ end
114
+
115
+
116
+ # This test will deliberately exhaust the deletion rate limit.
117
+ it "throws Error::RateLimit when rate limit is exhusted" do
118
+ # We post and delete the post until the ratelimit is exhausted, at
119
+ # which point Session should throw a Shep::Error::RateLimit
120
+
121
+ ss = Session.new(host: HOST,
122
+ token: TOKEN,
123
+ ua_comment: "(integration test; rate limit reached)")
124
+
125
+ post_and_del = proc{
126
+ testpost = "test post #{POST_UUID} #{Time.now}"
127
+ post = ss.post_status(testpost)
128
+ delpost = ss.delete_status(post.id)
129
+
130
+ expect( post.id ) .to eq delpost.id
131
+ }
132
+
133
+ expect { 50.times{ post_and_del.call } }
134
+ .to raise_error(Shep::Error::RateLimit)
135
+ end
136
+ end
data/spec/spec_helper.rb CHANGED
@@ -20,13 +20,22 @@ WRITE_ACCOUNT = ENV['SHEP_ACCOUNT']
20
20
  ALL_TESTS_REQUESTED = !!ENV['SHEP_TEST_ALL']
21
21
 
22
22
 
23
+
24
+ # UUID to put in test posts so we can identify them when testing deletion.
25
+ POST_UUID = "fc49e486-d445-4ca7-9d6d-a27c89c5c471" #SecureRandom.uuid
26
+ # Currently a constant so that I can clean up after broken tests.
27
+ # Ideally, this should be different for each run.
28
+
29
+
23
30
  # Tags:
24
31
  #
25
- # offline - runs without a Mastodon server
32
+ # offline - runs without a Mastodon server (always on)
26
33
  # anonymous - requires a server but no login
27
34
  # account - requires normal server account (which it *may* modify!)
28
35
  # account_limited - like 'account' but will also perform heavily
29
36
  # rate-limited actions (e.g. delete, upload media)
37
+ #
38
+ #
30
39
 
31
40
 
32
41
  RSpec.configure {|conf|
@@ -52,8 +61,8 @@ RSpec.configure {|conf|
52
61
  puts
53
62
 
54
63
  conf.filter_run_including(:offline)
55
- conf.filter_run_including(:anonymous) if allow_anonymous
56
- conf.filter_run_including(:account) if allow_account
64
+ conf.filter_run_including(:anonymous) if allow_anonymous
65
+ conf.filter_run_including(:account) if allow_account
57
66
  conf.filter_run_including(:account_limited) if allow_limited
58
67
  end
59
68
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.alpha0
4
+ version: 0.2.0.pre.alpha0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Reuter
@@ -11,42 +11,42 @@ cert_chain: []
11
11
  date: 2023-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: rspec
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
19
  version: 3.12.0
19
- name: rspec
20
- prerelease: false
21
20
  type: :development
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.12.0
27
27
  - !ruby/object:Gem::Dependency
28
+ name: yard
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - "~>"
31
32
  - !ruby/object:Gem::Version
32
33
  version: 0.9.34
33
- name: yard
34
- prerelease: false
35
34
  type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.9.34
41
41
  - !ruby/object:Gem::Dependency
42
+ name: rake
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - "~>"
45
46
  - !ruby/object:Gem::Version
46
47
  version: 13.0.6
47
- name: rake
48
- prerelease: false
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
@@ -81,6 +81,7 @@ files:
81
81
  - doc/Shep/Error.html
82
82
  - doc/Shep/Error/Caller.html
83
83
  - doc/Shep/Error/Http.html
84
+ - doc/Shep/Error/RateLimit.html
84
85
  - doc/Shep/Error/Remote.html
85
86
  - doc/Shep/Error/Server.html
86
87
  - doc/Shep/Error/Type.html
@@ -105,6 +106,7 @@ files:
105
106
  - lib/shep/exceptions.rb
106
107
  - lib/shep/session.rb
107
108
  - lib/shep/typeboxes.rb
109
+ - lib/shep/version.rb
108
110
  - run_rake_test.example.sh
109
111
  - shep.gemspec
110
112
  - spec/data/smallimg.jpg
@@ -125,11 +127,12 @@ files:
125
127
  - spec/session_reader_1_unauth_spec.rb
126
128
  - spec/session_reader_2_auth_spec.rb
127
129
  - spec/session_writer_spec.rb
130
+ - spec/session_zzz_tricky_spec.rb
128
131
  - spec/spec_helper.rb
129
132
  - yard_helper.rb
130
133
  homepage: https://codeberg.org/suetanvil/shep
131
134
  licenses:
132
- - AGPL with linking exemption
135
+ - AGPL-3.0-only with linking exception
133
136
  metadata: {}
134
137
  post_install_message:
135
138
  rdoc_options: []
@@ -147,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
150
  version: 1.3.1
148
151
  requirements:
149
152
  - A Ruby implementing 3.0.x syntax and the standard libs.
150
- rubygems_version: 3.3.25
153
+ rubygems_version: 3.2.32
151
154
  signing_key:
152
155
  specification_version: 4
153
156
  summary: An alternate interface to the Mastodon Web API