mock_redis 0.20.0 → 0.25.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +26 -5
- data/.rubocop_todo.yml +1 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +37 -0
- data/Gemfile +2 -2
- data/LICENSE.md +21 -0
- data/README.md +37 -13
- data/lib/mock_redis.rb +0 -5
- data/lib/mock_redis/database.rb +53 -17
- data/lib/mock_redis/future.rb +1 -1
- data/lib/mock_redis/geospatial_methods.rb +4 -4
- data/lib/mock_redis/hash_methods.rb +22 -14
- data/lib/mock_redis/info_method.rb +2 -2
- data/lib/mock_redis/multi_db_wrapper.rb +2 -2
- data/lib/mock_redis/set_methods.rb +1 -0
- data/lib/mock_redis/stream.rb +22 -2
- data/lib/mock_redis/stream/id.rb +1 -1
- data/lib/mock_redis/stream_methods.rb +14 -1
- data/lib/mock_redis/string_methods.rb +28 -13
- data/lib/mock_redis/transaction_wrapper.rb +2 -2
- data/lib/mock_redis/utility_methods.rb +6 -3
- data/lib/mock_redis/version.rb +1 -1
- data/lib/mock_redis/zset_methods.rb +52 -9
- data/mock_redis.gemspec +1 -2
- data/spec/client_spec.rb +12 -0
- data/spec/commands/blpop_spec.rb +0 -6
- data/spec/commands/brpop_spec.rb +6 -5
- data/spec/commands/del_spec.rb +15 -0
- data/spec/commands/dump_spec.rb +19 -0
- data/spec/commands/exists_spec.rb +34 -5
- data/spec/commands/future_spec.rb +11 -1
- data/spec/commands/geoadd_spec.rb +1 -1
- data/spec/commands/hdel_spec.rb +16 -0
- data/spec/commands/hmset_spec.rb +26 -0
- data/spec/commands/hset_spec.rb +6 -6
- data/spec/commands/keys_spec.rb +17 -0
- data/spec/commands/mget_spec.rb +6 -0
- data/spec/commands/move_spec.rb +5 -5
- data/spec/commands/pipelined_spec.rb +20 -0
- data/spec/commands/restore_spec.rb +47 -0
- data/spec/commands/scan_spec.rb +9 -0
- data/spec/commands/set_spec.rb +12 -2
- data/spec/commands/setbit_spec.rb +1 -0
- data/spec/commands/setex_spec.rb +16 -0
- data/spec/commands/srandmember_spec.rb +1 -1
- data/spec/commands/srem_spec.rb +5 -0
- data/spec/commands/xadd_spec.rb +20 -0
- data/spec/commands/xrange_spec.rb +13 -0
- data/spec/commands/xread_spec.rb +50 -0
- data/spec/commands/xtrim_spec.rb +6 -0
- data/spec/commands/zinterstore_spec.rb +34 -0
- data/spec/commands/zpopmax_spec.rb +60 -0
- data/spec/commands/zpopmin_spec.rb +60 -0
- data/spec/commands/zrange_spec.rb +1 -1
- data/spec/commands/zrangebyscore_spec.rb +1 -1
- data/spec/commands/zrevrange_spec.rb +1 -1
- data/spec/commands/zrevrangebyscore_spec.rb +1 -1
- data/spec/commands/zunionstore_spec.rb +33 -0
- data/spec/mock_redis_spec.rb +4 -6
- data/spec/spec_helper.rb +4 -2
- data/spec/support/redis_multiplexer.rb +1 -0
- data/spec/transactions_spec.rb +16 -0
- metadata +16 -26
- data/LICENSE +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4a2d7e6a155059cb97120f7f95c1e992a87a3933be5fe337a443dc0a9ac30df
|
4
|
+
data.tar.gz: 135172a723e9d5bfb058eec85863387093d56e3a6d7729f28da425f2b239e4bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e1b5cba39d01b11b2c85442c5d9485285bf661316e5196448484bc78dd9d866c3829648cd547ac0996d454f113d054c3bc43728f917740870f5fe191c97b15c
|
7
|
+
data.tar.gz: bf5d20de1111be19c03cacb2639f303d0ced578656bfc5b4dae4e8cd6e28991be003e7a20702ab6825526fbee6f91ebcd676fbb27c9010792abd37a2e7eab218
|
data/.rubocop.yml
CHANGED
@@ -3,10 +3,10 @@ inherit_from: .rubocop_todo.yml
|
|
3
3
|
AllCops:
|
4
4
|
TargetRubyVersion: 2.4
|
5
5
|
|
6
|
-
Layout/
|
6
|
+
Layout/ArgumentAlignment:
|
7
7
|
Enabled: false
|
8
8
|
|
9
|
-
Layout/
|
9
|
+
Layout/ParameterAlignment:
|
10
10
|
Enabled: false
|
11
11
|
|
12
12
|
Layout/DotPosition:
|
@@ -15,9 +15,21 @@ Layout/DotPosition:
|
|
15
15
|
Layout/EmptyLineAfterGuardClause:
|
16
16
|
Enabled: false
|
17
17
|
|
18
|
+
Layout/LineLength:
|
19
|
+
Max: 100
|
20
|
+
|
21
|
+
Layout/SpaceAroundMethodCallOperator:
|
22
|
+
Enabled: true
|
23
|
+
|
18
24
|
Lint/AssignmentInCondition:
|
19
25
|
Enabled: false
|
20
26
|
|
27
|
+
Lint/RaiseException:
|
28
|
+
Enabled: true
|
29
|
+
|
30
|
+
Lint/StructNewOverride:
|
31
|
+
Enabled: true
|
32
|
+
|
21
33
|
# We use this a lot in specs where it's perfectly valid
|
22
34
|
Lint/Void:
|
23
35
|
Exclude:
|
@@ -35,9 +47,6 @@ Metrics/CyclomaticComplexity:
|
|
35
47
|
Metrics/ClassLength:
|
36
48
|
Enabled: false
|
37
49
|
|
38
|
-
Metrics/LineLength:
|
39
|
-
Max: 100
|
40
|
-
|
41
50
|
Metrics/MethodLength:
|
42
51
|
Enabled: false
|
43
52
|
|
@@ -57,6 +66,18 @@ Style/Documentation:
|
|
57
66
|
Style/DoubleNegation:
|
58
67
|
Enabled: false
|
59
68
|
|
69
|
+
Style/ExponentialNotation:
|
70
|
+
Enabled: true
|
71
|
+
|
72
|
+
Style/HashEachMethods:
|
73
|
+
Enabled: true
|
74
|
+
|
75
|
+
Style/HashTransformKeys:
|
76
|
+
Enabled: true
|
77
|
+
|
78
|
+
Style/HashTransformValues:
|
79
|
+
Enabled: true
|
80
|
+
|
60
81
|
# We have too much code that relies on modifying strings
|
61
82
|
Style/FrozenStringLiteralComment:
|
62
83
|
Enabled: false
|
data/.rubocop_todo.yml
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
# Offense count: 17
|
10
10
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
11
11
|
# AllowedNames: io, id, to, by, on, in, at, ip
|
12
|
-
Naming/
|
12
|
+
Naming/MethodParameterName:
|
13
13
|
Exclude:
|
14
14
|
- 'lib/mock_redis/database.rb'
|
15
15
|
- 'lib/mock_redis/expire_wrapper.rb'
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,42 @@
|
|
1
1
|
# MockRedis Changelog
|
2
2
|
|
3
|
+
### 0.25.0
|
4
|
+
|
5
|
+
* Add support for `xread` command ([#190](https://github.com/sds/mock_redis/pull/190))
|
6
|
+
* Fix `mget` to raise error when passing empty array ([#191](https://github.com/sds/mock_redis/pull/191))
|
7
|
+
* Fix `xadd` when `maxlen` is zero ([#192](https://github.com/sds/mock_redis/pull/192))
|
8
|
+
|
9
|
+
### 0.24.0
|
10
|
+
|
11
|
+
* Fix handling of blocks within `multi` blocks ([#185](https://github.com/sds/mock_redis/pull/185))
|
12
|
+
* Fix handling of multiple consecutive `?` characters in key pattern matching ([#186](https://github.com/sds/mock_redis/pull/186))
|
13
|
+
* Change `exists` to return an integer and add `exists?` ([#188](https://github.com/sds/mock_redis/pull/188))
|
14
|
+
|
15
|
+
### 0.23.0
|
16
|
+
|
17
|
+
* Raise error when `setex` called with negative timeout ([#174](https://github.com/sds/mock_redis/pull/174))
|
18
|
+
* Add support for `dump`/`restore` between MockRedis instances ([#176](https://github.com/sds/mock_redis/pull/176))
|
19
|
+
* Fix warnings for ZSET methods on Ruby 2.7 ([#177](https://github.com/sds/mock_redis/pull/177))
|
20
|
+
* Add support for returning time in pipelines ([#179](https://github.com/sds/mock_redis/pull/179))
|
21
|
+
* Fix SET methods to correct set milliseconds with `px` ([#180](https://github.com/sds/mock_redis/pull/180))
|
22
|
+
* Add support for unsorted sets within `zinterstore`/`zunionstore`([#182](https://github.com/sds/mock_redis/pull/182))
|
23
|
+
|
24
|
+
### 0.22.0
|
25
|
+
|
26
|
+
* Gracefully handle cursors larger than the collection size in scan commands ([#171](https://github.com/sds/mock_redis/pull/171))
|
27
|
+
* Add `zpopmin` and `zpopmax` commands ([#172](https://github.com/sds/mock_redis/pull/172))
|
28
|
+
* Fix `hmset` to support array arguments ([#173](https://github.com/sds/mock_redis/pull/173))
|
29
|
+
* Fix `hmset` to always treat keys as strings ([#173](https://github.com/sds/mock_redis/pull/173))
|
30
|
+
* Remove unnecessary dependency on `rake` gem
|
31
|
+
|
32
|
+
### 0.21.0
|
33
|
+
|
34
|
+
* Fix behavior of `time` to return array of two integers ([#161](https://github.com/sds/mock_redis/pull/161))
|
35
|
+
* Add support for `close` and `disconnect!` ([#163](https://github.com/sds/mock_redis/pull/163))
|
36
|
+
* Fix `set` to properly handle (and ignore) other options ([#164](https://github.com/sds/mock_redis/pull/163))
|
37
|
+
* Fix `srem` to allow array of integers as argument ([#166](https://github.com/sds/mock_redis/pull/166))
|
38
|
+
* Fix `hdel` to allow array as argument ([#168](https://github.com/sds/mock_redis/pull/168))
|
39
|
+
|
3
40
|
### 0.20.0
|
4
41
|
|
5
42
|
* Add support for `count` parameter of `spop`
|
data/Gemfile
CHANGED
@@ -4,9 +4,9 @@ source 'http://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
# Run all pre-commit hooks via Overcommit during CI runs
|
7
|
-
gem 'overcommit', '0.
|
7
|
+
gem 'overcommit', '0.53.0'
|
8
8
|
|
9
9
|
# Pin tool versions (which are executed by Overcommit) for Travis builds
|
10
|
-
gem 'rubocop', '0.
|
10
|
+
gem 'rubocop', '0.82.0'
|
11
11
|
|
12
12
|
gem 'coveralls', require: false
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MockRedis released under the MIT license.
|
2
|
+
|
3
|
+
> Copyright (c) Shane da Silva. http://shane.io
|
4
|
+
>
|
5
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
> of this software and associated documentation files (the "Software"), to deal
|
7
|
+
> in the Software without restriction, including without limitation the rights
|
8
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
> copies of the Software, and to permit persons to whom the Software is
|
10
|
+
> furnished to do so, subject to the following conditions:
|
11
|
+
>
|
12
|
+
> The above copyright notice and this permission notice shall be included in
|
13
|
+
> all copies or substantial portions of the Software.
|
14
|
+
>
|
15
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
> SOFTWARE.
|
data/README.md
CHANGED
@@ -8,11 +8,20 @@ MockRedis provides the same interface as `redis-rb`, but it stores its
|
|
8
8
|
data in memory instead of talking to a Redis server. It is intended
|
9
9
|
for use in tests.
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
## Requirements
|
12
|
+
|
13
|
+
* Ruby 2.4+
|
14
|
+
|
15
|
+
The current implementation is tested against **Redis 5**. Older versions may work, but can also return different results or not support some commands.
|
13
16
|
|
14
17
|
## Getting Started
|
15
18
|
|
19
|
+
Install the gem:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
gem install mock_redis
|
23
|
+
```
|
24
|
+
|
16
25
|
It's as easy as `require 'mock_redis'; mr = MockRedis.new`. Then you can
|
17
26
|
call the same methods on it as you can call on a real `Redis` object.
|
18
27
|
|
@@ -90,17 +99,32 @@ please submit a pull request with your (tested!) implementation.
|
|
90
99
|
* `#config(:get|:set|:resetstat)` isn't done. They can just return
|
91
100
|
canned values.
|
92
101
|
|
93
|
-
##
|
102
|
+
## Running tests
|
103
|
+
|
104
|
+
We recommend running Redis within a Docker container to make development as simple as possible, but as long as you have a Redis instance listening on `localhost:6379` you should be good to go.
|
105
|
+
|
106
|
+
1. Start Redis.
|
107
|
+
```bash
|
108
|
+
docker run --rm -p 6379:6379 redis
|
109
|
+
```
|
110
|
+
2. Install dependencies.
|
111
|
+
```bash
|
112
|
+
bundle install
|
113
|
+
```
|
114
|
+
3. Run tests.
|
115
|
+
```bash
|
116
|
+
bundle exec rspec
|
117
|
+
```
|
118
|
+
|
119
|
+
These tests were written with Redis running on `localhost` without any
|
120
|
+
passwords required. If you're using a different version of Redis, you
|
121
|
+
may see failures due to error message text being different and other
|
122
|
+
breaking changes over time.
|
123
|
+
|
124
|
+
## Changelog
|
94
125
|
|
95
|
-
|
96
|
-
older versions of Ruby, use `0.18.0` or older.
|
126
|
+
If you're interested in seeing the changes and bug fixes between each version of `mock_redis`, read the [MockRedis Changelog](CHANGELOG.md).
|
97
127
|
|
98
|
-
##
|
128
|
+
## License
|
99
129
|
|
100
|
-
|
101
|
-
tests. (Just kidding! There's no probably about it.) These tests were
|
102
|
-
written with Redis running on `localhost` without any passwords
|
103
|
-
required. If you're using a different version of Redis, you may see
|
104
|
-
failures due to error message text being different. If you're running
|
105
|
-
a really old version of Redis, you'll definitely see failures due to
|
106
|
-
stuff that doesn't work!
|
130
|
+
This project is released under the [MIT license](LICENSE.md).
|
data/lib/mock_redis.rb
CHANGED
data/lib/mock_redis/database.rb
CHANGED
@@ -35,7 +35,7 @@ class MockRedis
|
|
35
35
|
|
36
36
|
def initialize_copy(_source)
|
37
37
|
@data = @data.clone
|
38
|
-
@data.
|
38
|
+
@data.each_key { |k| @data[k] = @data[k].clone }
|
39
39
|
@expire_times = @expire_times.map(&:clone)
|
40
40
|
end
|
41
41
|
|
@@ -56,6 +56,8 @@ class MockRedis
|
|
56
56
|
def disconnect
|
57
57
|
nil
|
58
58
|
end
|
59
|
+
alias close disconnect
|
60
|
+
alias disconnect! close
|
59
61
|
|
60
62
|
def connected?
|
61
63
|
true
|
@@ -86,7 +88,8 @@ class MockRedis
|
|
86
88
|
end
|
87
89
|
|
88
90
|
def pexpire(key, ms)
|
89
|
-
|
91
|
+
now, miliseconds = @base.now
|
92
|
+
now_ms = (now * 1000) + miliseconds
|
90
93
|
pexpireat(key, now_ms + ms.to_i)
|
91
94
|
end
|
92
95
|
|
@@ -103,7 +106,7 @@ class MockRedis
|
|
103
106
|
raise Redis::CommandError, 'ERR value is not an integer or out of range'
|
104
107
|
end
|
105
108
|
|
106
|
-
if exists(key)
|
109
|
+
if exists?(key)
|
107
110
|
timestamp = Rational(timestamp_ms.to_i, 1000)
|
108
111
|
set_expiration(key, @base.time_at(timestamp))
|
109
112
|
true
|
@@ -112,12 +115,33 @@ class MockRedis
|
|
112
115
|
end
|
113
116
|
end
|
114
117
|
|
115
|
-
def exists(
|
116
|
-
data.key?(key)
|
118
|
+
def exists(*keys)
|
119
|
+
keys.count { |key| data.key?(key) }
|
120
|
+
end
|
121
|
+
|
122
|
+
def exists?(*keys)
|
123
|
+
keys.each { |key| return true if data.key?(key) }
|
124
|
+
false
|
117
125
|
end
|
118
126
|
|
119
127
|
def flushdb
|
120
|
-
data.
|
128
|
+
data.each_key { |k| del(k) }
|
129
|
+
'OK'
|
130
|
+
end
|
131
|
+
|
132
|
+
def dump(key)
|
133
|
+
value = data[key]
|
134
|
+
value ? Marshal.dump(value) : nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def restore(key, ttl, value, replace: false)
|
138
|
+
if !replace && exists?(key)
|
139
|
+
raise Redis::CommandError, 'BUSYKEY Target key name already exists.'
|
140
|
+
end
|
141
|
+
data[key] = Marshal.load(value) # rubocop:disable Security/MarshalLoad
|
142
|
+
if ttl > 0
|
143
|
+
pexpire(key, ttl)
|
144
|
+
end
|
121
145
|
'OK'
|
122
146
|
end
|
123
147
|
|
@@ -140,11 +164,11 @@ class MockRedis
|
|
140
164
|
end
|
141
165
|
|
142
166
|
def lastsave
|
143
|
-
|
167
|
+
now.first
|
144
168
|
end
|
145
169
|
|
146
170
|
def persist(key)
|
147
|
-
if exists(key) && has_expiration?(key)
|
171
|
+
if exists?(key) && has_expiration?(key)
|
148
172
|
remove_expiration(key)
|
149
173
|
true
|
150
174
|
else
|
@@ -185,7 +209,7 @@ class MockRedis
|
|
185
209
|
raise Redis::CommandError, 'ERR no such key'
|
186
210
|
end
|
187
211
|
|
188
|
-
if exists(newkey)
|
212
|
+
if exists?(newkey)
|
189
213
|
false
|
190
214
|
else
|
191
215
|
rename(key, newkey)
|
@@ -198,27 +222,38 @@ class MockRedis
|
|
198
222
|
end
|
199
223
|
|
200
224
|
def ttl(key)
|
201
|
-
if !exists(key)
|
225
|
+
if !exists?(key)
|
202
226
|
-2
|
203
227
|
elsif has_expiration?(key)
|
204
|
-
|
228
|
+
now, = @base.now
|
229
|
+
expiration(key).to_i - now
|
205
230
|
else
|
206
231
|
-1
|
207
232
|
end
|
208
233
|
end
|
209
234
|
|
210
235
|
def pttl(key)
|
211
|
-
|
236
|
+
now, miliseconds = @base.now
|
237
|
+
now_ms = now * 1000 + miliseconds
|
238
|
+
|
239
|
+
if !exists?(key)
|
212
240
|
-2
|
213
241
|
elsif has_expiration?(key)
|
214
|
-
(expiration(key).to_r * 1000).to_i -
|
242
|
+
(expiration(key).to_r * 1000).to_i - now_ms
|
215
243
|
else
|
216
244
|
-1
|
217
245
|
end
|
218
246
|
end
|
219
247
|
|
248
|
+
def now
|
249
|
+
current_time = @base.options[:time_class].now
|
250
|
+
miliseconds = (current_time.to_r - current_time.to_i) * 1_000
|
251
|
+
[current_time.to_i, miliseconds.to_i]
|
252
|
+
end
|
253
|
+
alias time now
|
254
|
+
|
220
255
|
def type(key)
|
221
|
-
if !exists(key)
|
256
|
+
if !exists?(key)
|
222
257
|
'none'
|
223
258
|
elsif hashy?(key)
|
224
259
|
'hash'
|
@@ -293,7 +328,7 @@ class MockRedis
|
|
293
328
|
Regexp.new(
|
294
329
|
"^#{pattern}$".
|
295
330
|
gsub(/([+|()])/, '\\\\\1').
|
296
|
-
gsub(/(
|
331
|
+
gsub(/(?<!\\)\?/, '\\1.').
|
297
332
|
gsub(/([^\\])\*/, '\\1.*')
|
298
333
|
)
|
299
334
|
end
|
@@ -321,10 +356,11 @@ class MockRedis
|
|
321
356
|
# This method isn't private, but it also isn't a Redis command, so
|
322
357
|
# it doesn't belong up above with all the Redis commands.
|
323
358
|
def expire_keys
|
324
|
-
|
359
|
+
now_sec, miliseconds = now
|
360
|
+
now_ms = now_sec * 1_000 + miliseconds
|
325
361
|
|
326
362
|
to_delete = expire_times.take_while do |(time, _key)|
|
327
|
-
(time.to_r * 1_000).to_i <=
|
363
|
+
(time.to_r * 1_000).to_i <= now_ms
|
328
364
|
end
|
329
365
|
|
330
366
|
to_delete.each do |(_time, key)|
|
data/lib/mock_redis/future.rb
CHANGED
@@ -38,7 +38,7 @@ class MockRedis
|
|
38
38
|
lng2, lat2 = geohash_decode(hash2)
|
39
39
|
|
40
40
|
distance = geohash_distance(lng1, lat1, lng2, lat2) / to_meter
|
41
|
-
format('
|
41
|
+
format('%<distance>.4f', distance: distance)
|
42
42
|
end
|
43
43
|
|
44
44
|
def geohash(key, members)
|
@@ -95,8 +95,8 @@ class MockRedis
|
|
95
95
|
lat = Float(point[1])
|
96
96
|
|
97
97
|
unless LNG_RANGE.include?(lng) && LAT_RANGE.include?(lat)
|
98
|
-
lng = format('
|
99
|
-
lat = format('
|
98
|
+
lng = format('%<long>.6f', long: lng)
|
99
|
+
lat = format('%<lat>.6f', lat: lat)
|
100
100
|
raise Redis::CommandError,
|
101
101
|
"ERR invalid longitude,latitude pair #{lng},#{lat}"
|
102
102
|
end
|
@@ -201,7 +201,7 @@ class MockRedis
|
|
201
201
|
end
|
202
202
|
|
203
203
|
def format_decoded_coord(coord)
|
204
|
-
coord = format('
|
204
|
+
coord = format('%<coord>.17f', coord: coord)
|
205
205
|
l = 1
|
206
206
|
l += 1 while coord[-l] == '0'
|
207
207
|
coord = coord[0..-l]
|