operation 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4f94e9016bc8af451f55389d78d58f6123311d99
4
+ data.tar.gz: 18ff89827a6e314e669982c0b20e1420bbf8ef01
5
+ SHA512:
6
+ metadata.gz: 4f4363d6801908c589fb62eefa8864620981026e175e52155a7abdc3b1c54e4932d36b6bf6050ea48c56368df12065c0be41926d63271b623512ae21978bc43c
7
+ data.tar.gz: dc133b43f1452a22d36d8e645f87837a69b33224bf5901a66370fdb5f72a559b03a60d7f2a5ecd42c113b88329819bee542bfe64f1d90030669409d3d3ba8b2f
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ ## Operation
2
+
3
+ Imagine you have a class like this:
4
+
5
+ ```ruby
6
+ class User
7
+ def delete(id)
8
+ @users.delete id
9
+ end
10
+ end
11
+ ```
12
+
13
+ What does it return? True? The User? an ID? What if an error occured? How does anyone calling `User.delete 42` know what happened?
14
+
15
+ This is where `Operation` comes in. You would just **always** return an Operation. That Object holds information about what happened, like so:
16
+
17
+ ```ruby
18
+ class User
19
+ def delete(id)
20
+ return Operation.new(code: :id_missing) unless id
21
+ return Operation.new(code: :invalid_id, id: id) unless id.match /[a-f]{8}/
22
+
23
+ user = @users[id]
24
+ if @users.delete id
25
+ Operation.new success:true, code: :user_deleted, user: user
26
+ else
27
+ Operation.new code: :deletion_failed
28
+ end
29
+ rescue ConnectionError
30
+ Operation.new code: :deletion_failed_badly
31
+ end
32
+ end
33
+ ```
34
+
35
+ This will give you this joyful, consistent, conventional, implementation-unaware programming feeling:
36
+
37
+ ```ruby
38
+ operation = User.delete 42
39
+ if operation.success?
40
+ puts "It worked! You deleted the user #{operation.meta.user.first_name}"
41
+ else
42
+ puts "Oh, could not delete User with ID #{operation.object} because #{operation.code}"
43
+ end
44
+ ```
45
+
46
+ For your convenience you can use `Operations#failure` and `Operations.success`:
47
+
48
+ ```ruby
49
+ class User
50
+ def delete(id)
51
+ return Operations.failure(:id_missing) unless id
52
+ return Operations.failure(:invalid_id, id: id) unless id.match /[a-f]{8}/
53
+
54
+ user = @users[id]
55
+ if @users.delete id
56
+ Operations.success :user_deleted, object: user
57
+ else
58
+ Operations.failure :deletion_failed
59
+ end
60
+ rescue ConnectionError
61
+ Operation.failure :deletion_failed_badly
62
+ end
63
+ end
64
+ ```
65
+
66
+ `#object` is just a shortcut to `#meta.object`:
67
+
68
+ ```ruby
69
+ operation = User.delete 42
70
+ operation.success? # => true
71
+ operation.object # => <#User id=42>
72
+ operation.meta # => <#Hashie::Mash object: <#User id=42>>
73
+ operation.metadata # => { object: <#User id=42> }
74
+ operation.failure? # => false
75
+ ```
76
+
77
+ ### Requirements
78
+
79
+ * Ruby >= 1.9
80
+
81
+ ### Copyright
82
+
83
+ MIT 2014 halo. See [MIT-LICENSE](http://github.com/halo/operation/blob/master/MIT-LICENSE).
data/lib/operation.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'hashie/mash'
2
+ require 'operations' # <- Not that we need them here, but the developer using this gem might want them.
3
+
4
+ class Operation
5
+
6
+ attr_reader :metadata, :code
7
+
8
+ def initialize(options = {})
9
+ @success = [true, 'true', 1, '1'].include? options[:success]
10
+ @code = options[:code].to_s.to_sym unless options[:code].to_s == ''
11
+ @metadata = options[:metadata]
12
+ end
13
+
14
+ def success?
15
+ !!@success
16
+ end
17
+
18
+ def failure?
19
+ !success?
20
+ end
21
+
22
+ # Convenience Wrapper
23
+ def object
24
+ meta.object
25
+ end
26
+
27
+ def meta
28
+ if metadata.respond_to? :each_pair
29
+ Hashie::Mash.new metadata
30
+ elsif metadata
31
+ metadata
32
+ else
33
+ Hashie::Mash.new
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ class Operation
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
8
+ end
9
+ end
data/lib/operations.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Operations
2
+
3
+ def self.success(code = :success, metadata = {})
4
+ Operation.new success: true, code: code, metadata: metadata
5
+ end
6
+
7
+ def self.failure(code, metadata = {})
8
+ Operation.new success: false, code: code, metadata: metadata
9
+ end
10
+
11
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'operation'
3
+
4
+ describe Operation do
5
+
6
+ describe '#success' do
7
+ it 'handles different types of success' do
8
+ expect( Operation.new(success: true) ).to be_success
9
+ expect( Operation.new(success: 'true') ).to be_success
10
+ expect( Operation.new(success: 1) ).to be_success
11
+ expect( Operation.new(success: '1') ).to be_success
12
+ end
13
+ end
14
+
15
+ describe '#failure' do
16
+ it 'handles different types of failure' do
17
+ expect( Operation.new(success: false) ).to be_failure
18
+ expect( Operation.new(success: 'false') ).to be_failure
19
+ expect( Operation.new(success: 0) ).to be_failure
20
+ expect( Operation.new(success: '0') ).to be_failure
21
+ end
22
+ end
23
+
24
+ describe '#code' do
25
+ it 'is a Symbol if possible' do
26
+ expect( Operation.new(code: :normal).code ).to eq :normal
27
+ expect( Operation.new(code: 'normal').code ).to eq :normal
28
+ expect( Operation.new(code: 'it worked').code ).to eq :'it worked'
29
+ expect( Operation.new(code: 0).code ).to eq :'0'
30
+ expect( Operation.new(code: "\n").code ).to eq :"\n"
31
+ end
32
+
33
+ it 'may be nil' do
34
+ expect( Operation.new.code ).to be_nil
35
+ expect( Operation.new(code: nil).code ).to be_nil
36
+ expect( Operation.new(code: '').code ).to be_nil
37
+ end
38
+ end
39
+
40
+ describe '#metadata' do
41
+ it 'is whatever was passed in' do
42
+ expect( Operation.new(metadata: nil).metadata ).to be_nil
43
+ expect( Operation.new(metadata: []).metadata ).to eq []
44
+ expect( Operation.new(metadata: { one: :two }).metadata ).to eq one: :two
45
+ end
46
+ end
47
+
48
+ describe '#meta' do
49
+ it 'is a Mash for nil' do
50
+ expect( Operation.new.meta ).to be_instance_of Hashie::Mash
51
+ expect( Operation.new(metadata: nil).meta ).to be_instance_of Hashie::Mash
52
+ end
53
+
54
+ it 'is the Mash of what was passed in' do
55
+ expect( Operation.new(metadata: {}).meta ).to be_instance_of Hashie::Mash
56
+ expect( Operation.new(metadata: { one: { two: :three } }).meta.one.two ).to eq :three
57
+ end
58
+
59
+ it 'is the metadata if no Mash possible' do
60
+ expect( Operation.new(metadata: []).meta ).to eq []
61
+ expect( Operation.new(metadata: 'wow').meta ).to eq 'wow'
62
+ end
63
+ end
64
+
65
+ end
File without changes
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: operation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - halo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hashie
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
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: guard-rspec
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
+ - !ruby/object:Gem::Dependency
56
+ name: rb-fsevent
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: See https://github.com/halo/operation
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - README.md
76
+ - lib/operation.rb
77
+ - lib/operation/version.rb
78
+ - lib/operations.rb
79
+ - spec/lib/operation_spec.rb
80
+ - spec/spec_helper.rb
81
+ homepage: https://github.com/halo/operation
82
+ licenses:
83
+ - MIT-LICENSE
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.2.2
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Implementation-agnostic method return status objects
105
+ test_files: []