basket 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a3e9da361b2587c986144240ada1490a812ae9a9d0f6f639c0e38c167874ac8
4
- data.tar.gz: 936a8d8b31d126cd35913cc1c087ecffbca722a2d5cc06747b23f26ba90d9055
3
+ metadata.gz: 8ac7e6fe22a043a420bf43a2dddcf0a9eee9f9fc647624e6aeecadb0f6ffb0e6
4
+ data.tar.gz: 043aa8c1033f8b58cf28ca41609397eb7872846ef139e9fb10654700ef61cefc
5
5
  SHA512:
6
- metadata.gz: 551534c644dbb4a269f2de9de81ae43aef66f7e41dedef2e27845d4edcd17584d74067339110611628052282f5601ca9d5c39dd7962a4a71103110b9d1b37b1a
7
- data.tar.gz: 96af7b3698edec4b70b3fa13acbb007ee17a03750c2df6583ed42df0e144bc32da8074378425ac24a655e6630070d2bcadd5b9870f2e4523804003fcdbd72fb6
6
+ metadata.gz: 8075bdd1180e9a58b5debec7a9925b1b1a08c1fdec6935e36fba4f1442cb6372c21b5d4ea02215a78a5710d87787c4cfe826ed2f8a0cd0328f25bdab08f93b52
7
+ data.tar.gz: a91e1571c99a3a20432186464eaeb4f57068cda33aeddbc912b5e358c83106a11c698fa902e20b1c4dc2809558d1d650381982d61464c900750caf15380c44ab
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,10 @@
1
+ # Contributing to Basket
2
+
3
+ This is a small project. We welcome ideas, contributions, thoughts, issues, bug reports, questions and any other thing you might like to add.
4
+
5
+ If you do want to add something, open and issue and we will respond! Our current list of issues is sort of short hand between to the two authors, but we'd be happy to clarify anything if you are so interested.
6
+
7
+ We use `standardrb` for linting.
8
+ We use `rspec`.
9
+
10
+ If this is your first contribution to any open source project, we'd be happy to help you get something merged! If you have an idea or question and are new to Ruby, we would love to help you!
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in basket.gemspec
6
6
  gemspec
7
7
 
8
+ gem "pry"
8
9
  gem "guard"
9
10
  gem "guard-rspec", require: false
10
11
  gem "guard-standardrb", require: false
@@ -13,4 +14,4 @@ gem "rake", "~> 13.0"
13
14
  gem "rspec", "~> 3.0"
14
15
  gem "simplecov", require: false, group: :test
15
16
  gem "simplecov-json", require: false, group: :test
16
- gem "standard", "~> 1.3"
17
+ gem "standard", "~> 1.27"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- basket (0.0.6)
4
+ basket (0.0.7)
5
5
  redis
6
6
  redis-namespace
7
7
 
@@ -47,8 +47,8 @@ GEM
47
47
  notiffany (0.1.3)
48
48
  nenv (~> 0.1)
49
49
  shellany (~> 0.0)
50
- parallel (1.22.1)
51
- parser (3.2.1.0)
50
+ parallel (1.23.0)
51
+ parser (3.2.2.0)
52
52
  ast (~> 2.4.1)
53
53
  pry (0.14.2)
54
54
  coderay (~> 1.1)
@@ -64,7 +64,7 @@ GEM
64
64
  connection_pool
65
65
  redis-namespace (1.10.0)
66
66
  redis (>= 4)
67
- regexp_parser (2.7.0)
67
+ regexp_parser (2.8.0)
68
68
  rexml (3.2.5)
69
69
  rspec (3.12.0)
70
70
  rspec-core (~> 3.12.0)
@@ -79,22 +79,22 @@ GEM
79
79
  diff-lcs (>= 1.2.0, < 2.0)
80
80
  rspec-support (~> 3.12.0)
81
81
  rspec-support (3.12.0)
82
- rubocop (1.44.1)
82
+ rubocop (1.50.2)
83
83
  json (~> 2.3)
84
84
  parallel (~> 1.10)
85
85
  parser (>= 3.2.0.0)
86
86
  rainbow (>= 2.2.2, < 4.0)
87
87
  regexp_parser (>= 1.8, < 3.0)
88
88
  rexml (>= 3.2.5, < 4.0)
89
- rubocop-ast (>= 1.24.1, < 2.0)
89
+ rubocop-ast (>= 1.28.0, < 2.0)
90
90
  ruby-progressbar (~> 1.7)
91
91
  unicode-display_width (>= 2.4.0, < 3.0)
92
- rubocop-ast (1.26.0)
92
+ rubocop-ast (1.28.0)
93
93
  parser (>= 3.2.1.0)
94
- rubocop-performance (1.15.2)
94
+ rubocop-performance (1.16.0)
95
95
  rubocop (>= 1.7.0, < 2.0)
96
96
  rubocop-ast (>= 0.4.0)
97
- ruby-progressbar (1.11.0)
97
+ ruby-progressbar (1.13.0)
98
98
  ruby2_keywords (0.0.5)
99
99
  shellany (0.0.1)
100
100
  simplecov (0.22.0)
@@ -106,10 +106,10 @@ GEM
106
106
  json
107
107
  simplecov
108
108
  simplecov_json_formatter (0.1.4)
109
- standard (1.24.3)
109
+ standard (1.27.0)
110
110
  language_server-protocol (~> 3.17.0.2)
111
- rubocop (= 1.44.1)
112
- rubocop-performance (= 1.15.2)
111
+ rubocop (~> 1.50.2)
112
+ rubocop-performance (~> 1.16.0)
113
113
  standardrb (1.0.1)
114
114
  standard
115
115
  thor (1.2.1)
@@ -128,11 +128,12 @@ DEPENDENCIES
128
128
  guard-standardrb
129
129
  mock_redis
130
130
  mocktail
131
+ pry
131
132
  rake (~> 13.0)
132
133
  rspec (~> 3.0)
133
134
  simplecov
134
135
  simplecov-json
135
- standard (~> 1.3)
136
+ standard (~> 1.27)
136
137
 
137
138
  BUNDLED WITH
138
139
  2.4.6
data/README.md CHANGED
@@ -22,6 +22,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
22
22
  $ gem install basket
23
23
 
24
24
  ## Usage
25
+ ### Adding
25
26
 
26
27
  Add items to your basket as they come along. They might come along quickly, or there might be a delay between them. Regardless, you want to collect items into your basket before going and doing something with them.
27
28
 
@@ -34,6 +35,10 @@ end
34
35
 
35
36
  The item added to the basket can be any data you want! If you are using the in memory Queue, it is fine to store Ruby objects, but if you have a different backend, must be JSON serializable via `to_json`.
36
37
 
38
+ ### Your basket
39
+
40
+ When a basket has become full after you have added a bunch of things to it, it performs actions! See below for the full definition of a basket.
41
+
37
42
  ```ruby
38
43
  class QuicheBasket
39
44
  # Include the Basket::Batcher
@@ -84,6 +89,51 @@ The `on_failure` use of `batch` of course may not have a full batch as the error
84
89
 
85
90
  Defining `on_add`, `on_failure`, and `on_success` is optional.
86
91
 
92
+ ### Search
93
+
94
+ You may search through your basket, if for example, you need to see if you've accidentally collected a robin egg and not a chicken egg!
95
+
96
+ ```ruby
97
+ search_results = Basket.search("QuicheBasket") do |egg|
98
+ egg.color == "blue"
99
+ end
100
+ ```
101
+
102
+ The block you pass will match against the objects in your basket. If you have ruby objects in your basket, you can match against their properties just as if you were accessing them one at a time. If you have json objects in your basket, you will be searching through a hash thusly:
103
+
104
+ ```ruby
105
+ search_results = Basket.search("PlaylistBasket") do |song|
106
+ song[:artist] == "Vansire"
107
+ end
108
+ ```
109
+
110
+ The search results will be a fully qualified basket element which will contain an id attribute and a data attribute. In the case of using the MemoryBackend, you might see something like this:
111
+
112
+ ```ruby
113
+ # ...continued from above
114
+ search_results.first #=> #<Basket::Element:0x00000001075d9c80
115
+ # @data=#<Egg color="blue", size="smol">
116
+ # @id="5fe3df9e-4063-4b67-a08f-e36b847087c7">
117
+ ```
118
+
119
+ You'll note that the result of a search is an array of basket elements. An element consists of the data that you put in and ID. What is the id for? Glad you asked.
120
+
121
+ ### Remove
122
+
123
+ You can also remove something from your basket. Perhaps it is deleted in the database and no longer contains a valid reference to data? Perhaps you found that robin egg and don't actually want to use it to make a quiche, because who would? Either way, removing the element is easy!
124
+
125
+ ```ruby
126
+ # ...continued from above
127
+ element_id_to_remove = search_results.first
128
+ removed_egg = Basket.remove('Quiche', element_id_to_remove)
129
+ removed_egg #=> #<Egg color="blue", size="smol">
130
+ ```
131
+
132
+ Voila!
133
+
134
+ ### A Note of Warning
135
+
136
+ Searching for and removing elements from your basket is an inherently tricky process as your basket may fill up and execute the `perform` action while searching and removing.
87
137
  ## Configuration
88
138
 
89
139
  In an initializer, or somewhere equally appropriate, you might put something like this:
@@ -132,5 +182,11 @@ The gem is available as open source under the terms of the [MIT License](https:/
132
182
 
133
183
  Everyone interacting in the Basket project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/nicholalexander/basket/blob/main/CODE_OF_CONDUCT.md).
134
184
 
185
+ ## Thanks
186
+
187
+ This project has been a fun and educational use of Growth Time at [Test Double](https://testdouble.com/) where consultants are given 4hrs per week to grow their skills and work on projects that further the mission of building software, better.
135
188
 
189
+ ## Authors
136
190
 
191
+ * [Nichol Alexander](https://github.com/nicholalexander/)
192
+ * [Alec Clarke](https://github.com/alecclarke)
data/SECURITY.md ADDED
@@ -0,0 +1,16 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We support Ruby versions as below:
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 3.2.2 | :white_check_mark: |
10
+ | 3.1.4 | :white_check_mark: |
11
+ | 3.0.6 | :white_check_mark: |
12
+ | < 4.0 | :x: |
13
+
14
+ ## Reporting a Vulnerability
15
+
16
+ If you discover a security related bug, please don't file an issue for it and instead let us know directly!
@@ -22,6 +22,17 @@ module Basket
22
22
  @data[queue]
23
23
  end
24
24
 
25
+ def search(queue, &block)
26
+ @data[queue].select { |element| block.call(element.data) }
27
+ end
28
+
29
+ def remove(queue, id)
30
+ index_of_element_to_delete = @data[queue].index { |element| element.id == id }
31
+ @data[queue].delete_at(index_of_element_to_delete)
32
+ rescue
33
+ nil
34
+ end
35
+
25
36
  def clear(queue)
26
37
  @data[queue] = []
27
38
  end
@@ -1,5 +1,4 @@
1
1
  require "redis-namespace"
2
- require "json"
3
2
 
4
3
  module Basket
5
4
  class BackendAdapter
@@ -25,6 +24,18 @@ module Basket
25
24
  response
26
25
  end
27
26
 
27
+ def search(queue, &block)
28
+ deserialized_queue_data(queue).select { |raw_element| block.call(raw_element["data"]) }
29
+ end
30
+
31
+ def remove(queue, element_id)
32
+ element = deserialized_queue_data(queue).find { |raw_element| raw_element["id"] == element_id }
33
+
34
+ @client.lrem(queue, 1, element.to_json)
35
+
36
+ element
37
+ end
38
+
28
39
  def push(queue, data)
29
40
  @client.lpush(queue, serialize_data(data))
30
41
  end
@@ -0,0 +1,38 @@
1
+ require "securerandom"
2
+
3
+ module Basket
4
+ class Element
5
+ class InvalidElement < StandardError; end
6
+
7
+ attr_reader :data, :id
8
+
9
+ def self.from_queue(element)
10
+ if element.is_a?(Element)
11
+ element
12
+ elsif element.is_a?(Hash)
13
+ new(element["data"], element["id"])
14
+ else
15
+ raise InvalidElement, "element must be a hash or a Basket::Element"
16
+ end
17
+ end
18
+
19
+ def initialize(data, id = SecureRandom.uuid)
20
+ raise InvalidElement, "both data and id must be present" unless data && id
21
+
22
+ @data = data
23
+ @id = id
24
+ end
25
+
26
+ def to_h
27
+ {data: data, id: id}
28
+ end
29
+
30
+ def to_json(*)
31
+ to_h.to_json
32
+ end
33
+
34
+ def ==(other)
35
+ to_h == other.to_h
36
+ end
37
+ end
38
+ end
data/lib/basket/error.rb CHANGED
@@ -2,4 +2,8 @@ module Basket
2
2
  class Error < StandardError; end
3
3
 
4
4
  class BasketNotFoundError < Error; end
5
+
6
+ class EmptyBasketError < Error; end
7
+
8
+ class ElementNotFoundError < Error; end
5
9
  end
@@ -5,7 +5,7 @@ module Basket
5
5
  end
6
6
 
7
7
  def push(queue, data)
8
- @backend.push(queue, data)
8
+ @backend.push(queue, Element.new(data))
9
9
  length(queue)
10
10
  end
11
11
 
@@ -14,7 +14,22 @@ module Basket
14
14
  end
15
15
 
16
16
  def read(queue)
17
- @backend.read(queue)
17
+ check_for_basket(queue)
18
+ raw_queue = @backend.read(queue)
19
+ raw_queue.map { |element| Element.from_queue(element).data }
20
+ end
21
+
22
+ def search(queue, query)
23
+ check_for_basket(queue)
24
+ check_for_zero_length(queue)
25
+ raw_search_results = @backend.search(queue, &query)
26
+ raw_search_results.map { |raw_search_result| Element.from_queue(raw_search_result) }
27
+ end
28
+
29
+ def remove(queue, id)
30
+ raw_removed_element = @backend.remove(queue, id)
31
+ check_for_raw_removed_element(raw_removed_element)
32
+ Element.from_queue(raw_removed_element).data
18
33
  end
19
34
 
20
35
  def clear(queue)
@@ -28,5 +43,19 @@ module Basket
28
43
  def reset_backend
29
44
  @backend = Basket.config.backend.new
30
45
  end
46
+
47
+ private
48
+
49
+ def check_for_basket(queue)
50
+ raise Basket::BasketNotFoundError unless Object.const_defined?(queue)
51
+ end
52
+
53
+ def check_for_zero_length(queue)
54
+ raise Basket::EmptyBasketError, "The basket #{queue} is empty." if length(queue).zero?
55
+ end
56
+
57
+ def check_for_raw_removed_element(raw_removed_element)
58
+ raise Basket::ElementNotFoundError if raw_removed_element.nil?
59
+ end
31
60
  end
32
61
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Basket
4
- VERSION = "0.0.6"
4
+ VERSION = "0.0.7"
5
5
  end
data/lib/basket.rb CHANGED
@@ -5,11 +5,14 @@ require_relative "basket/backend_adapter/memory_backend"
5
5
  require_relative "basket/backend_adapter/redis_backend"
6
6
  require_relative "basket/batcher"
7
7
  require_relative "basket/configuration"
8
+ require_relative "basket/element"
8
9
  require_relative "basket/error"
9
10
  require_relative "basket/handle_add"
10
11
  require_relative "basket/queue_collection"
11
12
  require_relative "basket/version"
12
13
 
14
+ require "json"
15
+
13
16
  module Basket
14
17
  class Error < StandardError; end
15
18
 
@@ -25,6 +28,10 @@ module Basket
25
28
  @queue_collection.data
26
29
  end
27
30
 
31
+ def self.peek(queue)
32
+ queue_collection.read(queue)
33
+ end
34
+
28
35
  def self.queue_collection
29
36
  @queue_collection ||= Basket::QueueCollection.new
30
37
  end
@@ -33,6 +40,14 @@ module Basket
33
40
  HandleAdd.call(queue, data)
34
41
  end
35
42
 
43
+ def self.search(queue, &query)
44
+ queue_collection.search(queue, query)
45
+ end
46
+
47
+ def self.remove(queue, id)
48
+ queue_collection.remove(queue, id)
49
+ end
50
+
36
51
  def self.clear_all
37
52
  queue_collection.reset_backend
38
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - nichol alexander
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-04-14 00:00:00.000000000 Z
12
+ date: 2023-04-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
@@ -66,12 +66,14 @@ files:
66
66
  - ".standard.yml"
67
67
  - CHANGELOG.md
68
68
  - CODE_OF_CONDUCT.md
69
+ - CONTRIBUTING.md
69
70
  - Gemfile
70
71
  - Gemfile.lock
71
72
  - Guardfile
72
73
  - LICENSE.txt
73
74
  - README.md
74
75
  - Rakefile
76
+ - SECURITY.md
75
77
  - basket.gemspec
76
78
  - lib/basket.rb
77
79
  - lib/basket/backend_adapter.rb
@@ -79,6 +81,7 @@ files:
79
81
  - lib/basket/backend_adapter/redis_backend.rb
80
82
  - lib/basket/batcher.rb
81
83
  - lib/basket/configuration.rb
84
+ - lib/basket/element.rb
82
85
  - lib/basket/error.rb
83
86
  - lib/basket/handle_add.rb
84
87
  - lib/basket/queue_collection.rb