first_and_only 1.0.0 → 2.0.0

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
  SHA1:
3
- metadata.gz: 2b4c91e830188491065f0ce936d55c0cfee7757e
4
- data.tar.gz: 9d85444ffd3680109fb97e7ebfa49289681cbabc
3
+ metadata.gz: 9f854f3edf7c69ae6b88c87c29678b91678ed91c
4
+ data.tar.gz: c2d49e72515a4d1bac8367c76ecfaa473efed78c
5
5
  SHA512:
6
- metadata.gz: 7c00ff20741d3eac47a38b9815a87a3fd2e270dcf194f6155e9e702466909c7d2c877eb53d2e598940790aaa0743eede95650eb01fc57ac81c486bb10ed4a383
7
- data.tar.gz: 0ebc077a6d80d5e47de14de7d5c1e3d17c71e07be4ec4a7972958815c3a57a07a03435733b88f17045d2aeee4b8d3e992aed643922bff4a95444fa4009db83b0
6
+ metadata.gz: a477760c26ecaabfc516a8968ccab37467bcba33ee5197d15eae078f56f235a71acb02868c0932bc0203cef3bf99a44f3d17c71b0e72e349aaf4c50b5de921c2
7
+ data.tar.gz: cd2cd50bbed8f4f40ed478f5d20ade952272a5047cc7f6144c17657374e177a13df713f918bb8687947bab43ea946e03e14b107839e29e582d508fa800056eab
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "2.1.0"
6
+ - "2.2.3"
7
+ script: bundle exec rspec
data/README.md CHANGED
@@ -1,24 +1,52 @@
1
1
  # FirstAndOnly
2
2
 
3
- TODO: Write a gem description
3
+ Get the first element from an enumerable, and assert that there is only one element to take.
4
+
5
+ ```
6
+ [:just_one].first_and_only! # => :just_one
7
+ ```
8
+
9
+ ```
10
+ [].first_and_only! # => 0 (Enumerable::FirstAndOnly::CountNotOne)
11
+ ```
12
+
13
+ ```
14
+ [:one, :and_two].first_and_only! # => 2 (Enumerable::FirstAndOnly::CountNotOne)
15
+ ```
16
+
17
+ ## Why?
18
+
19
+ Sometimes in a spec you have a collection object that you know only has one element. You set it up this way. Later spec refactors may accidentally introduce a second element. To prevent accidental false positives, and to make fixing failures introduced by this easier, you can use `#first_and_only!` to codify the "there is only one" assumption.
20
+
21
+ Another common use case for `#first_and_only` is `id` assertions on HTML documents. A valid HTML document can only have one occurrence of each `id` attribute, but authoring tools and browsers don't typically enforce this. If you hang your JavaScript of the "only one" assumption of `id` attributes, you should enforce this with a specification.
22
+
23
+ This gem follows the same line of thinking as the [fetching gem](https://github.com/covermymeds/fetching-gem)
4
24
 
5
25
  ## Installation
6
26
 
7
27
  Add this line to your application's Gemfile:
8
28
 
9
- gem 'first_and_only'
29
+ ```
30
+ gem 'first_and_only'
31
+ ```
10
32
 
11
33
  And then execute:
12
34
 
13
- $ bundle
35
+ ```
36
+ $ bundle
37
+ ```
14
38
 
15
39
  Or install it yourself as:
16
40
 
17
- $ gem install first_and_only
41
+ ```
42
+ $ gem install first_and_only
43
+ ```
18
44
 
19
- ## Usage
45
+ ## Running specs
20
46
 
21
- TODO: Write usage instructions here
47
+ ```
48
+ bundle exec rspec
49
+ ```
22
50
 
23
51
  ## Contributing
24
52
 
@@ -17,11 +17,11 @@ Get the first element from an enumerable, and assert that there is only one elem
17
17
  ```
18
18
 
19
19
  ```
20
- [].first_and_only! # => 0 (Enumerable::FirstAndOnly::LengthNotOne)
20
+ [].first_and_only! # => 0 (Enumerable::FirstAndOnly::CountNotOne)
21
21
  ```
22
22
 
23
23
  ```
24
- [:one, :and_two].first_and_only! # => 2 (Enumerable::FirstAndOnly::LengthNotOne)
24
+ [:one, :and_two].first_and_only! # => 2 (Enumerable::FirstAndOnly::CountNotOne)
25
25
  ```
26
26
  SUMMARY
27
27
  spec.homepage = "https://github.com/dapplebeforedawn/first-and-only-gem"
@@ -34,4 +34,5 @@ Get the first element from an enumerable, and assert that there is only one elem
34
34
 
35
35
  spec.add_development_dependency "bundler", "~> 1.3"
36
36
  spec.add_development_dependency "rake"
37
+ spec.add_development_dependency "rspec", "~> 2.14.1"
37
38
  end
@@ -2,11 +2,15 @@ require "first_and_only/version"
2
2
 
3
3
  module Enumerable
4
4
  def first_and_only!
5
- fail(FirstAndOnly::LengthNotOne, count) if first(2).count != 1
5
+ fail(FirstAndOnly::CountNotOne.new count) if first(2).count != 1
6
6
  first
7
7
  end
8
8
 
9
9
  module FirstAndOnly
10
- LengthNotOne = Class.new(StandardError)
10
+ class CountNotOne < StandardError
11
+ def initialize(count)
12
+ super("Expected the count to be 1, but it was #{count}.")
13
+ end
14
+ end
11
15
  end
12
16
  end
@@ -1,3 +1,3 @@
1
1
  module FirstAndOnly
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+
3
+ describe "Enumerable#first_and_only!" do
4
+
5
+ shared_examples_for "it_has_one_element" do
6
+ specify { expect(subject.first_and_only!).to eq(:element) }
7
+ end
8
+
9
+ shared_examples_for "it_is_empty" do
10
+ specify do
11
+ expect { subject.first_and_only! }.to raise_error(
12
+ Enumerable::FirstAndOnly::CountNotOne,
13
+ "Expected the count to be 1, but it was 0."
14
+ )
15
+ end
16
+ end
17
+
18
+ shared_examples_for "it_has_more_than_one_element" do
19
+ specify do
20
+ fail "bad example" if subject.count < 2
21
+
22
+ expect { subject.first_and_only! }.to raise_error(
23
+ Enumerable::FirstAndOnly::CountNotOne,
24
+ "Expected the count to be 1, but it was #{subject.count}."
25
+ )
26
+ end
27
+ end
28
+
29
+ describe "an array" do
30
+
31
+ context "with one element" do
32
+ subject { [:element] }
33
+ it_behaves_like "it_has_one_element"
34
+ end
35
+
36
+ context "that is empty" do
37
+ subject { [] }
38
+ it_behaves_like "it_is_empty"
39
+ end
40
+
41
+ context "with two elements" do
42
+ subject { [:element, :element] }
43
+ it_behaves_like "it_has_more_than_one_element"
44
+ end
45
+ end
46
+
47
+ describe "any enumerable" do
48
+ let(:my_enumerable) do
49
+ Class.new do
50
+ include Enumerable
51
+
52
+ def initialize *args
53
+ @args = args
54
+ end
55
+
56
+ def each
57
+ @args.each { |arg| yield(arg) }
58
+ end
59
+ end
60
+ end
61
+
62
+ context "with one element" do
63
+ subject { my_enumerable.new(:element) }
64
+ it_behaves_like "it_has_one_element"
65
+ end
66
+
67
+ context "empty" do
68
+ subject { my_enumerable.new() }
69
+ it_behaves_like "it_is_empty"
70
+ end
71
+
72
+ context "with more than on element" do
73
+ subject { my_enumerable.new(:element, :element) }
74
+ it_behaves_like "it_has_more_than_one_element"
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,13 @@
1
+ require "first_and_only"
2
+ require "rspec/autorun"
3
+ require "pathname"
4
+
5
+ Pathname(__FILE__).dirname.join("support").each_child { |f| require f }
6
+
7
+ RSpec.configure do |config|
8
+ # Run specs in random order to surface order dependencies. If you find an
9
+ # order dependency and want to debug it, you can fix the order by providing
10
+ # the seed, which is printed after each run.
11
+ # --seed 1234
12
+ config.order = "random"
13
+ end
@@ -0,0 +1,35 @@
1
+ # Adapted from https://github.com/bronson/vim-runtest/blob/master/rspec_formatter.rb.
2
+ require "rspec/core/formatters/base_text_formatter"
3
+
4
+ class VimFormatter < RSpec::Core::Formatters::BaseTextFormatter
5
+
6
+ def example_failed example
7
+ exception = example.execution_result[:exception]
8
+ path = Regexp.last_match[1] if exception.backtrace.find do |frame|
9
+ frame =~ %r{\b(spec/.*_spec\.rb:\d+)(?::|\z)}
10
+ end
11
+ message = format_message exception.message
12
+ path = format_caller(path || " ")
13
+ output.puts "#{path}: #{example.example_group.description.strip} " \
14
+ "#{example.description.strip}: #{message.strip}" if path
15
+ end
16
+
17
+ def example_pending *_args; end
18
+
19
+ def dump_failures *_args; end
20
+
21
+ def dump_pending *_args; end
22
+
23
+ def message _msg; end
24
+
25
+ def dump_summary *_args; end
26
+
27
+ def seed *_args; end
28
+
29
+ private
30
+
31
+ def format_message msg
32
+ msg.gsub("\n", " ")[0, 80]
33
+ end
34
+
35
+ end
metadata CHANGED
@@ -1,43 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: first_and_only
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Lorenz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-05 00:00:00.000000000 Z
11
+ date: 2015-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
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
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
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
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.14.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.14.1
41
55
  description: |
42
56
  Get the first element from an enumerable, and assert that there is only one element to take.
43
57
  email:
@@ -46,7 +60,8 @@ executables: []
46
60
  extensions: []
47
61
  extra_rdoc_files: []
48
62
  files:
49
- - .gitignore
63
+ - ".gitignore"
64
+ - ".travis.yml"
50
65
  - Gemfile
51
66
  - LICENSE.txt
52
67
  - README.md
@@ -54,6 +69,9 @@ files:
54
69
  - first_and_only.gemspec
55
70
  - lib/first_and_only.rb
56
71
  - lib/first_and_only/version.rb
72
+ - spec/first_and_only_spec.rb
73
+ - spec/spec_helper.rb
74
+ - spec/support/vim_formatter.rb
57
75
  homepage: https://github.com/dapplebeforedawn/first-and-only-gem
58
76
  licenses:
59
77
  - MIT
@@ -64,20 +82,23 @@ require_paths:
64
82
  - lib
65
83
  required_ruby_version: !ruby/object:Gem::Requirement
66
84
  requirements:
67
- - - '>='
85
+ - - ">="
68
86
  - !ruby/object:Gem::Version
69
87
  version: '0'
70
88
  required_rubygems_version: !ruby/object:Gem::Requirement
71
89
  requirements:
72
- - - '>='
90
+ - - ">="
73
91
  - !ruby/object:Gem::Version
74
92
  version: '0'
75
93
  requirements: []
76
94
  rubyforge_project:
77
- rubygems_version: 2.2.2
95
+ rubygems_version: 2.4.8
78
96
  signing_key:
79
97
  specification_version: 4
80
- summary: '``` [:just_one].first_and_only! # => :just_one ``` ``` [].first_and_only! #
81
- => 0 (Enumerable::FirstAndOnly::LengthNotOne) ``` ``` [:one, :and_two].first_and_only! #
82
- => 2 (Enumerable::FirstAndOnly::LengthNotOne) ```'
83
- test_files: []
98
+ summary: "``` [:just_one].first_and_only! # => :just_one ``` ``` [].first_and_only!
99
+ \ # => 0 (Enumerable::FirstAndOnly::CountNotOne) ``` ``` [:one, :and_two].first_and_only!
100
+ \ # => 2 (Enumerable::FirstAndOnly::CountNotOne) ```"
101
+ test_files:
102
+ - spec/first_and_only_spec.rb
103
+ - spec/spec_helper.rb
104
+ - spec/support/vim_formatter.rb