fetching 0.4.1 → 0.5.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.
data/README.md CHANGED
@@ -12,11 +12,13 @@ Fetching(HTTParty.get(url, query: query)).forms[0].request_form_id
12
12
  # fails loudly if the first `form` doesn't have a `request_form_id` key
13
13
  ```
14
14
 
15
+ Or, if you prefer to learn from slide decks -- [As presented at RailsConf 2014](http://dapplebeforedawn.github.io/fetching-gem-talk)
16
+
15
17
  ## Installation
16
18
 
17
19
  Add this line to your application's Gemfile:
18
20
 
19
- gem 'fetching', git: 'https://github.com/covermymeds/fetching-gem.git'
21
+ gem 'fetching'
20
22
 
21
23
  And then execute:
22
24
 
@@ -0,0 +1,56 @@
1
+ class Fetching
2
+ class FetchingArray < Fetching
3
+
4
+ include Enumerable
5
+
6
+ def [](index)
7
+ Fetching.from @table.fetch(index)
8
+ end
9
+
10
+ def each
11
+ @table.each_index do |i|
12
+ yield self[i]
13
+ end
14
+ end
15
+
16
+ def first
17
+ self[0]
18
+ end
19
+
20
+ module ArrayMethods
21
+
22
+ def empty?
23
+ @table.empty?
24
+ end
25
+
26
+ def length
27
+ @table.length
28
+ end
29
+ alias size length
30
+
31
+ def reverse
32
+ Fetching.from @table.reverse
33
+ end
34
+
35
+ def shuffle *args
36
+ Fetching.from @table.shuffle(*args)
37
+ end
38
+
39
+ def sort &block
40
+ Fetching.from @table.sort(&block)
41
+ end
42
+
43
+ def sort_by &block
44
+ Fetching.from @table.sort_by(&block)
45
+ end
46
+
47
+ def values_at *args
48
+ Fetching.from(args.map { |i| self[i] })
49
+ end
50
+
51
+ end
52
+
53
+ include ArrayMethods
54
+
55
+ end
56
+ end
@@ -0,0 +1,28 @@
1
+ class Fetching
2
+ class FetchingHash < Fetching
3
+
4
+ def initialize *args
5
+ super
6
+ make_methods
7
+ end
8
+
9
+ def to_hash
10
+ @table.dup
11
+ end
12
+
13
+ private
14
+
15
+ def make_methods
16
+ @table.each do |k, v|
17
+ define_singleton_method(k) do
18
+ Fetching.from(v)
19
+ end
20
+ end
21
+ end
22
+
23
+ def method_missing key, *args, &block
24
+ fail NoMethodError, "#{key} not found\nyou have:\n#{@table.inspect}"
25
+ end
26
+
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  class Fetching
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/fetching.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require "json"
2
+ require "fetching/fetching_array"
3
+ require "fetching/fetching_hash"
2
4
 
3
5
  module Kernel
4
6
 
@@ -11,8 +13,9 @@ end
11
13
  class Fetching
12
14
 
13
15
  WHITELIST = %w[ define_singleton_method class object_id
14
- == inspect to_s instance_variables instance_eval
16
+ == instance_variables instance_eval
15
17
  instance_variable_get ]
18
+
16
19
  all_methods = instance_methods.map(&:to_s).grep(/\A[^_]/)
17
20
  (all_methods - WHITELIST).each(&method(:undef_method))
18
21
 
@@ -43,52 +46,12 @@ class Fetching
43
46
  self.class.hash ^ @table.hash
44
47
  end
45
48
 
46
- private
47
-
48
- def no_method key
49
- end
50
-
51
- end
52
-
53
- class FetchingArray < Fetching
54
-
55
- include Enumerable
56
-
57
- def [](index)
58
- Fetching.from @table.fetch(index)
59
- end
60
-
61
- def each
62
- @table.each_index do |i|
63
- yield self[i]
64
- end
65
- end
66
-
67
- end
68
-
69
- class FetchingHash < Fetching
70
-
71
- def initialize *args
72
- super
73
- make_methods
74
- end
75
-
76
- def to_hash
77
- @table.dup
78
- end
79
-
80
- private
81
-
82
- def make_methods
83
- @table.each do |k, v|
84
- define_singleton_method(k) do
85
- Fetching.from(v)
86
- end
87
- end
49
+ def to_s
50
+ @table.to_s
88
51
  end
89
52
 
90
- def method_missing key, *args, &block
91
- fail NoMethodError, "#{key} not found\nyou have:\n#{@table.inspect}"
53
+ def inspect
54
+ "#<#{self.class.name}: @table=#{to_s}>"
92
55
  end
93
56
 
94
57
  end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+
3
+ describe Fetching::FetchingArray do
4
+
5
+ specify "#map" do
6
+ ary = [1, 2]
7
+ fetching_ary = Fetching(ary)
8
+ expect(fetching_ary.map(&:to_s)).to eq(%w[1 2])
9
+ end
10
+
11
+ specify "Fetching should go deep" do
12
+ Fetching([{one: 1}]).each do |element|
13
+ expect(element.one).to eq(1)
14
+ end
15
+ end
16
+
17
+ specify "#first" do
18
+ ary = []
19
+ sassy_ary = Fetching(ary)
20
+ expect{ sassy_ary.first }.to raise_error(IndexError)
21
+ end
22
+
23
+ describe "array methods" do
24
+ let(:array) { [1, 2, 3] }
25
+ let(:fetching) { Fetching(array) }
26
+
27
+ describe "#empty?" do
28
+ it("should be false"){ expect(fetching.empty?).to be_false }
29
+
30
+ context "when empty" do
31
+ let(:array) { [] }
32
+ it("should be true"){ expect(fetching.empty?).to be_true }
33
+ end
34
+ end
35
+
36
+ specify "#length" do
37
+ expect(fetching.length).to eq(array.length)
38
+ expect(fetching.size).to eq(array.size)
39
+ end
40
+
41
+ specify "#reverse" do
42
+ reversed = Fetching(array.reverse)
43
+ expect(fetching.reverse).to eq(reversed)
44
+ end
45
+
46
+ specify "#shuffle" do
47
+ seed = 1
48
+ shuffled = Fetching(array.shuffle(random: Random.new(seed)))
49
+ expect(fetching.shuffle(random: Random.new(seed))).to eq(shuffled)
50
+ end
51
+
52
+ specify "#sort" do
53
+ sorter = ->(x, y){ y <=> x }
54
+ sorted = Fetching(array.sort(&sorter))
55
+ expect(fetching.sort(&sorter)).to eq(sorted)
56
+ end
57
+
58
+ specify "#sort_by" do
59
+ sorter = ->(i){ 1/i.to_f }
60
+ sorted = Fetching(array.sort_by(&sorter))
61
+ expect(fetching.sort_by(&sorter)).to eq(sorted)
62
+ end
63
+
64
+ describe "#values_at" do
65
+ specify "happy path" do
66
+ at = [0, 2]
67
+ values = Fetching(array.values_at(*at))
68
+ expect(fetching.values_at(*at)).to eq(values)
69
+ end
70
+ specify "out of bounds" do
71
+ at = 5
72
+ expected_message = "index #{at} outside of array bounds: -3...3"
73
+ expect{ fetching.values_at(at) }.to raise_error(IndexError, expected_message)
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe Fetching::FetchingHash do
4
+
5
+ specify "#to_hash" do
6
+ hash = {one: 1, two: 2}
7
+ fetching_hash = Fetching(hash)
8
+ expect(fetching_hash.to_hash).to eq(hash)
9
+ end
10
+
11
+ specify "#to_hash doesn't allow you to break fetching" do
12
+ fetching_hash = Fetching(one: 1, two: 2)
13
+ hash = fetching_hash.to_hash
14
+ hash[:one] = ":)"
15
+ expect(fetching_hash.to_hash[:one]).to eq(1)
16
+ end
17
+
18
+ specify "#to_hash does a deep copy" do
19
+ hash = {one: 1, two: {three: 3}}
20
+ fetching_hash = Fetching(hash)
21
+ expect(fetching_hash.to_hash).to eq(hash)
22
+ end
23
+
24
+ end
@@ -37,42 +37,14 @@ describe Fetching do
37
37
  end
38
38
  end
39
39
 
40
- end
41
-
42
- describe FetchingHash do
43
-
44
- specify "#to_hash" do
45
- hash = {one: 1, two: 2}
46
- sassy_hash = Fetching(hash)
47
- expect(sassy_hash.to_hash).to eq(hash)
48
- end
49
-
50
- specify "#to_hash doesn't allow you to break fetching" do
51
- sassy_hash = Fetching(one: 1, two: 2)
52
- hash = sassy_hash.to_hash
53
- hash[:one] = ":)"
54
- expect(sassy_hash.to_hash[:one]).to eq(1)
55
- end
56
-
57
- specify "#to_hash does a deep copy" do
58
- hash = {one: 1, two: {three: 3}}
59
- sassy_hash = Fetching(hash)
60
- expect(sassy_hash.to_hash).to eq(hash)
40
+ it "has a nice #to_s" do
41
+ nice_to_s = "{:one=>1, :two=>{\"two\"=>2}, :ary=>[1, 2], :object_ary=>[{}, {:three=>3}]}"
42
+ expect(subject.to_s).to eq(nice_to_s)
61
43
  end
62
44
 
63
- end
64
-
65
- describe FetchingArray do
66
-
67
- specify "#map" do
68
- ary = [1, 2]
69
- sassy_ary = Fetching(ary)
70
- expect(sassy_ary.map(&:to_s)).to eq(%w[1 2])
45
+ it "has a nice #inspect" do
46
+ nice_inspect = "#<Fetching::FetchingHash: @table={:one=>1, :two=>{\"two\"=>2}, :ary=>[1, 2], :object_ary=>[{}, {:three=>3}]}>"
47
+ expect(subject.inspect).to eq(nice_inspect)
71
48
  end
72
49
 
73
- specify "Sassiness should go deep" do
74
- Fetching([{one: 1}]).each do |element|
75
- expect(element.one).to eq(1)
76
- end
77
- end
78
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fetching
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-04-24 00:00:00.000000000 Z
13
+ date: 2014-05-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -91,7 +91,11 @@ files:
91
91
  - Rakefile
92
92
  - fetching.gemspec
93
93
  - lib/fetching.rb
94
+ - lib/fetching/fetching_array.rb
95
+ - lib/fetching/fetching_hash.rb
94
96
  - lib/fetching/version.rb
97
+ - spec/fetching_array_spec.rb
98
+ - spec/fetching_hash_spec.rb
95
99
  - spec/fetching_spec.rb
96
100
  - spec/spec_helper.rb
97
101
  - spec/support/vim_formatter.rb
@@ -123,6 +127,8 @@ summary: ! 'This gem is a work in progress. The implementation code is not what
123
127
  important. What is important: Don''t de-serialize API responses in to hashes and
124
128
  arrays. Use a "strict" object that inforces key presence, and array bounds.}'
125
129
  test_files:
130
+ - spec/fetching_array_spec.rb
131
+ - spec/fetching_hash_spec.rb
126
132
  - spec/fetching_spec.rb
127
133
  - spec/spec_helper.rb
128
134
  - spec/support/vim_formatter.rb