rencoder 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a0a89dc8e168dfd539d8c8c6e2280f84d44fbf46
4
- data.tar.gz: 4f32d7cd11b02e312fce9ea333fb98f247e251c4
2
+ SHA256:
3
+ metadata.gz: f87f5dfd83820c67adf886b6b38ecc9ee5aa57da16e545c9f2698f7d94d8c1b2
4
+ data.tar.gz: 188690f46aff4d973bb593b83bdf775eb784a6608942d7af08bb3eb6ebb59432
5
5
  SHA512:
6
- metadata.gz: b2325cff13c80b3b2ef4961c117f574904ee468ff1f04cceb3a47ea10edad9a0d2460065c5934fa4458ab38ed1b82d27e78dbb4f7f129e278413f167e9385146
7
- data.tar.gz: 21fe2903654904c946c2e422637bfe959fbb37c2fc0114acb25ab4ab78f7cfe32685895f44f882162e3e551b6ae19ccbb5b8970bcd1444c58e57ba38ec72f252
6
+ metadata.gz: 51cf0155f687f6687112a9e8953df56441847f7ca43c64c17eab7ca5db5f293febe61da70c8681a579d0265eeb0ca1d567baf10aff0ef33799dd2fde626e5a37
7
+ data.tar.gz: 8b36e60bc122a7e8a7b17d9b0ec829f55f0c5896d17815813a1654e13217b33086ea626426846ef9d9143ca3b83f7f60002432fcdd1a60ce70cf3880fe7abd96
@@ -0,0 +1,30 @@
1
+ name: Publish Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v0.*
7
+ release:
8
+ types: [published]
9
+ jobs:
10
+ build:
11
+ name: Build + Publish
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby 2.7
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.7.x
20
+
21
+ - name: Publish to RubyGems
22
+ run: |
23
+ mkdir -p $HOME/.gem
24
+ touch $HOME/.gem/credentials
25
+ chmod 0600 $HOME/.gem/credentials
26
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
27
+ gem build *.gemspec
28
+ gem push *.gem
29
+ env:
30
+ GEM_HOST_API_KEY: "Bearer ${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,33 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: On Push
9
+
10
+ on: [push, pull_request]
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ max-parallel: 4
17
+ matrix:
18
+ ruby-version: [2.4, 2.7]
19
+ steps:
20
+ - uses: actions/checkout@v2
21
+ - name: Set up Ruby ${{ matrix.ruby-version }}
22
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
23
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
24
+ # uses: ruby/setup-ruby@v1
25
+ uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
26
+ with:
27
+ ruby-version: ${{ matrix.ruby-version }}
28
+ - name: Install dependencies
29
+ run: bundle install
30
+ - name: Run RuboCop
31
+ run: bundle exec rubocop
32
+ - name: Run RSpec
33
+ run: bundle exec rspec spec
@@ -0,0 +1,27 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://docs.rubocop.org/rubocop/configuration
11
+
12
+ require: rubocop-rspec
13
+
14
+
15
+ AllCops:
16
+ NewCops: enable
17
+
18
+ Metrics/BlockLength:
19
+ Exclude:
20
+ - spec/**/*.rb
21
+
22
+
23
+ Metrics/MethodLength:
24
+ Max: 30
25
+
26
+ Metrics/CyclomaticComplexity:
27
+ Max: 10
@@ -1 +1 @@
1
- 2.1.4
1
+ 2.7
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in rencoder.gemspec
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Rencoder
2
2
 
3
- Rencoder is pure Ruby implementation of Rencode serialization format encoding/decoding.
3
+ Rencoder is a pure Ruby implementation of Rencode serialization format encoding/decoding.
4
4
 
5
- Rencoder is *FULLY* compliant with Python implementation, and uses all optimizations (by-type-offset integers, strings, arrays, hashes) both in encoding and decoding.
5
+ Rencoder is a *FULLY* compliant with Python implementation, and uses all optimizations (by-type-offset integers, strings, arrays, hashes) both for encoding and decoding.
6
6
 
7
- Rencoder has no runtime dependencies. Everything done in a pure Ruby.
7
+ Rencoder have no runtime dependencies. Everything done in a pure Ruby.
8
8
 
9
9
  More about Rencode format:
10
10
  - <https://github.com/aresch/rencode>
@@ -30,15 +30,15 @@ Rencoder.dump(["hello", :world, 123]) # Arrays
30
30
  ```
31
31
 
32
32
  **Float precion notice**
33
- Rencoder uses 64-bit precision by default.
34
- It's highly recommended to stay that way.
35
- If there is strong reason to use 32-bit precision, then please specify
36
- ``float32: true`` option for ``Rencoder.dump``:
33
+ Rencoder uses a 64-bit precision by default.
34
+ It's recommended to stay this way.
35
+ If there is a strong reason to use 32-bit precision, then please specify
36
+ ``float32: true`` option in a ``Rencoder.dump`` call:
37
37
 
38
38
  ```ruby
39
39
  Rencoder.dump(1.000001, float32: true)
40
40
  ```
41
- ***Using 32-bit precision is highly NOT recommended***
41
+ ***Using 32-bit precision is NOT recommended***
42
42
 
43
43
  ### Deserialization
44
44
 
@@ -52,7 +52,7 @@ Rencoder.load(string_data)
52
52
  # => "Hello World"
53
53
  ```
54
54
 
55
- **Rencoder can read data from any IO object directly without using any buffers**
55
+ **Rencoder can read data from any IO object directly, without using any buffers**
56
56
  ```ruby
57
57
  socket = TCPSocket.new('example.com', 8814)
58
58
  Rendcoder.load(socket)
@@ -61,7 +61,7 @@ Rendcoder.load(socket)
61
61
 
62
62
  ### ActiveRecord
63
63
 
64
- Rencoder is compliant with ActiveSupport ``serialize`` interface:
64
+ Rencoder is compliant with the ActiveSupport's ``serialize`` interface:
65
65
 
66
66
  ```ruby
67
67
  class MyModel < ActiveRecord::Base
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rencoder/version'
2
4
 
5
+ # Rencode format encoder/decoder
3
6
  module Rencoder
4
7
  # Rencoder Constants
5
8
  MAX_INT_LENGTH = 64
@@ -22,30 +25,30 @@ module Rencoder
22
25
  # Dictionaries with length embedded in typecode.
23
26
  DICT_FIXED_START = 102
24
27
  DICT_FIXED_COUNT = 25
25
- DICT_FIXED = (DICT_FIXED_START...DICT_FIXED_START + DICT_FIXED_COUNT)
28
+ DICT_FIXED = (DICT_FIXED_START...DICT_FIXED_START + DICT_FIXED_COUNT).freeze
26
29
 
27
30
  # Positive integers with value embedded in typecode.
28
31
  INT_POS_FIXED_START = 0
29
32
  INT_POS_FIXED_COUNT = 44
30
- INT_POS_FIXED = (INT_POS_FIXED_START...INT_POS_FIXED_START + INT_POS_FIXED_COUNT)
33
+ INT_POS_FIXED = (INT_POS_FIXED_START...INT_POS_FIXED_START + INT_POS_FIXED_COUNT).freeze
31
34
 
32
35
  # Negative integers with value embedded in typecode.
33
36
  INT_NEG_FIXED_START = 70
34
37
  INT_NEG_FIXED_COUNT = 32
35
- INT_NEG_FIXED = (INT_NEG_FIXED_START...INT_NEG_FIXED_START + INT_NEG_FIXED_COUNT)
38
+ INT_NEG_FIXED = (INT_NEG_FIXED_START...INT_NEG_FIXED_START + INT_NEG_FIXED_COUNT).freeze
36
39
 
37
40
  # String length header
38
- STR_HEADER = ('0'.ord..'9'.ord)
41
+ STR_HEADER = ('0'.ord..'9'.ord).freeze
39
42
 
40
43
  # Strings with length embedded in typecode.
41
44
  STR_FIXED_START = 128
42
45
  STR_FIXED_COUNT = 64
43
- STR_FIXED = (STR_FIXED_START..STR_FIXED_START + STR_FIXED_COUNT)
46
+ STR_FIXED = (STR_FIXED_START...STR_FIXED_START + STR_FIXED_COUNT).freeze
44
47
 
45
48
  # Lists with length embedded in typecode.
46
- LIST_FIXED_START = STR_FIXED_START+STR_FIXED_COUNT
49
+ LIST_FIXED_START = STR_FIXED_START + STR_FIXED_COUNT
47
50
  LIST_FIXED_COUNT = 64
48
- LIST_FIXED = (LIST_FIXED_START..LIST_FIXED_START + LIST_FIXED_COUNT)
51
+ LIST_FIXED = (LIST_FIXED_START...LIST_FIXED_START + LIST_FIXED_COUNT).freeze
49
52
 
50
53
  require_relative 'rencoder/encoder'
51
54
  require_relative 'rencoder/decoder'
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rencoder
4
+ # Rencode format encoder/decoder class
2
5
  class Coder
3
6
  attr_reader :options
4
7
 
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rencoder
4
+ # Rencode format decoder module
2
5
  module Decoder
3
6
  INTEGER_DECODING_MAP = {
4
7
  CHR_INT1 => [1, 'c'],
5
8
  CHR_INT2 => [2, 's>'],
6
9
  CHR_INT4 => [4, 'l>'],
7
10
  CHR_INT8 => [8, 'q>']
8
- }
11
+ }.freeze
9
12
 
10
13
  def decode(buffer)
11
14
  buffer = StringIO.new(buffer) unless buffer.respond_to?(:read) # IO object
@@ -43,11 +46,11 @@ module Rencoder
43
46
  when CHR_INT1, CHR_INT2, CHR_INT4, CHR_INT8
44
47
  size, template = INTEGER_DECODING_MAP[type]
45
48
 
46
- buffer.read(size).unpack(template).first
49
+ buffer.read(size).unpack1(template)
47
50
  when INT_POS_FIXED
48
51
  type - INT_POS_FIXED_START
49
52
  when INT_NEG_FIXED
50
- -1-(type - INT_NEG_FIXED_START)
53
+ -1 - (type - INT_NEG_FIXED_START)
51
54
  end
52
55
  end
53
56
 
@@ -71,7 +74,7 @@ module Rencoder
71
74
  end
72
75
  end
73
76
 
74
- def decode_boolean(buffer, type)
77
+ def decode_boolean(_buffer, type)
75
78
  type == CHR_TRUE
76
79
  end
77
80
 
@@ -88,7 +91,7 @@ module Rencoder
88
91
  when LIST_FIXED
89
92
  size = type - LIST_FIXED_START
90
93
 
91
- size.times.map do |i|
94
+ size.times.map do |_i|
92
95
  decode(buffer)
93
96
  end
94
97
  end
@@ -111,7 +114,7 @@ module Rencoder
111
114
  end
112
115
  end
113
116
 
114
- def decode_nil(buffer, type)
117
+ def decode_nil(_buffer, _type)
115
118
  nil
116
119
  end
117
120
 
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rencoder
4
+ # Rencode format encoder module
2
5
  module Encoder
3
6
  class EncodingError < StandardError; end
4
7
 
5
8
  def encode(object)
6
9
  case object
7
10
  when String, Symbol then encode_string(object)
8
- when Fixnum then encode_integer(object)
11
+ when Integer then encode_integer(object)
9
12
  when Float then encode_float(object)
10
13
  when TrueClass, FalseClass then encode_boolean(object)
11
14
  when NilClass then encode_nil(object)
@@ -16,26 +19,24 @@ module Rencoder
16
19
  end
17
20
  end
18
21
 
19
- def encode_integer(object)
22
+ def encode_integer(object) # rubocop:disable Metrics/AbcSize
20
23
  case object
21
24
  when (0...INT_POS_FIXED_COUNT) # predefined positive intger
22
25
  [INT_POS_FIXED_START + object].pack('C')
23
26
  when (-INT_NEG_FIXED_COUNT...0) # predefined negative integer
24
- [INT_NEG_FIXED_START-1-object].pack('C')
27
+ [INT_NEG_FIXED_START - 1 - object].pack('C')
25
28
  when (-128...128)
26
29
  [CHR_INT1, object].pack('Cc') # 8-bit signed
27
- when (-32768...32768)
30
+ when (-32_768...32_768)
28
31
  [CHR_INT2, object].pack('Cs>') # 16-bit signed
29
- when (-2147483648...2147483648)
32
+ when (-2_147_483_648...2_147_483_648)
30
33
  [CHR_INT4, object].pack('Cl>') # 32-bit signed
31
- when (-9223372036854775808...9223372036854775808)
34
+ when (-9_223_372_036_854_775_808...9_223_372_036_854_775_808)
32
35
  [CHR_INT8, object].pack('Cq>') # 64-bit signed
33
36
  else # encode as ASCII
34
37
  bytes = object.to_s.bytes
35
38
 
36
- if bytes.size >= MAX_INT_LENGTH
37
- raise EncodingError, "Unable to serialize Fixnum #{object} due to overflow"
38
- end
39
+ raise EncodingError, "Unable to serialize Integer #{object} due to overflow" if bytes.size >= MAX_INT_LENGTH
39
40
 
40
41
  [CHR_INT, *bytes, CHR_TERM].pack('C*')
41
42
  end
@@ -61,7 +62,7 @@ module Rencoder
61
62
  if bytes.size < STR_FIXED_COUNT
62
63
  (STR_FIXED_START + bytes.size).chr + bytes
63
64
  else
64
- "#{bytes.bytesize.to_s}:#{bytes}"
65
+ "#{bytes.bytesize}:#{bytes}"
65
66
  end
66
67
  end
67
68
 
@@ -89,7 +90,7 @@ module Rencoder
89
90
  end
90
91
  end
91
92
 
92
- def encode_nil(object)
93
+ def encode_nil(_object)
93
94
  [CHR_NONE].pack('C')
94
95
  end
95
96
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rencoder
2
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
3
5
  end
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'rencoder/version'
5
6
 
@@ -8,16 +9,18 @@ Gem::Specification.new do |spec|
8
9
  spec.version = Rencoder::VERSION
9
10
  spec.authors = ['Igor Yamolov']
10
11
  spec.email = ['clouster@yandex.ru']
11
- spec.summary = %q{Rencoder is pure Ruby implementation of Rencoder serialization format encoding/decoding.}
12
- spec.description = %q{Rencoder is implementation of Rencoder encoding/decoding.}
12
+ spec.summary = 'Rencoder is pure Ruby implementation of Rencoder serialization format encoding/decoding.'
13
+ spec.description = 'Rencoder is implementation of Rencoder encoding/decoding.'
13
14
  spec.homepage = 'https://github.com/t3hk0d3/rencoder'
14
15
  spec.license = 'MIT'
16
+ spec.required_ruby_version = '>= 2.2' # rubocop:disable Gemspec/RequiredRubyVersion
15
17
 
16
18
  spec.files = `git ls-files -z`.split("\x0")
17
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib']
20
22
 
21
- spec.add_development_dependency 'bundler', '~> 1.7'
22
23
  spec.add_development_dependency 'rspec', '~> 3.1.0'
24
+ spec.add_development_dependency 'rubocop', '~> 0.90'
25
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.43'
23
26
  end
@@ -1,100 +1,118 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Rencoder::Decoder do
4
- include_context 'serialization_values'
6
+ subject(:decoder) { Rencoder::Coder.new }
5
7
 
6
- subject { Rencoder::Coder.new }
8
+ include_context 'with serialization_values'
7
9
 
8
10
  describe '#decode' do
9
11
  it 'raises EOFError on EOF' do
10
- expect {
11
- subject.decode(StringIO.new)
12
- }.to raise_error(EOFError)
12
+ expect do
13
+ decoder.decode(StringIO.new)
14
+ end.to raise_error(EOFError)
13
15
  end
14
16
 
15
17
  describe 'string' do
16
18
  it 'decode string' do
17
- expect(subject.decode(serialized_string)).to eq('Test')
19
+ expect(decoder.decode(serialized_string)).to eq('Test')
20
+ end
21
+
22
+ it 'decode empty string' do
23
+ expect(decoder.decode(serialized_empty_string)).to eq('')
24
+ end
25
+
26
+ it 'decode maximum embedded-length type string' do
27
+ expect(decoder.decode(serialized_63byte_string)).to eq('a' * 63)
18
28
  end
19
29
 
20
30
  it 'decode long string' do
21
- expect(subject.decode(serialized_long_string)).to eq('a' * 100)
31
+ expect(decoder.decode(serialized_long_string)).to eq('a' * 100)
22
32
  end
23
33
  end
24
34
 
25
35
  describe 'integer' do
26
36
  it 'decode positive small integer' do
27
- expect(subject.decode(serialized_positive_integer)).to eq(10)
37
+ expect(decoder.decode(serialized_positive_integer)).to eq(10)
28
38
  end
29
39
 
30
40
  it 'decode negative small integer' do
31
- expect(subject.decode(serialized_negative_integer)).to eq(-10)
41
+ expect(decoder.decode(serialized_negative_integer)).to eq(-10)
32
42
  end
33
43
 
34
44
  it 'decode 8-bit integer' do
35
- expect(subject.decode(serialized_8bit_integer)).to eq(100)
45
+ expect(decoder.decode(serialized_8bit_integer)).to eq(100)
36
46
  end
37
47
 
38
48
  it 'decode 16-bit integer' do
39
- expect(subject.decode(serialized_16bit_integer)).to eq(5000)
49
+ expect(decoder.decode(serialized_16bit_integer)).to eq(5000)
40
50
  end
41
51
 
42
52
  it 'decode 32-bit integer' do
43
- expect(subject.decode(serialized_32bit_integer)).to eq(50000)
53
+ expect(decoder.decode(serialized_32bit_integer)).to eq(50_000)
44
54
  end
45
55
 
46
56
  it 'decode 64-bit integer' do
47
- expect(subject.decode(serialized_64bit_integer)).to eq(5000000000)
57
+ expect(decoder.decode(serialized_64bit_integer)).to eq(5_000_000_000)
48
58
  end
49
59
 
50
60
  it 'decode big ascii integer' do
51
- expect(subject.decode(serialized_big_integer)).to eq(50000000000000000000)
61
+ expect(decoder.decode(serialized_big_integer)).to eq(50_000_000_000_000_000_000)
52
62
  end
53
63
  end
54
64
 
55
65
  describe 'float' do
56
66
  it 'decode 32-bit float' do
57
- expect(subject.decode(serialized_32bit_float)).to eq(100.0)
67
+ expect(decoder.decode(serialized_32bit_float)).to eq(100.0)
58
68
  end
59
69
 
60
70
  it 'decode 64-bit float' do
61
- expect(subject.decode(serialized_float)).to eq(100.0001)
71
+ expect(decoder.decode(serialized_float)).to eq(100.0001)
62
72
  end
63
73
  end
64
74
 
65
75
  describe 'boolean' do
66
76
  it 'decode true boolean' do
67
- expect(subject.decode(serialized_true)).to eq(true)
77
+ expect(decoder.decode(serialized_true)).to eq(true)
68
78
  end
69
79
 
70
80
  it 'decode false boolean' do
71
- expect(subject.decode(serialized_false)).to eq(false)
81
+ expect(decoder.decode(serialized_false)).to eq(false)
72
82
  end
73
83
  end
74
84
 
75
85
  describe 'nil' do
76
86
  it 'decode nil' do
77
- expect(subject.decode(serialized_nil)).to eq(nil)
87
+ expect(decoder.decode(serialized_nil)).to eq(nil)
78
88
  end
79
89
  end
80
90
 
81
91
  describe 'array' do
92
+ it 'decode empty array' do
93
+ expect(decoder.decode(serialized_empty_array)).to eq([])
94
+ end
95
+
82
96
  it 'decode small array' do
83
- expect(subject.decode(serialized_array)).to eq(['Test', 100, 100.0001, nil])
97
+ expect(decoder.decode(serialized_array)).to eq(['Test', 100, 100.0001, nil])
98
+ end
99
+
100
+ it 'decode maximum embedded length type array' do
101
+ expect(decoder.decode(serialized_63_element_array)).to eq(63.times.to_a)
84
102
  end
85
103
 
86
104
  it 'decode big array' do
87
- expect(subject.decode(serialized_big_array)).to eq(100.times.to_a)
105
+ expect(decoder.decode(serialized_big_array)).to eq(100.times.to_a)
88
106
  end
89
107
  end
90
108
 
91
109
  describe 'hash' do
92
110
  it 'decode small hash' do
93
- expect(subject.decode(serialized_hash)).to eq({ 'test' => 123, 'hello' => 'world' })
111
+ expect(decoder.decode(serialized_hash)).to eq({ 'test' => 123, 'hello' => 'world' })
94
112
  end
95
113
 
96
114
  it 'decode big hash' do
97
- expect(subject.decode(serialized_big_hash)).to eq(Hash[100.times.map { |i| [i, i.chr] }])
115
+ expect(decoder.decode(serialized_big_hash)).to eq(Hash[100.times.map { |i| [i, i.chr] }])
98
116
  end
99
117
  end
100
118
  end
@@ -1,135 +1,137 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Rencoder::Encoder do
4
- include_context 'serialization_values'
6
+ subject(:encoder) { Rencoder::Coder.new }
5
7
 
6
- subject { Rencoder::Coder.new }
8
+ include_context 'with serialization_values'
7
9
 
8
10
  describe '#encode' do
9
11
  it 'encode string' do
10
- expect(subject.encode('Test')).to eq(serialized_string)
12
+ expect(encoder.encode('Test')).to eq(serialized_string)
11
13
  end
12
14
 
13
15
  it 'encode symbol' do
14
- expect(subject.encode(:test)).to eq(serialized_symbol)
16
+ expect(encoder.encode(:test)).to eq(serialized_symbol)
15
17
  end
16
18
 
17
19
  it 'encode integer' do
18
- expect(subject.encode(100)).to eq(serialized_integer)
20
+ expect(encoder.encode(100)).to eq(serialized_integer)
19
21
  end
20
22
 
21
23
  it 'encode float' do
22
- expect(subject.encode(100.0001)).to eq(serialized_float)
24
+ expect(encoder.encode(100.0001)).to eq(serialized_float)
23
25
  end
24
26
 
25
27
  it 'encode boolean' do
26
- expect(subject.encode(false)).to eq(serialized_false)
28
+ expect(encoder.encode(false)).to eq(serialized_false)
27
29
  end
28
30
 
29
31
  it 'encode nil' do
30
- expect(subject.encode(nil)).to eq(serialized_nil)
32
+ expect(encoder.encode(nil)).to eq(serialized_nil)
31
33
  end
32
34
 
33
35
  it 'encode array' do
34
- expect(subject.encode(["Test", 100, 100.0001, nil])).to eq(serialized_array)
36
+ expect(encoder.encode(['Test', 100, 100.0001, nil])).to eq(serialized_array)
35
37
  end
36
38
 
37
39
  it 'encode hash' do
38
- expect(subject.encode({ test: 123, hello: 'world' })).to eq(serialized_hash)
40
+ expect(encoder.encode({ test: 123, hello: 'world' })).to eq(serialized_hash)
39
41
  end
40
42
 
41
43
  it 'raise exception for non-serializable object' do
42
- expect { subject.encode(Object.new) }.to raise_error(Rencoder::Encoder::EncodingError)
44
+ expect { encoder.encode(Object.new) }.to raise_error(Rencoder::Encoder::EncodingError)
43
45
  end
44
46
  end
45
47
 
46
48
  describe '#encode_string' do
47
49
  it 'encode small strings' do
48
- expect(subject.encode_string('Test')).to eq(serialized_string)
50
+ expect(encoder.encode_string('Test')).to eq(serialized_string)
49
51
  end
50
52
 
51
53
  it 'encode big strings' do
52
- expect(subject.encode_string('a' * 100)).to eq(serialized_long_string)
54
+ expect(encoder.encode_string('a' * 100)).to eq(serialized_long_string)
53
55
  end
54
56
  end
55
57
 
56
58
  describe '#encode_integer' do
57
59
  it 'encode small positive number' do
58
- expect(subject.encode_integer(10)).to eq(serialized_positive_integer)
60
+ expect(encoder.encode_integer(10)).to eq(serialized_positive_integer)
59
61
  end
60
62
 
61
63
  it 'encode small negative number' do
62
- expect(subject.encode_integer(-10)).to eq(serialized_negative_integer)
64
+ expect(encoder.encode_integer(-10)).to eq(serialized_negative_integer)
63
65
  end
64
66
 
65
67
  it 'encode 8-bit integer' do
66
- expect(subject.encode_integer(100)).to eq(serialized_8bit_integer)
68
+ expect(encoder.encode_integer(100)).to eq(serialized_8bit_integer)
67
69
  end
68
70
 
69
71
  it 'encode 16-bit integer' do
70
- expect(subject.encode_integer(5000)).to eq(serialized_16bit_integer)
72
+ expect(encoder.encode_integer(5000)).to eq(serialized_16bit_integer)
71
73
  end
72
74
 
73
75
  it 'encode 32-bit integer' do
74
- expect(subject.encode_integer(50000)).to eq(serialized_32bit_integer)
76
+ expect(encoder.encode_integer(50_000)).to eq(serialized_32bit_integer)
75
77
  end
76
78
 
77
79
  it 'encode 64-bit integer' do
78
- expect(subject.encode_integer(5000000000)).to eq(serialized_64bit_integer)
80
+ expect(encoder.encode_integer(5_000_000_000)).to eq(serialized_64bit_integer)
79
81
  end
80
82
 
81
83
  it 'encode big integer as ascii' do
82
- expect(subject.encode_integer(50000000000000000000)).to eq(serialized_big_integer)
84
+ expect(encoder.encode_integer(50_000_000_000_000_000_000)).to eq(serialized_big_integer)
83
85
  end
84
86
 
85
87
  it 'raise error for super-big integers' do
86
88
  expect do
87
- subject.encode_integer(128.times.map { '9' }.join.to_i)
89
+ encoder.encode_integer(128.times.map { '9' }.join.to_i)
88
90
  end.to raise_error(Rencoder::Encoder::EncodingError)
89
91
  end
90
92
  end
91
93
 
92
94
  describe '#encode_float' do
93
95
  it 'encode 64-bit float' do
94
- expect(subject.encode_float(100.0001)).to eq(serialized_float)
96
+ expect(encoder.encode_float(100.0001)).to eq(serialized_float)
95
97
  end
96
98
  end
97
99
 
98
100
  describe '#encode_boolean' do
99
101
  it 'encode true boolean' do
100
- expect(subject.encode_boolean(true)).to eq(serialized_true)
102
+ expect(encoder.encode_boolean(true)).to eq(serialized_true)
101
103
  end
102
104
 
103
105
  it 'encode false boolean' do
104
- expect(subject.encode_boolean(false)).to eq(serialized_false)
106
+ expect(encoder.encode_boolean(false)).to eq(serialized_false)
105
107
  end
106
108
  end
107
109
 
108
110
  describe '#encode_nil' do
109
111
  it 'encode nil' do
110
- expect(subject.encode_nil(nil)).to eq(serialized_nil)
112
+ expect(encoder.encode_nil(nil)).to eq(serialized_nil)
111
113
  end
112
114
  end
113
115
 
114
116
  describe '#encode_array' do
115
117
  it 'encode small-sized array' do
116
- expect(subject.encode_array(["Test", 100, 100.0001, nil])).to eq(serialized_array)
118
+ expect(encoder.encode_array(['Test', 100, 100.0001, nil])).to eq(serialized_array)
117
119
  end
118
120
 
119
121
  it 'encode big-sized array' do
120
- expect(subject.encode_array(100.times.to_a)).to eq(serialized_big_array)
122
+ expect(encoder.encode_array(100.times.to_a)).to eq(serialized_big_array)
121
123
  end
122
124
  end
123
125
 
124
126
  describe '#encode_hash' do
125
127
  it 'encode small-sized hash' do
126
- expect(subject.encode_hash({ test: 123, hello: 'world' })).to eq(serialized_hash)
128
+ expect(encoder.encode_hash({ test: 123, hello: 'world' })).to eq(serialized_hash)
127
129
  end
128
130
 
129
131
  it 'encode big-sized hash' do
130
132
  hash = Hash[100.times.map { |i| [i, i.chr] }]
131
133
 
132
- expect(subject.encode_hash(hash)).to eq(serialized_big_hash)
134
+ expect(encoder.encode_hash(hash)).to eq(serialized_big_hash)
133
135
  end
134
136
  end
135
137
  end
@@ -1,12 +1,13 @@
1
- $:.unshift(File.expand_path('../../lib', __FILE__))
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
2
4
 
3
5
  require 'rspec'
4
6
  require 'rencoder'
5
7
 
6
8
  require 'base64'
7
9
 
8
- shared_context 'serialization_values' do
9
-
10
+ shared_context 'with serialization_values' do # rubocop:disable RSpec/MultipleMemoizedHelpers
10
11
  # Values encoded using original Python code
11
12
 
12
13
  # Integers
@@ -41,8 +42,14 @@ shared_context 'serialization_values' do
41
42
  # :test (symbol)
42
43
  let(:serialized_symbol) { Base64.decode64('hHRlc3Q=') }
43
44
 
45
+ # ''
46
+ let(:serialized_empty_string) { Base64.decode64("gA==\n") }
47
+
48
+ # maximum embedded-length string type ('a' * 63)
49
+ let(:serialized_63byte_string) { "\xBF#{'a' * 63}" }
50
+
44
51
  # 'a' * 100
45
- let(:serialized_long_string) { '100:' + 'a' * 100 }
52
+ let(:serialized_long_string) { "100:#{'a' * 100}" }
46
53
 
47
54
  # Booleans
48
55
  # true
@@ -61,12 +68,20 @@ shared_context 'serialization_values' do
61
68
  let(:serialized_nil) { 69.chr }
62
69
 
63
70
  # Array
71
+ # []
72
+ let(:serialized_empty_array) { "\xC0" }
73
+
64
74
  # ["Test", 100, 100.0001, nil]
65
75
  let(:serialized_array) { Base64.decode64('xIRUZXN0PmQsQFkAAaNuLrJF') }
66
76
 
77
+ # maximum embedded-length array type (63.times.to_a)
78
+ let(:serialized_63_element_array) do
79
+ Base64.decode64("/z4APgE+Aj4DPgQ+BT4GPgc+CD4JPgo+Cz4MPg0+Dj4PPhA+ET4SPhM+FD4V\nPhY+Fz4YPhk+Gj4bPhw+HT4ePh8+ID4hPiI+Iz4kPiU+Jj4nPig+KT4qPis+\nLD4tPi4+Lz4wPjE+Mj4zPjQ+NT42Pjc+OD45Pjo+Oz48Pj0+Pg==\n") # rubocop:disable Layout/LineLength
80
+ end
81
+
67
82
  # big array (100.times.to_a)
68
83
  let(:serialized_big_array) do
69
- Base64.decode64('OwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorPiw+LT4uPi8+MD4xPjI+Mz40PjU+Nj43Pjg+OT46Pjs+PD49Pj4+Pz5APkE+Qj5DPkQ+RT5GPkc+SD5JPko+Sz5MPk0+Tj5PPlA+UT5SPlM+VD5VPlY+Vz5YPlk+Wj5bPlw+XT5ePl8+YD5hPmI+Y38=')
84
+ Base64.decode64('OwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorPiw+LT4uPi8+MD4xPjI+Mz40PjU+Nj43Pjg+OT46Pjs+PD49Pj4+Pz5APkE+Qj5DPkQ+RT5GPkc+SD5JPko+Sz5MPk0+Tj5PPlA+UT5SPlM+VD5VPlY+Vz5YPlk+Wj5bPlw+XT5ePl8+YD5hPmI+Y38=') # rubocop:disable Layout/LineLength
70
85
  end
71
86
 
72
87
  # Hash
@@ -75,6 +90,6 @@ shared_context 'serialization_values' do
75
90
 
76
91
  # big hash (Hash[100.times.map { |i| [i, i.chr] }])
77
92
  let(:serialized_big_hash) do
78
- Base64.decode64('PACBAAGBAQKBAgOBAwSBBAWBBQaBBgeBBwiBCAmBCQqBCguBCwyBDA2BDQ6BDg+BDxCBEBGBERKBEhOBExSBFBWBFRaBFheBFxiBGBmBGRqBGhuBGxyBHB2BHR6BHh+BHyCBICGBISKBIiOBIySBJCWBJSaBJieBJyiBKCmBKSqBKiuBKz4sgSw+LYEtPi6BLj4vgS8+MIEwPjGBMT4ygTI+M4EzPjSBND41gTU+NoE2PjeBNz44gTg+OYE5PjqBOj47gTs+PIE8Pj2BPT4+gT4+P4E/PkCBQD5BgUE+QoFCPkOBQz5EgUQ+RYFFPkaBRj5HgUc+SIFIPkmBST5KgUo+S4FLPkyBTD5NgU0+ToFOPk+BTz5QgVA+UYFRPlKBUj5TgVM+VIFUPlWBVT5WgVY+V4FXPliBWD5ZgVk+WoFaPluBWz5cgVw+XYFdPl6BXj5fgV8+YIFgPmGBYT5igWI+Y4Fjfw==')
93
+ Base64.decode64('PACBAAGBAQKBAgOBAwSBBAWBBQaBBgeBBwiBCAmBCQqBCguBCwyBDA2BDQ6BDg+BDxCBEBGBERKBEhOBExSBFBWBFRaBFheBFxiBGBmBGRqBGhuBGxyBHB2BHR6BHh+BHyCBICGBISKBIiOBIySBJCWBJSaBJieBJyiBKCmBKSqBKiuBKz4sgSw+LYEtPi6BLj4vgS8+MIEwPjGBMT4ygTI+M4EzPjSBND41gTU+NoE2PjeBNz44gTg+OYE5PjqBOj47gTs+PIE8Pj2BPT4+gT4+P4E/PkCBQD5BgUE+QoFCPkOBQz5EgUQ+RYFFPkaBRj5HgUc+SIFIPkmBST5KgUo+S4FLPkyBTD5NgU0+ToFOPk+BTz5QgVA+UYFRPlKBUj5TgVM+VIFUPlWBVT5WgVY+V4FXPliBWD5ZgVk+WoFaPluBWz5cgVw+XYFdPl6BXj5fgV8+YIFgPmGBYT5igWI+Y4Fjfw==') # rubocop:disable Layout/LineLength
79
94
  end
80
95
  end
metadata CHANGED
@@ -1,43 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rencoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Yamolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-13 00:00:00.000000000 Z
11
+ date: 2020-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.7'
19
+ version: 3.1.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.7'
26
+ version: 3.1.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec
28
+ name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.1.0
33
+ version: '0.90'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.1.0
40
+ version: '0.90'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop-rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.43'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.43'
41
55
  description: Rencoder is implementation of Rencoder encoding/decoding.
42
56
  email:
43
57
  - clouster@yandex.ru
@@ -45,7 +59,10 @@ executables: []
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
62
+ - ".github/workflows/gem-push.yml"
63
+ - ".github/workflows/on_push.yml"
48
64
  - ".gitignore"
65
+ - ".rubocop.yml"
49
66
  - ".ruby-version"
50
67
  - Gemfile
51
68
  - LICENSE.txt
@@ -71,15 +88,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
88
  requirements:
72
89
  - - ">="
73
90
  - !ruby/object:Gem::Version
74
- version: '0'
91
+ version: '2.2'
75
92
  required_rubygems_version: !ruby/object:Gem::Requirement
76
93
  requirements:
77
94
  - - ">="
78
95
  - !ruby/object:Gem::Version
79
96
  version: '0'
80
97
  requirements: []
81
- rubyforge_project:
82
- rubygems_version: 2.2.2
98
+ rubygems_version: 3.0.3
83
99
  signing_key:
84
100
  specification_version: 4
85
101
  summary: Rencoder is pure Ruby implementation of Rencoder serialization format encoding/decoding.
@@ -87,4 +103,3 @@ test_files:
87
103
  - spec/rencoder/decoder_spec.rb
88
104
  - spec/rencoder/encoder_spec.rb
89
105
  - spec/spec_helper.rb
90
- has_rdoc: