curio 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc28163d1bb46f19b67859128f7aa5919dbb3db0
4
+ data.tar.gz: 15db1a1eb06af28ab4b140580dadcf3dcf217718
5
+ SHA512:
6
+ metadata.gz: 673e78456916956fdb249bebab246af4cea5256d8182ec61bc1427b8dfc887ad13336caf728e7bebcc446518cc899e3267be835767f87db9ff2b7fdcfe079d56
7
+ data.tar.gz: 226735b61807e97bfeb135e379b2b42c1012870f42fa37a23f57b42c5d002dabc38eb59293ebf1199da3a0e4b276f063a74c9576a04792a0ec392be3ac15536b
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rubocop.yml ADDED
@@ -0,0 +1,74 @@
1
+ AllCops:
2
+ Exclude:
3
+ - bin/**/*
4
+ - vendor/**/*
5
+
6
+ Encoding:
7
+ Enabled: true
8
+
9
+ Documentation:
10
+ Enabled: false
11
+
12
+ LineLength:
13
+ Max: 72
14
+
15
+ # Class
16
+ ClassLength:
17
+ Max: 80
18
+
19
+ EmptyLinesAroundAccessModifier:
20
+ Enabled: false
21
+
22
+ AccessModifierIndentation:
23
+ EnforcedStyle: indent
24
+
25
+ # Error
26
+ RaiseArgs:
27
+ EnforcedStyle: exploded
28
+
29
+ SignalException:
30
+ EnforcedStyle: semantic
31
+
32
+ # Method
33
+ MethodLength:
34
+ Max: 10
35
+
36
+ SingleLineMethods:
37
+ AllowIfMethodIsEmpty: false
38
+
39
+ CollectionMethods:
40
+ PreferredMethods:
41
+ collect: 'map'
42
+ collect!: 'map!'
43
+ reduce: 'inject'
44
+ detect: 'find'
45
+ find_all: 'select'
46
+
47
+ # Parameter
48
+ ParameterLists:
49
+ Max: 3
50
+ CountKeywordArgs: true
51
+
52
+ BracesAroundHashParameters:
53
+ Enabled: false
54
+ EnforcedStyle: braces
55
+
56
+ # Block
57
+ BlockNesting:
58
+ Max: 3
59
+
60
+ # Brackets
61
+ SpaceInsideBrackets:
62
+ Enabled: true
63
+
64
+ # Hash
65
+ IndentHash:
66
+ EnforcedStyle: consistent
67
+
68
+ SpaceInsideHashLiteralBraces:
69
+ EnforcedStyle: space
70
+ EnforcedStyleForEmptyBraces: space
71
+
72
+ # String
73
+ StringLiterals:
74
+ EnforcedStyle: single_quotes
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in curio.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Terje Larsen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Curio
2
+
3
+ A module to ease creation of collections and enumerable maps
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'curio'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install curio
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/curio/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/setup'
4
+ require 'bundler/gem_tasks'
5
+
6
+ require 'rake/testtask'
7
+ require 'rubocop/rake_task'
8
+
9
+ Rubocop::RakeTask.new
10
+
11
+ task default: :test
12
+ task test: 'test:all'
13
+ task ci: %w(rubocop test:all)
14
+
15
+ namespace :test do
16
+ desc 'Run all tests'
17
+ Rake::TestTask.new :all do |t|
18
+ t.test_files = Rake::FileList['test/*_test.rb']
19
+ end
20
+
21
+ desc 'Run unit tests'
22
+ Rake::TestTask.new :unit do |t|
23
+ t.test_files = Rake::FileList['test/unit_test.rb']
24
+ end
25
+
26
+ desc 'Run integration tests'
27
+ Rake::TestTask.new :integration do |t|
28
+ t.test_files = Rake::FileList['test/integration_test.rb']
29
+ end
30
+ end
data/curio.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../lib/curio/version', __FILE__)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'curio'
7
+ spec.version = Curio::VERSION
8
+ spec.authors = ['Terje Larsen']
9
+ spec.email = ['terlar@gmail.com']
10
+ spec.description = 'Mixin for enumerable maps'
11
+ spec.summary = spec.description
12
+ spec.homepage = 'https://github.com/terlar/curio'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.test_files = spec.files.grep(/^test\//)
17
+ spec.require_paths = ['lib']
18
+
19
+ spec.add_development_dependency 'bundler', '~> 1.6'
20
+ spec.add_development_dependency 'rake'
21
+ spec.add_development_dependency 'rubocop'
22
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ class Curio < Module
4
+ VERSION = '0.1.0'
5
+ end
data/lib/curio.rb ADDED
@@ -0,0 +1,186 @@
1
+ # encoding: utf-8
2
+
3
+ require 'curio/version'
4
+
5
+ # A mixin to define enumerable maps
6
+ class Curio < Module
7
+ # Error raised when fetch cannot find an item with key
8
+ class NotFoundError < KeyError
9
+ def initialize(key)
10
+ @key = key
11
+ super "Item not found in collection with key: #{key}"
12
+ end
13
+ end
14
+
15
+ # Initialize a collection object with given key and type
16
+ #
17
+ # :key will be used to determine which method to call on items to get
18
+ # their unique identifier when adding them to the collection.
19
+ #
20
+ # :type will be used to determine how to coerce the input when calling
21
+ # methods on the collection.
22
+ #
23
+ # @param [Symbol] key
24
+ # @param [Class] type
25
+ #
26
+ # @return [undefined]
27
+ #
28
+ # @api private
29
+ def initialize(key, type = String)
30
+ @key, @type = key, type
31
+
32
+ define_key_method
33
+ define_coerce_key_method
34
+
35
+ freeze
36
+ end
37
+
38
+ private
39
+ # Hook called when module is included
40
+ #
41
+ # @param [Class|Module] descendant
42
+ #
43
+ # @return [undefined]
44
+ #
45
+ # @api private
46
+ def included(descendant)
47
+ super
48
+
49
+ descendant.module_eval do
50
+ include Enumerable
51
+ include Methods
52
+ end
53
+ end
54
+
55
+ # Define #key_method based on @key
56
+ #
57
+ # @return [undefined]
58
+ #
59
+ # @api private
60
+ def define_key_method
61
+ key = @key
62
+ define_method :key_method do
63
+ key
64
+ end
65
+ end
66
+
67
+ # Define #coerce_key based on @type
68
+ #
69
+ # @return [undefined]
70
+ #
71
+ # @api private
72
+ def define_coerce_key_method
73
+ type = @type
74
+ define_method :coerce_key do |value|
75
+ case type.to_s
76
+ when 'String' then "#{value}"
77
+ when 'Symbol' then :"#{value}"
78
+ when 'Integer' then "#{value}".to_i
79
+ else value
80
+ end
81
+ end
82
+ end
83
+
84
+ # The collection methods
85
+ module Methods
86
+ extend Forwardable
87
+
88
+ # Iterate over each item in the collection
89
+ #
90
+ # @yield [object]
91
+ #
92
+ # @return [Enumerator]
93
+ #
94
+ # @api public
95
+ def_delegators :values, :each
96
+
97
+ # Last item in the collection
98
+ #
99
+ # @return [object]
100
+ #
101
+ # @api public
102
+ def_delegators :values, :last
103
+
104
+ # Setup the map and call parent initializer
105
+ #
106
+ # @return [undefined]
107
+ #
108
+ # @api private
109
+ def initialize(*)
110
+ @map = { }
111
+ super
112
+ end
113
+
114
+ # Get all the items in collection
115
+ #
116
+ # @return [Array]
117
+ #
118
+ # @api public
119
+ def values
120
+ @map.values
121
+ end
122
+ alias_method :all, :values
123
+
124
+ # Add an item to the collection
125
+ #
126
+ # @param [object] item
127
+ #
128
+ # @return [self]
129
+ #
130
+ # @api public
131
+ def <<(item)
132
+ key = coerce_key item.send(key_method)
133
+ @map[key] = item
134
+ self
135
+ end
136
+
137
+ # Fetch an item from the collection
138
+ #
139
+ # @yield [undefined]
140
+ #
141
+ # @param [undefined] key
142
+ # @param [undefined] default
143
+ #
144
+ # @return [object]
145
+ #
146
+ # @api public
147
+ def fetch(key, *args, &block)
148
+ args.unshift coerce_key(key)
149
+ @map.fetch(*args, &block)
150
+ rescue KeyError
151
+ raise NotFoundError, key
152
+ end
153
+
154
+ # Get an item from the collection
155
+ #
156
+ # @param [undefined] key
157
+ #
158
+ # @return [object]
159
+ #
160
+ # @api public
161
+ def [](key)
162
+ fetch key, nil
163
+ end
164
+
165
+ # Check if collection has an item with specified key
166
+ #
167
+ # @param [undefined] key
168
+ #
169
+ # @return [Boolean]
170
+ #
171
+ # @api public
172
+ def key?(key)
173
+ @map.key? coerce_key(key)
174
+ end
175
+ alias_method :has?, :key?
176
+
177
+ # Returns a hash representation of the collection
178
+ #
179
+ # @return [Hash]
180
+ #
181
+ # @api public
182
+ def to_h
183
+ @map
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'test_helper'
4
+
5
+ class IntegrationTest < MiniTest::Unit::TestCase
6
+ class Collection
7
+ include Curio.new(:id)
8
+ end
9
+
10
+ Item = Struct.new(:id)
11
+
12
+ attr_reader :collection
13
+
14
+ def setup
15
+ @collection = Collection.new
16
+ end
17
+
18
+ def test_enumerable_behavior
19
+ assert_kind_of Enumerable, collection
20
+ assert_instance_of Enumerator, collection.each
21
+ end
22
+
23
+ def test_retrieving_last_item
24
+ item1 = Item.new 1
25
+ item2 = Item.new 2
26
+ collection << item1 << item2
27
+
28
+ assert_equal item2, collection.last
29
+ end
30
+
31
+ def test_retriving_all_items
32
+ item1 = Item.new 1
33
+ item2 = Item.new 2
34
+ collection << item1 << item2
35
+
36
+ assert_equal [item1, item2], collection.all
37
+ assert_equal [item1, item2], collection.values
38
+ end
39
+
40
+ def test_retrieving_item
41
+ item = Item.new 'a'
42
+ collection << item
43
+
44
+ found = collection['a']
45
+ assert_equal item, found
46
+
47
+ found = collection.fetch 'a'
48
+ assert_equal item, found
49
+ end
50
+
51
+ def test_retrieving_unknown_item
52
+ found = collection['a']
53
+ assert_equal nil, found
54
+
55
+ assert_raises Curio::NotFoundError do
56
+ collection.fetch 'a'
57
+ end
58
+
59
+ found = collection.fetch 'a', 'bang'
60
+ assert_equal 'bang', found
61
+
62
+ found = collection.fetch('a') { 'bang' }
63
+ assert_equal 'bang', found
64
+ end
65
+
66
+ def test_adding_an_item
67
+ item = Item.new 1
68
+
69
+ assert_equal 0, collection.count
70
+ collection << item
71
+ assert_includes collection, item
72
+ assert_equal 1, collection.count
73
+ end
74
+
75
+ def test_item_is_known
76
+ item = Item.new 'a'
77
+ collection << item
78
+
79
+ assert collection.key? 'a'
80
+ assert collection.has? 'a'
81
+ refute collection.key? 'b'
82
+ refute collection.has? 'b'
83
+ end
84
+
85
+ def test_hash_representation
86
+ item1 = Item.new 'a'
87
+ item2 = Item.new 'b'
88
+ collection << item1 << item2
89
+
90
+ assert_equal({
91
+ 'a' => item1,
92
+ 'b' => item2
93
+ }, collection.to_h)
94
+ end
95
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/setup'
4
+ require 'curio'
5
+ require 'minitest/autorun'
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: curio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Terje Larsen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Mixin for enumerable maps
56
+ email:
57
+ - terlar@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rubocop.yml"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - curio.gemspec
69
+ - lib/curio.rb
70
+ - lib/curio/version.rb
71
+ - test/integration_test.rb
72
+ - test/test_helper.rb
73
+ homepage: https://github.com/terlar/curio
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.2.2
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Mixin for enumerable maps
97
+ test_files:
98
+ - test/integration_test.rb
99
+ - test/test_helper.rb