informator 0.0.1
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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +5 -0
- data/Guardfile +14 -0
- data/LICENSE +21 -0
- data/README.md +141 -0
- data/Rakefile +27 -0
- data/config/metrics/STYLEGUIDE +226 -0
- data/config/metrics/cane.yml +5 -0
- data/config/metrics/churn.yml +6 -0
- data/config/metrics/flay.yml +2 -0
- data/config/metrics/metric_fu.yml +15 -0
- data/config/metrics/reek.yml +1 -0
- data/config/metrics/roodi.yml +24 -0
- data/config/metrics/rubocop.yml +76 -0
- data/config/metrics/saikuro.yml +3 -0
- data/config/metrics/simplecov.yml +8 -0
- data/config/metrics/yardstick.yml +37 -0
- data/informator.gemspec +23 -0
- data/lib/informator.rb +82 -0
- data/lib/informator/event.rb +80 -0
- data/lib/informator/reporter.rb +67 -0
- data/lib/informator/subscriber.rb +88 -0
- data/lib/informator/version.rb +9 -0
- data/spec/integration/informator_spec.rb +147 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/unit/informator/event_spec.rb +71 -0
- data/spec/unit/informator/reporter_spec.rb +75 -0
- data/spec/unit/informator/subscriber_spec.rb +86 -0
- metadata +100 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
folders: # The list of folders to be used by any metric.
|
3
|
+
- lib
|
4
|
+
- app
|
5
|
+
metrics: # The list of allowed metrics. The other metrics are disabled.
|
6
|
+
- cane
|
7
|
+
- churn
|
8
|
+
- flay
|
9
|
+
- flog
|
10
|
+
- reek
|
11
|
+
- roodi
|
12
|
+
- saikuro
|
13
|
+
format: html
|
14
|
+
output: tmp/metric_fu
|
15
|
+
verbose: false
|
@@ -0,0 +1 @@
|
|
1
|
+
---
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
AssignmentInConditionalCheck:
|
3
|
+
CaseMissingElseCheck:
|
4
|
+
ClassLineCountCheck:
|
5
|
+
line_count: 300
|
6
|
+
ClassNameCheck:
|
7
|
+
pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
|
8
|
+
ClassVariableCheck:
|
9
|
+
CyclomaticComplexityBlockCheck:
|
10
|
+
complexity: 4
|
11
|
+
CyclomaticComplexityMethodCheck:
|
12
|
+
complexity: 8
|
13
|
+
EmptyRescueBodyCheck:
|
14
|
+
ForLoopCheck:
|
15
|
+
MethodLineCountCheck:
|
16
|
+
line_count: 20
|
17
|
+
MethodNameCheck:
|
18
|
+
pattern: !ruby/regexp /^[\||\^|\&|\!]$|^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/
|
19
|
+
ModuleLineCountCheck:
|
20
|
+
line_count: 300
|
21
|
+
ModuleNameCheck:
|
22
|
+
pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
|
23
|
+
ParameterNumberCheck:
|
24
|
+
parameter_count: 5
|
@@ -0,0 +1,76 @@
|
|
1
|
+
---
|
2
|
+
# settings added by the 'hexx-suit' module
|
3
|
+
# output: "tmp/rubocop"
|
4
|
+
# format: "html"
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
Exclude:
|
8
|
+
- '**/db/schema.rb'
|
9
|
+
|
10
|
+
Lint/HandleExceptions:
|
11
|
+
Exclude:
|
12
|
+
- '**/*_spec.rb'
|
13
|
+
|
14
|
+
Lint/RescueException:
|
15
|
+
Exclude:
|
16
|
+
- '**/*_spec.rb'
|
17
|
+
|
18
|
+
Style/AccessorMethodName:
|
19
|
+
Exclude:
|
20
|
+
- '**/*_spec.rb'
|
21
|
+
|
22
|
+
Style/AsciiComments:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/ClassAndModuleChildren:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/Documentation:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/EmptyLinesAroundBlockBody:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/EmptyLinesAroundClassBody:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/EmptyLinesAroundMethodBody:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/EmptyLinesAroundModuleBody:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/EmptyLineBetweenDefs:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/FileName:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/RaiseArgs:
|
50
|
+
EnforcedStyle: compact
|
51
|
+
|
52
|
+
Style/RescueModifier:
|
53
|
+
Exclude:
|
54
|
+
- '**/*_spec.rb'
|
55
|
+
|
56
|
+
Style/SingleLineMethods:
|
57
|
+
Exclude:
|
58
|
+
- '**/*_spec.rb'
|
59
|
+
|
60
|
+
Style/SingleSpaceBeforeFirstArg:
|
61
|
+
Enabled: false
|
62
|
+
|
63
|
+
Style/SpecialGlobalVars:
|
64
|
+
Exclude:
|
65
|
+
- '**/Gemfile'
|
66
|
+
- '**/*.gemspec'
|
67
|
+
|
68
|
+
Style/StringLiterals:
|
69
|
+
EnforcedStyle: double_quotes
|
70
|
+
|
71
|
+
Style/StringLiteralsInInterpolation:
|
72
|
+
EnforcedStyle: double_quotes
|
73
|
+
|
74
|
+
Style/TrivialAccessors:
|
75
|
+
Exclude:
|
76
|
+
- '**/*_spec.rb'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
---
|
2
|
+
# Settings added by the 'hexx-suit' gem
|
3
|
+
output: "tmp/yardstick/output.log"
|
4
|
+
path: "lib/**/*.rb"
|
5
|
+
rules:
|
6
|
+
ApiTag::Presence:
|
7
|
+
enabled: true
|
8
|
+
exclude: []
|
9
|
+
ApiTag::Inclusion:
|
10
|
+
enabled: true
|
11
|
+
exclude: []
|
12
|
+
ApiTag::ProtectedMethod:
|
13
|
+
enabled: true
|
14
|
+
exclude: []
|
15
|
+
ApiTag::PrivateMethod:
|
16
|
+
enabled: false
|
17
|
+
exclude: []
|
18
|
+
ExampleTag:
|
19
|
+
enabled: true
|
20
|
+
exclude: []
|
21
|
+
ReturnTag:
|
22
|
+
enabled: true
|
23
|
+
exclude: []
|
24
|
+
Summary::Presence:
|
25
|
+
enabled: true
|
26
|
+
exclude: []
|
27
|
+
Summary::Length:
|
28
|
+
enabled: true
|
29
|
+
exclude: []
|
30
|
+
Summary::Delimiter:
|
31
|
+
enabled: true
|
32
|
+
exclude: []
|
33
|
+
Summary::SingleLine:
|
34
|
+
enabled: true
|
35
|
+
exclude: []
|
36
|
+
threshold: 100
|
37
|
+
verbose: false
|
data/informator.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "informator/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
|
6
|
+
gem.name = "informator"
|
7
|
+
gem.version = Informator::VERSION.dup
|
8
|
+
gem.author = "Andrew Kozin"
|
9
|
+
gem.email = "andrew.kozin@gmail.com"
|
10
|
+
gem.homepage = "https://github.com/nepalez/informator"
|
11
|
+
gem.summary = "Implementation of subscribe/publish design pattern"
|
12
|
+
gem.license = "MIT"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
15
|
+
gem.test_files = Dir["spec/**/*.rb"]
|
16
|
+
gem.extra_rdoc_files = Dir["README.md", "LICENSE"]
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.required_ruby_version = "~> 2.1"
|
20
|
+
|
21
|
+
gem.add_development_dependency "hexx-rspec", "~> 0.4"
|
22
|
+
|
23
|
+
end # Gem::Specification
|
data/lib/informator.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "informator/event"
|
4
|
+
require_relative "informator/subscriber"
|
5
|
+
require_relative "informator/reporter"
|
6
|
+
|
7
|
+
# The module provides subscribe/publish/report features
|
8
|
+
#
|
9
|
+
module Informator
|
10
|
+
|
11
|
+
# Subscribes the listener for receiving events notifications via callback
|
12
|
+
#
|
13
|
+
# @param [Object] listener
|
14
|
+
# The object to send events to
|
15
|
+
# @param [#to_sym] callback (:receive)
|
16
|
+
# The name of the listener method to send events through
|
17
|
+
#
|
18
|
+
# @return [self] itself
|
19
|
+
#
|
20
|
+
def subscribe(listener, callback = :receive)
|
21
|
+
sub = Subscriber.new(listener, callback)
|
22
|
+
__subscribers__ << sub unless __subscribers__.include? sub
|
23
|
+
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
# @!method remember(type, messages, data)
|
28
|
+
# Builds and stores the event waiting for being published
|
29
|
+
#
|
30
|
+
# @param (see Informator::Event.new)
|
31
|
+
#
|
32
|
+
# @return [self] itself
|
33
|
+
#
|
34
|
+
def remember(*args)
|
35
|
+
__reporter__.remember(*args)
|
36
|
+
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# @overload publish(type, messages, data)
|
41
|
+
# Builds the event and then publishes all unpublished events
|
42
|
+
#
|
43
|
+
# @param (see #remember)
|
44
|
+
#
|
45
|
+
# @overload publish
|
46
|
+
# Publishes all unpublished events without adding a new one
|
47
|
+
#
|
48
|
+
# @return [Array<Informator::Event>] list of events having been published
|
49
|
+
#
|
50
|
+
def publish(*args)
|
51
|
+
remember(*args) if args.any?
|
52
|
+
__reporter__.notify __subscribers__
|
53
|
+
end
|
54
|
+
|
55
|
+
# The same as `publish` except for it throws `:published` afterwards
|
56
|
+
#
|
57
|
+
# @overload publish(type, messages, data)
|
58
|
+
# Builds the event and then publishes all unpublished events
|
59
|
+
#
|
60
|
+
# @param (see #remember)
|
61
|
+
#
|
62
|
+
# @overload publish
|
63
|
+
# Publishes all unpublished events without adding a new one
|
64
|
+
#
|
65
|
+
# @raise [UncaughtThrowError, ArgumentError]
|
66
|
+
# for `:published` events being carried
|
67
|
+
#
|
68
|
+
def publish!(*args)
|
69
|
+
throw :published, publish(*args)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def __reporter__
|
75
|
+
@__reporter__ ||= Reporter.new
|
76
|
+
end
|
77
|
+
|
78
|
+
def __subscribers__
|
79
|
+
@__subscribers__ ||= []
|
80
|
+
end
|
81
|
+
|
82
|
+
end # module Informator
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Informator
|
4
|
+
|
5
|
+
# Class Event provides an immutable container for hash of some data, to
|
6
|
+
# which a type is attached. It also contains an array of human-readable
|
7
|
+
# messages describing the event.
|
8
|
+
#
|
9
|
+
# The primary goal of events is folding data to be returned and/or sent
|
10
|
+
# between various objects into unified format.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# event = Event.new :success, "bingo!", foo: :bar
|
14
|
+
# # => #<Event @type=:success, @messages=["bingo!"], @data={ :foo => :bar }>
|
15
|
+
# event.frozen?
|
16
|
+
# # => true
|
17
|
+
#
|
18
|
+
class Event
|
19
|
+
|
20
|
+
include Comparable
|
21
|
+
|
22
|
+
# @!attribute [r] type
|
23
|
+
#
|
24
|
+
# @return [Symbol] the type of the event
|
25
|
+
#
|
26
|
+
attr_reader :type
|
27
|
+
|
28
|
+
# @!attribute [r] data
|
29
|
+
#
|
30
|
+
# @return [Hash] the event-specific data
|
31
|
+
#
|
32
|
+
attr_reader :data
|
33
|
+
|
34
|
+
# @!attribute [r] messages
|
35
|
+
#
|
36
|
+
# @return [Array<String>] human-readable messages, describing the event
|
37
|
+
#
|
38
|
+
attr_reader :messages
|
39
|
+
|
40
|
+
# @!scope class
|
41
|
+
# @!method new(type, messages, data)
|
42
|
+
# Builds the event
|
43
|
+
#
|
44
|
+
# @param [#to_sym] type
|
45
|
+
# @param [#to_s, Array<#to_s>] messages
|
46
|
+
# @param [Hash] data
|
47
|
+
#
|
48
|
+
# @return [Informator::Event]
|
49
|
+
|
50
|
+
# @private
|
51
|
+
def initialize(type, *messages, **data)
|
52
|
+
@type = type.to_sym
|
53
|
+
@messages = messages.flatten.map(&:to_s)
|
54
|
+
@data = data
|
55
|
+
freeze
|
56
|
+
end
|
57
|
+
|
58
|
+
# Compares the event to another one by their types and data
|
59
|
+
#
|
60
|
+
# @param [Object] other
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
#
|
64
|
+
def ==(other)
|
65
|
+
other.is_a?(self.class) && other.value.eql?(value)
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
# Returns value to compare events by
|
71
|
+
#
|
72
|
+
# @return [Array]
|
73
|
+
#
|
74
|
+
def value
|
75
|
+
[type, data]
|
76
|
+
end
|
77
|
+
|
78
|
+
end # class Event
|
79
|
+
|
80
|
+
end # module Informator
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Informator
|
4
|
+
|
5
|
+
# Builds, collects and publishes events to selected subscribers
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# reporter = Reporter.new
|
9
|
+
# reporter.events # => []
|
10
|
+
#
|
11
|
+
# reporter.remember :success
|
12
|
+
# reporter.events # => [#<Event @type=:success @data={} @messages=[]>]
|
13
|
+
#
|
14
|
+
# # this will call subscriber.notify for any event
|
15
|
+
# reporter.notify subscriber
|
16
|
+
# reporter.events # => []
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
#
|
20
|
+
class Reporter
|
21
|
+
|
22
|
+
# @private
|
23
|
+
def initialize
|
24
|
+
@events = []
|
25
|
+
freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
# @!attribute [r] events
|
29
|
+
# @return [Array<Informator::Event>]
|
30
|
+
# the list of registered events that havent'b been published yet
|
31
|
+
attr_reader :events
|
32
|
+
|
33
|
+
# @!method remember(type, messages, data)
|
34
|
+
# Registers the event to be published to subscribers
|
35
|
+
#
|
36
|
+
# @param (see Informator::Event.new)
|
37
|
+
#
|
38
|
+
# @return [self] itself
|
39
|
+
#
|
40
|
+
def remember(*args)
|
41
|
+
events << Event.new(*args)
|
42
|
+
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
# Notifies subscribers on events registered since the last notification
|
47
|
+
#
|
48
|
+
# Mutates [#events] by excluding all events having been published.
|
49
|
+
#
|
50
|
+
# @param [Informator::Subscriber, Array<Informator::Subscriber>] subscribers
|
51
|
+
# the list of subscribers to be notified
|
52
|
+
#
|
53
|
+
# @return [Array<Informator::Event>] the list of published events
|
54
|
+
def notify(*subscribers)
|
55
|
+
events.dup.each { publish subscribers.flatten }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def publish(subscribers)
|
61
|
+
event = events.shift
|
62
|
+
subscribers.each { |subscriber| subscriber.notify event }
|
63
|
+
end
|
64
|
+
|
65
|
+
end # class Reporter
|
66
|
+
|
67
|
+
end # module Informator
|