informator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88050d195612b6c522dd73ce402377bb0eef1205
4
+ data.tar.gz: ad5e5fad66364bcbde46b4db64a827e6348d1419
5
+ SHA512:
6
+ metadata.gz: 2d14dc46cf3956d2605b9b5ca01e47596c42985c14aa2c98f28d19ef75af5109efe1dc2cd47bbec0ed2ea9113da7b96b458327eb44ea9940c2d84b8765a4d4ab
7
+ data.tar.gz: 9949843cdfd102984541ccd34e3cf7238e63d499279fd23f0c452adce57942d512ab8c4be8f6109a860603ad2917da6acdffecb10aecbf2d2365d6d78cc12aeb
@@ -0,0 +1,2 @@
1
+ ---
2
+ service_name: travis-ci
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ *.lock
3
+ .bundle/
4
+ .yardoc/
5
+ coverage/
6
+ doc/
7
+ log/
8
+ pkg/
9
+ tmp/
@@ -0,0 +1,9 @@
1
+ # Settings for metric_fu and its packages are collected in the `config/metrics`
2
+ # and loaded by the Hexx::Suit::Metrics::MetricFu.
3
+
4
+ begin
5
+ require "hexx-suit"
6
+ Hexx::Suit::Metrics::MetricFu.load
7
+ rescue LoadError
8
+ puts "The 'hexx-suit' gem is not installed"
9
+ end
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --color
@@ -0,0 +1,2 @@
1
+ ---
2
+ inherit_from: "./config/metrics/rubocop.yml"
@@ -0,0 +1,15 @@
1
+ ---
2
+ language: ruby
3
+ bundler_args: --without metrics
4
+ cache: bundler
5
+ script: rake test:coverage:run
6
+ rvm:
7
+ - '2.1'
8
+ - ruby-head
9
+ - rbx-2 --2.1
10
+ - jruby-9.0.0.0.pre1
11
+ - jruby-head
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+ - rvm: jruby-head
@@ -0,0 +1,3 @@
1
+ --asset LICENSE
2
+ --exclude lib/informator/version.rb
3
+ --output doc/api
File without changes
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "hexx-suit", "~> 2.2", group: :metrics if RUBY_ENGINE == "ruby"
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ guard :rspec, cmd: "bundle exec rspec" do
4
+
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+
7
+ watch(%r{^lib/(.+)\.rb}) do |m|
8
+ "spec/unit/#{ m[1] }_spec.rb"
9
+ end
10
+
11
+ watch("lib/informator.rb") { "spec" }
12
+ watch("spec/spec_helper.rb") { "spec" }
13
+
14
+ end # guard :rspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2015 Andrew Kozin (nepalez), andrew.kozin@gmail.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,141 @@
1
+ Informator
2
+ ==========
3
+
4
+ [![Gem Version](https://img.shields.io/gem/v/informator.svg?style=flat)][gem]
5
+ [![Build Status](https://img.shields.io/travis/nepalez/informator/master.svg?style=flat)][travis]
6
+ [![Dependency Status](https://img.shields.io/gemnasium/nepalez/informator.svg?style=flat)][gemnasium]
7
+ [![Code Climate](https://img.shields.io/codeclimate/github/nepalez/informator.svg?style=flat)][codeclimate]
8
+ [![Coverage](https://img.shields.io/coveralls/nepalez/informator.svg?style=flat)][coveralls]
9
+ [![Inline docs](http://inch-ci.org/github/nepalez/informator.svg)][inch]
10
+
11
+ [codeclimate]: https://codeclimate.com/github/nepalez/informator
12
+ [coveralls]: https://coveralls.io/r/nepalez/informator
13
+ [gem]: https://rubygems.org/gems/informator
14
+ [gemnasium]: https://gemnasium.com/nepalez/informator
15
+ [travis]: https://travis-ci.org/nepalez/informator
16
+ [inch]: https://inch-ci.org/github/nepalez/informator
17
+
18
+ The [wisper]-inspired tiny implementation of publish/subscribe design pattern.
19
+
20
+ The implementation differs from the original wisper's approach in the following aspects:
21
+
22
+ * Unlike `Wisper::Publisher` that calls listener methods depending on the event, the `Informator` uses the same listener's callback for sending all events. Instead it wraps data to `Informator::Event` container and uses its as the argument for the callback.
23
+
24
+ * The `Informator` has two separate methods - `#remember` and `#publish`. The first one is used to build and collect events, while the second one publishes all unpublished events at once (and clears the list of events to be published).
25
+
26
+ * The `Informator` also defines `#publish!` method that is the same as `#publish` except for it throws the `:published`, that should be catched somewhere. This is just a shortcut for exiting from a use cases.
27
+
28
+ * The `#publish` method returns the list of published events. The exception thrown by `#publish!` carries that list as well. This allows not only to publish them to listeners but to return them to caller. This is necessary to simplify chaining of service objects that includes the `Informator`.
29
+
30
+ * The `Informator` has no global neither async subscribers. The gem's scope is narrower. Its main goal is to support service objects, that are either chained to each other, or publishes their results to decoupled listeners.
31
+
32
+ [wisper]: https://github.com/krisleech/wisper
33
+
34
+ Synopsis
35
+ --------
36
+
37
+ The `Informator` module API defines 4 instance methods:
38
+
39
+ * `#subscribe` to subscribe listeners for receiving events, published by the informator
40
+ * `#remember` to build an event and keep it unpublished
41
+ * `#publish` to publish all events keeped since last publishing
42
+ * `#publish!` the same as `#publish`, except for it throws `:published` exception which carries a list of events
43
+
44
+ Except for the `Informator` the module defines public class `Informator::Event` for immutable events, that has 3 attributes:
45
+
46
+ * `#type` for symbolic type of the event
47
+ * `#data` for hash of data, carried by the event
48
+ * `#messages` for array of human-readable messages, describing the event
49
+
50
+ The event instance is build by the `#remember`, `#publish` or `#publish!` methods and is sent to listeners by either `#publish` or `#publish!`. When sending an event, the informator just calls the listeners callback, defined by `#subscribe` method, and gives it a corresponding event object as the only argument.
51
+
52
+ ```ruby
53
+ require "informator"
54
+
55
+ class Listener
56
+ def receive(event)
57
+ puts "The listener received #{ event.type }: #{ event.messages }"
58
+ end
59
+ end
60
+
61
+ listener = Listener.new
62
+
63
+ class Service
64
+ include Informator
65
+
66
+ def call
67
+ catch(:published) { do_some_staff }
68
+ end
69
+
70
+ def do_some_staff
71
+ # ...
72
+ remember :success, "for now all is fine", foo: :bar
73
+ #
74
+ publish! :error, "OMG!", bar: :baz
75
+ end
76
+ end
77
+
78
+ service = Service.new
79
+ service.subscribe listener, :receive
80
+ result = service.call
81
+ # The listener received success: ["for now all is fine"]
82
+ # The listener received error: ["OMG!"]
83
+ # => [
84
+ # #<Informator::Event @type=:success @data={ foo: :bar } @messages=["for now all is fine"]>,
85
+ # #<Informator::Event @type=:error @data={ bar: :baz } @messages=["OMG!"]>
86
+ # ]
87
+
88
+ ```
89
+
90
+ In the example above the `listener#receive` method is called twice with the first, and then with the second event as an argument.
91
+
92
+ Then the `publish!` throws an exception that carries the list of messages.
93
+ The `service#call` catches it and returns the array of events. With this feature it is possible not only to subscribe for the service's events but receive it directly, combining [both telling and asking](http://martinfowler.com/bliki/TellDontAsk.html) when necessary.
94
+
95
+ Installation
96
+ ------------
97
+
98
+ Add this line to your application's Gemfile:
99
+
100
+ ```ruby
101
+ # Gemfile
102
+ gem "informator"
103
+ ```
104
+
105
+ Then execute:
106
+
107
+ ```
108
+ bundle
109
+ ```
110
+
111
+ Or add it manually:
112
+
113
+ ```
114
+ gem install informator
115
+ ```
116
+
117
+ Compatibility
118
+ -------------
119
+
120
+ Tested under rubies [compatible to MRI 2.1+](.travis.yml).
121
+
122
+ Uses [RSpec] 3.0+ for testing and [hexx-suit] for dev/test tools collection.
123
+
124
+ [RSpec]: http://rspec.org
125
+ [hexx-suit]: https://github.com/nepalez/hexx-suit
126
+
127
+ Contributing
128
+ ------------
129
+
130
+ * Read the [STYLEGUIDE](config/metrics/STYLEGUIDE)
131
+ * [Fork the project](https://github.com/nepalez/informator)
132
+ * Create your feature branch (`git checkout -b my-new-feature`)
133
+ * Add tests for it
134
+ * Commit your changes (`git commit -am '[UPDATE] Add some feature'`)
135
+ * Push to the branch (`git push origin my-new-feature`)
136
+ * Create a new Pull Request
137
+
138
+ License
139
+ -------
140
+
141
+ See the [MIT LICENSE](LICENSE).
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ begin
3
+ require "bundler/setup"
4
+ rescue LoadError
5
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
6
+ exit
7
+ end
8
+
9
+ # Loads bundler tasks
10
+ Bundler::GemHelper.install_tasks
11
+
12
+ # Loads the Hexx::RSpec and its tasks
13
+ begin
14
+ require "hexx-suit"
15
+ Hexx::Suit.install_tasks
16
+ rescue LoadError
17
+ require "hexx-rspec"
18
+ Hexx::RSpec.install_tasks
19
+ end
20
+
21
+ # Sets the Hexx::RSpec :test task to default
22
+ task default: "test:coverage:run"
23
+
24
+ desc "Runs mutation metric for testing"
25
+ task :mutant do
26
+ system "mutant -r informator --use rspec 'Informator*' --fail-fast"
27
+ end
@@ -0,0 +1,226 @@
1
+ = Ruby Style Guide
2
+
3
+ Adapted from Dan Kubb's Ruby Style Guide
4
+ https://github.com/dkubb/styleguide/blob/master/RUBY-STYLE
5
+
6
+ == Commiting:
7
+
8
+ * Write descriptive commit messages, following the pattern:
9
+
10
+ [TYPE] name
11
+
12
+ The message, describing the changes being made
13
+
14
+ * Use the types below to mark commits:
15
+
16
+ - [FEATURE] - for adding new features, or backward-compatible changes;
17
+ - [CHANGE] - for backward-incompatible changes;
18
+ - [BUG FIX] - for fixing bugs;
19
+ - [REFACTORING] - for other changes of the code not affecting the API;
20
+ - [OTHER] - for changes in documentaton, metrics etc, not touching the code;
21
+ - [VERSION] - for version changes.
22
+
23
+ * Always separate commits of different types (such as FEATURE and CHANGE).
24
+
25
+ * Try to separate various features from each other.
26
+
27
+ * Include specification to the same commit as the code.
28
+
29
+ * Run all tests before making a commit.
30
+ Never commit the code that break unit tests.
31
+
32
+ * Use metric (run `rake check`) before making a commit.
33
+
34
+ * Do refactoring before making a commit. Best writing is rewriting.
35
+
36
+ * Follow semantic versioning.
37
+
38
+ http://semver.org/
39
+
40
+ * For versions name the commit after a version number, following the pattern:
41
+
42
+ VERSION 1.0.0-rc2
43
+
44
+ == Formatting:
45
+
46
+ * Use UTF-8. Declare encoding in the first line of every file.
47
+
48
+ # encoding: utf-8
49
+
50
+ * Use 2 space indent, no tabs.
51
+
52
+ * Use Unix-style line endings.
53
+
54
+ * Use spaces around operators, after commas, colons and semicolons,
55
+ around { and before }.
56
+
57
+ * No spaces after (, [ and before ], ).
58
+
59
+ * Align `when` and `else` with `case`.
60
+
61
+ * Use an empty line before the return value of a method (unless it
62
+ only has one line), and an empty line between defs.
63
+
64
+ * Use empty lines to break up a long method into logical paragraphs.
65
+
66
+ * Keep lines fewer than 80 characters.
67
+
68
+ * Strip trailing whitespace.
69
+
70
+ == Syntax:
71
+
72
+ * Write for 2.1.
73
+
74
+ * Use double quotes
75
+
76
+ http://viget.com/extend/just-use-double-quoted-ruby-strings
77
+
78
+ * Use def with parentheses when there are arguments.
79
+
80
+ * Never use for, unless you exactly know why.
81
+
82
+ * Never use then, except in case statements.
83
+
84
+ * Use when x then ... for one-line cases.
85
+
86
+ * Use &&/|| for boolean expressions, and/or for control flow. (Rule
87
+ of thumb: If you have to use outer parentheses, you are using the
88
+ wrong operators.)
89
+
90
+ * Avoid double negation (!!), unless Null Objects are expected.
91
+
92
+ http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness
93
+
94
+ * Avoid multiline ?:, use if.
95
+
96
+ * Use {...} when defining blocks on one line. Use do...end for multiline
97
+ blocks. The same is for procs and lambdas.
98
+
99
+ * Avoid return where not required.
100
+
101
+ * Use ||= freely.
102
+
103
+ * Use OO regexps, and avoid =~ $0-9, $~, $` and $' when possible.
104
+
105
+ * Do not use Enumerable#inject when the "memo" object does not change between
106
+ iterations, use Enumerable#each_with_object instead.
107
+
108
+ * Prefer ENV.fetch to ENV[] syntax.
109
+ Prefer block syntax for ENV.fetch to the second argument.
110
+
111
+
112
+ == Naming:
113
+
114
+ * Use snake_case for methods. Add the __ affixes to private methods.
115
+
116
+ * Use CamelCase for classes and modules. (Keep acronyms like HTTP,
117
+ RFC, XML, UUID uppercase.)
118
+
119
+ * Use SCREAMING_SNAKE_CASE for other constants.
120
+
121
+ * Do not use single letter variable names. Avoid uncommunicative names.
122
+
123
+ * Use consistent variable names. Try to keep the variable names close
124
+ to the object class name.
125
+
126
+ * Use names prefixed with _ for unused variables.
127
+
128
+ * When defining a predicate method that compares against another object of
129
+ a similar type, name the argument "other".
130
+
131
+ * Prefer map over collect, detect over find, select over find_all.
132
+
133
+ * Use def self.method to define singleton methods.
134
+
135
+ * Avoid alias when alias_method will do.
136
+
137
+ == Comments:
138
+
139
+ * Use YARD and its conventions for API documentation. Don't put an
140
+ empty line between the comment block and the def.
141
+
142
+ * Comments longer than a word are capitalized and use punctuation.
143
+ Use one space after periods.
144
+
145
+ * Avoid superfluous comments.
146
+
147
+
148
+ == Code structuring:
149
+
150
+ * Break code into packages, decoupled from the environment.
151
+
152
+ * Wrap packages into gems.
153
+
154
+ * Inject dependencies explicitly.
155
+ Leave all outer references on the border of any package. Inside
156
+ the package use internal references only.
157
+
158
+ * Follow SOLID principles.
159
+
160
+ http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
161
+
162
+ * Only give a method one purpose for existing. If you pass in a boolean
163
+ to a method, what you're saying is that this method has two different
164
+ behaviours. Just split it into two single purpose methods. If you have
165
+ to use the words "AND" or "OR" to describe what the method does it
166
+ probably does too much.
167
+
168
+ * Avoid long methods.
169
+ Try to keep them at no more than 6 lines long, and preferably 4 or less.
170
+
171
+ If sections of a method are logically separate by blank lines, then
172
+ that's probably a sign that those sections should be split into separate
173
+ methods.
174
+
175
+ * Avoid hashes-as-optional-parameters. Does the method do too much?
176
+
177
+ * Avoid long parameter lists.
178
+
179
+ * Add "global" methods to Kernel (if you have to) and make them private.
180
+
181
+ * Use OptionParser for parsing complex command line options and
182
+ ruby -s for trivial command line options.
183
+
184
+ * Avoid needless metaprogramming.
185
+
186
+ * Always freeze objects assigned to constants.
187
+
188
+
189
+ == General:
190
+
191
+ * Code in a functional way, avoid mutation when it makes sense.
192
+
193
+ * Try to have methods either return the state of the object and have
194
+ no side effects, or return self and have side effects. This is
195
+ otherwise known as Command-query separation (CQS):
196
+
197
+ http://en.wikipedia.org/wiki/Command-query_separation
198
+
199
+ * Do not mutate arguments unless that is the purpose of the method.
200
+
201
+ * Try following TRUE heuristics by Sandi Metz
202
+
203
+ http://designisrefactoring.com/2015/02/08/introducing-sandi-metz-true/
204
+
205
+ * Do not mess around in core classes when writing libraries.
206
+ Namespace your code inside the modules, or wrap core classes to
207
+ decorators of your own.
208
+
209
+ * Do not program defensively.
210
+
211
+ http://www.erlang.se/doc/programming_rules.shtml#HDR11
212
+
213
+ * Keep the code simple.
214
+
215
+ * Don't overdesign.
216
+
217
+ * Don't underdesign.
218
+
219
+ * Avoid bugs.
220
+
221
+ * Read other style guides and apply the parts that don't dissent with
222
+ this list.
223
+
224
+ * Be consistent.
225
+
226
+ * Use common sense.