spectro 0.2
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/README.md +33 -0
- data/bin/spectro +5 -0
- data/lib/spectro.rb +52 -0
- data/lib/spectro/client.rb +16 -0
- data/lib/spectro/compiler.rb +65 -0
- data/lib/spectro/config.rb +31 -0
- data/lib/spectro/database.rb +45 -0
- data/lib/spectro/exception.rb +9 -0
- data/lib/spectro/exception/undefined_method_definition.rb +22 -0
- data/lib/spectro/exception/unknown_mock_response.rb +22 -0
- data/lib/spectro/mock.rb +41 -0
- data/lib/spectro/spec.rb +28 -0
- data/lib/spectro/spec/parser.rb +86 -0
- data/lib/spectro/spec/rule.rb +28 -0
- data/lib/spectro/spec/signature.rb +30 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1bf7b456866166c224e87dca6b5526766412dd3f
|
4
|
+
data.tar.gz: 6e888e0846f3111e2af07f77b5d982c1e7fe6e20
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: de13b0e41bb2bf2fc3a0aedb8600593e0d587789faf99633a189faa0182f4f60d45bb4dc3abcbd2fbd0cbff350681f6203d246246eae76fc6682b6defdc2ba98
|
7
|
+
data.tar.gz: fe5c65a3242a62ca08a4bfd9936cfe39662b7dc8d5bcb20c5df2c0edacfebb90c5f5d929c33d4ce81fa9be32f25b0627af67b347dd6c76e3b70f62aa4071c2b4
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Spectro
|
2
|
+
|
3
|
+
Specs driven social meta-programming
|
4
|
+
|
5
|
+
[](https://travis-ci.org/robertodecurnex/spectro)
|
6
|
+
[](https://codeclimate.com/github/robertodecurnex/spectro)
|
7
|
+
[](https://codeclimate.com/github/robertodecurnex/spectro)
|
8
|
+
[](http://www.rubydoc.info/github/robertodecurnex/spectro/master)
|
9
|
+
|
10
|
+
## Prototype
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
require 'spectro'
|
14
|
+
|
15
|
+
class Sample
|
16
|
+
|
17
|
+
include Spectro
|
18
|
+
|
19
|
+
implements \
|
20
|
+
hello: [:name]
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
__END__
|
25
|
+
spec_for hello String -> String
|
26
|
+
"Minion" -> "Say Hello to Minion"
|
27
|
+
"Roberto" -> "Say Hello to Roberto"
|
28
|
+
"Roland" -> "Say Hello to Roland"
|
29
|
+
```
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
sample.hello 'Eddie' #=> 'Say Hello to Eddie'
|
33
|
+
```
|
data/bin/spectro
ADDED
data/lib/spectro.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'singleton'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
require 'spectro/config'
|
7
|
+
require 'spectro/database'
|
8
|
+
require 'spectro/exception'
|
9
|
+
require 'spectro/mock'
|
10
|
+
require 'spectro/spec'
|
11
|
+
|
12
|
+
# Specs driven social meta-programming
|
13
|
+
module Spectro
|
14
|
+
|
15
|
+
# Extends the caller with the Spectro class methods on #include
|
16
|
+
def self.included klass
|
17
|
+
klass.extend(ClassMethods)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Gives access to the Spectro::Config instance insde the given block
|
21
|
+
#
|
22
|
+
# Usage:
|
23
|
+
# Spectro.configure do |config|
|
24
|
+
# config.enable_mocks!
|
25
|
+
# end
|
26
|
+
def self.configure
|
27
|
+
yield Spectro::Config.instance
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
# Register the given method name supporting the given parameters.
|
33
|
+
#
|
34
|
+
# Whenever Spectro::Config.mocks_enabled? is true it will try to cover unfulfilled
|
35
|
+
# specs using the knwon rules as mocks.
|
36
|
+
#
|
37
|
+
# @param [{String, Symbol=><String, Symbol>}] interfaces hash of method names and required param names that the method supports
|
38
|
+
def implements interfaces
|
39
|
+
file_path = caller.first.match(/#{Dir.pwd}\/(.+):\d+:in .+/)[1]
|
40
|
+
interfaces.each do |method_name, required_params|
|
41
|
+
λ = Spectro::Database.fetch(file_path, method_name, *required_params) || Spectro::Mock.create(file_path, method_name)
|
42
|
+
|
43
|
+
raise Spectro::Exception::UndefinedMethodDefinition.new(file_path, method_name) if λ.nil?
|
44
|
+
|
45
|
+
self.send(:define_method, method_name, &λ)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spectro'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module Spectro
|
5
|
+
|
6
|
+
class Client < Thor
|
7
|
+
|
8
|
+
desc 'compile', 'Parses the current project looking for unfulfilled specs and looks for suitable lambdas in the repos. It then updates the cache with them.'
|
9
|
+
def compile
|
10
|
+
require 'spectro/compiler'
|
11
|
+
Spectro::Compiler.compile
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spectro'
|
2
|
+
require 'spectro/spec/parser'
|
3
|
+
require 'yaml/store'
|
4
|
+
|
5
|
+
module Spectro
|
6
|
+
|
7
|
+
# Spectro:Compiler is in charge of spectroan the projects and parse its files,
|
8
|
+
# updating the project Spectro index and dumping information about the missing
|
9
|
+
# implementations (specs without an associated lambda)
|
10
|
+
class Compiler
|
11
|
+
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
class << self
|
15
|
+
extend Forwardable
|
16
|
+
def_delegators :instance, :compile
|
17
|
+
end
|
18
|
+
|
19
|
+
# Filters the project files keeping those making use of Spectro.
|
20
|
+
# It them parses those files, check for missing implementations
|
21
|
+
# and creates an .spectro/undefined.yml with the specs of them.
|
22
|
+
#
|
23
|
+
# @return [Spectro::Compiler] self
|
24
|
+
def compile
|
25
|
+
undefined_yaml = YAML::Store.new(".spectro/undefined.yml")
|
26
|
+
undefined_yaml.transaction do
|
27
|
+
targets().map do |path|
|
28
|
+
missing_specs = missing_specs_from_file(path)
|
29
|
+
|
30
|
+
next if missing_specs.empty?
|
31
|
+
|
32
|
+
undefined_yaml[path] = missing_specs
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
return self
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Parse the specs on the given file path and return those specs
|
42
|
+
# that have not been fulfilled or need to be updated.
|
43
|
+
#
|
44
|
+
# @param [String] path target file path
|
45
|
+
# @return [<Spectro::Spec>] collection of specs not fulfilled or out of date
|
46
|
+
def missing_specs_from_file(path)
|
47
|
+
Spectro::Spec::Parser.parse(path).select do |spec|
|
48
|
+
index_spec = Spectro::Database.index[path] && Spectro::Database.index[path][spec.signature.name]
|
49
|
+
index_spec.nil? || index_spec['spec_md5'] != spec.md5
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Filter project's rb files returning an Array of files
|
54
|
+
# containinig specs to be parsed.
|
55
|
+
#
|
56
|
+
# @return [<String>] array of files to be parsed
|
57
|
+
def targets
|
58
|
+
return %x[ grep -Pzrl --include="*.rb" "^__END__.*\\n.*spec_for" . ].split("\n").collect do |path|
|
59
|
+
path[2..-1]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
attr_accessor :mocks_enabled
|
6
|
+
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
class << self
|
10
|
+
extend Forwardable
|
11
|
+
def_delegators :instance, :enable_mocks!, :mocks_enabled?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sets mocks_enabled to true
|
15
|
+
#
|
16
|
+
# @return [Spectro::Config] self
|
17
|
+
def enable_mocks!
|
18
|
+
self.mocks_enabled = true
|
19
|
+
return self
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the current mocks policy (enabled or disabled)
|
23
|
+
#
|
24
|
+
# @return [TrueClass, FalseClass] whether mocks are enabled or not
|
25
|
+
def mocks_enabled?
|
26
|
+
return !!self.mocks_enabled
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
# Gives access to the current collection of
|
4
|
+
# algorithms (lambdas) providing several ways
|
5
|
+
# to fetch specific elements by different criterias.
|
6
|
+
class Database
|
7
|
+
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
class << self
|
11
|
+
extend Forwardable
|
12
|
+
def_delegators :instance, :fetch, :index
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :cache
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
self.cache = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Lazy loads the index.yml and returns it
|
22
|
+
#
|
23
|
+
# @return [Hash] the parsed index.yml
|
24
|
+
def index
|
25
|
+
@index ||= YAML.load_file('./.spectro/index.yml')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fetches and return the target lambda based on the
|
29
|
+
# given class, method name and required aprameters.
|
30
|
+
#
|
31
|
+
# @param [String] file_path relative path of the file that requests the lambda
|
32
|
+
# @param [Symbol] method_name the method name that would be implemented
|
33
|
+
# @param [<Symbol>] required_params parameters that would be required by the lambda
|
34
|
+
# @return [Proc] the labda that would be implemented
|
35
|
+
def fetch file_path, method_name, *required_params
|
36
|
+
if self.index["#{file_path}"].nil? || self.index["#{file_path}"]["#{method_name}"].nil?
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
λ_id = self.index["#{file_path}"]["#{method_name}"]['lambda_id']
|
40
|
+
return self.cache[λ_id] ||= eval(File.read(".spectro/cache/#{λ_id}.rb"))
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
module Exception
|
4
|
+
|
5
|
+
class UndefinedMethodDefinition < ::Exception
|
6
|
+
|
7
|
+
attr_accessor :file_path, :method_name
|
8
|
+
|
9
|
+
def initialize file_path, method_name
|
10
|
+
self.file_path = file_path
|
11
|
+
self.method_name = method_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"[##{self.method_name}] has not been defiend for \"#{self.file_path}\". Verify the specs at \"#{self.file_path}\" and check the `spectro compile` output for more detailed information."
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
module Exception
|
4
|
+
|
5
|
+
class UnknownMockResponse < ::Exception
|
6
|
+
|
7
|
+
attr_accessor :file_path, :method_name
|
8
|
+
|
9
|
+
def initialize file_path, method_name
|
10
|
+
self.file_path = file_path
|
11
|
+
self.method_name = method_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"[##{self.method_name}] mock has not response defined for the given params. Verify the specs at \"#{self.file_path}\"."
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/spectro/mock.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
class Mock
|
4
|
+
|
5
|
+
# Creates a mock of the given method for the given file based
|
6
|
+
# on the spec rules.
|
7
|
+
# If mocks are not enabled it defaults to nil
|
8
|
+
#
|
9
|
+
# @param [String] file_path relative path of the file that requests the lambda
|
10
|
+
# @param [Symbol] method_name the method name that would be implemented
|
11
|
+
# @return [NilClass, Proc] the mock as Proc or nil if mocks are disabled
|
12
|
+
def self.create file_path, method_name
|
13
|
+
return nil unless Spectro::Config.mocks_enabled?
|
14
|
+
|
15
|
+
spec = Spectro::Spec::Parser.parse(file_path).detect do |spec|
|
16
|
+
spec.signature.name == method_name.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
param_names = Array.new(spec.signature.params_types.count) do |index|
|
20
|
+
('a'.ord+index).chr
|
21
|
+
end
|
22
|
+
|
23
|
+
responses = spec.rules.inject({}) do |memo, rule|
|
24
|
+
memo[rule.params] = rule.output
|
25
|
+
memo
|
26
|
+
end
|
27
|
+
|
28
|
+
return eval "
|
29
|
+
lambda do |#{param_names.join(',')}|
|
30
|
+
if !responses.has_key?([#{param_names.join(',')}])
|
31
|
+
raise Spectro::Exception::UnknownMockResponse.new(file_path, method_name)
|
32
|
+
end
|
33
|
+
|
34
|
+
return responses[[#{param_names.join(',')}]]
|
35
|
+
end
|
36
|
+
"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/spectro/spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spectro/spec/parser'
|
2
|
+
require 'spectro/spec/rule'
|
3
|
+
require 'spectro/spec/signature'
|
4
|
+
|
5
|
+
module Spectro
|
6
|
+
|
7
|
+
class Spec
|
8
|
+
|
9
|
+
attr_accessor :md5, :rules, :signature
|
10
|
+
|
11
|
+
# @param [String] spec md5
|
12
|
+
# @param [Spectro::Spec::Signature] signature spec signature
|
13
|
+
# @param [<Spectro::Spec::Rule>] rules collection of spec rules
|
14
|
+
def initialize md5, signature, rules
|
15
|
+
self.md5 = md5
|
16
|
+
self.rules = rules
|
17
|
+
self.signature = signature
|
18
|
+
end
|
19
|
+
|
20
|
+
def == spec
|
21
|
+
return \
|
22
|
+
self.signature == spec.signature && \
|
23
|
+
self.rules == spec.rules
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spectro'
|
2
|
+
|
3
|
+
module Spectro
|
4
|
+
|
5
|
+
class Spec
|
6
|
+
|
7
|
+
# Parser to get Spectro::Spec instances from the metadata on the program's files
|
8
|
+
class Parser
|
9
|
+
|
10
|
+
attr_accessor :file_path
|
11
|
+
|
12
|
+
# @param [String] file_path the path of the file to parse
|
13
|
+
def initialize file_path
|
14
|
+
self.file_path = file_path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create an instance of Spectro::Spec::Parser for the given file path
|
18
|
+
# and return the #parse response (the collection of Spectro::Spec instances
|
19
|
+
# for the given file)
|
20
|
+
#
|
21
|
+
# @param [String] file_path the path of the file to parse
|
22
|
+
# @return [<Spectro::Spec>] collection of specs found in the given file path
|
23
|
+
def self.parse(file_path)
|
24
|
+
Spectro::Spec::Parser.new(file_path).parse
|
25
|
+
end
|
26
|
+
|
27
|
+
# Look for specs on the given file and parse them as Spectro::Specs
|
28
|
+
#
|
29
|
+
# @return [<Spectro::Spec>] collection of specs found in the given file path
|
30
|
+
def parse
|
31
|
+
/.*^__END__$(?<raw_specs>.*)\Z/m =~ File.read(self.file_path)
|
32
|
+
return raw_specs.split('spec_for')[1..-1].map do |raw_spec|
|
33
|
+
self.parse_spec raw_spec
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Parses a raw spec and returns an Spectro::Spec instance
|
38
|
+
#
|
39
|
+
# @param [String] raw_spec raw spec
|
40
|
+
# @return [Spectro::Spec] the Spectro::Spec instance
|
41
|
+
def parse_spec raw_spec
|
42
|
+
spec_raw_signature, *spec_raw_rules = raw_spec.split("\n").reject(&:empty?)
|
43
|
+
|
44
|
+
spec_signature = self.parse_spec_signature(spec_raw_signature)
|
45
|
+
|
46
|
+
spec_rules = spec_raw_rules.map do |spec_raw_rule|
|
47
|
+
self.parse_spec_rule(spec_raw_rule)
|
48
|
+
end
|
49
|
+
|
50
|
+
spec_md5 = Digest::MD5.hexdigest(raw_spec)
|
51
|
+
|
52
|
+
return Spectro::Spec.new(spec_md5, spec_signature, spec_rules)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns a Spectro::Spec::Rule instance from the raw spec rule
|
56
|
+
#
|
57
|
+
# @param [String] spec_raw_rule raw rule if the spec
|
58
|
+
# @return [Spectro::Spec::Rule]
|
59
|
+
def parse_spec_rule spec_raw_rule
|
60
|
+
# REGEX HERE PLEASE, F%#&!@* EASY
|
61
|
+
raw_params, raw_output = spec_raw_rule.split('->').map(&:strip)
|
62
|
+
output = eval(raw_output)
|
63
|
+
params = raw_params.split(/,\s+/).map do |raw_param|
|
64
|
+
eval(raw_param)
|
65
|
+
end
|
66
|
+
|
67
|
+
return Spectro::Spec::Rule.new(params, output)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns a Spectro::Spec::Signature from the raw spec signature
|
71
|
+
#
|
72
|
+
# @param [String] spec_raw_signature raw signature of the spec
|
73
|
+
# @param [<Spectro::Spec::Signature]
|
74
|
+
def parse_spec_signature spec_raw_signature
|
75
|
+
# REGEX HERE PLEASE, F%#&!@* EASY
|
76
|
+
raw_name_and_params_types, output_type = spec_raw_signature.split('->').map(&:strip)
|
77
|
+
name, *params_types = raw_name_and_params_types.split(/,?\s+/).map(&:strip)
|
78
|
+
|
79
|
+
return Spectro::Spec::Signature.new(name, params_types, output_type)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
class Spec
|
4
|
+
|
5
|
+
# Assert representation based on input params and an expected output.
|
6
|
+
# Meant to be used against an algorith to test its behavior.
|
7
|
+
class Rule
|
8
|
+
|
9
|
+
attr_accessor :output, :params
|
10
|
+
|
11
|
+
# @param [<Object>] parmas set of input params
|
12
|
+
# @param [<Object>] output expected result
|
13
|
+
def initialize params, output
|
14
|
+
self.output = output
|
15
|
+
self.params = params
|
16
|
+
end
|
17
|
+
|
18
|
+
def == rule
|
19
|
+
return \
|
20
|
+
self.output == rule.output && \
|
21
|
+
self.params == rule.params
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Spectro
|
2
|
+
|
3
|
+
class Spec
|
4
|
+
|
5
|
+
# Representation of the required input/output types
|
6
|
+
class Signature
|
7
|
+
|
8
|
+
attr_accessor :name, :output_type, :params_types
|
9
|
+
|
10
|
+
# @param [String] name local name of the algorith (not sure if needed)
|
11
|
+
# @param [<String>] param_types types of the expected input params
|
12
|
+
# @param [String] output_type type of the expected output
|
13
|
+
def initialize name, params_types, output_type
|
14
|
+
self.name = name
|
15
|
+
self.output_type = output_type
|
16
|
+
self.params_types = params_types
|
17
|
+
end
|
18
|
+
|
19
|
+
def == signature
|
20
|
+
return \
|
21
|
+
self.name == signature.name && \
|
22
|
+
self.output_type == signature.output_type && \
|
23
|
+
self.params_types == signature.params_types
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spectro
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roberto Decurnex
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
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: codeclimate-test-reporter
|
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
|
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: guard-rake
|
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
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description:
|
112
|
+
email: decurnex.roberto@gmail.com
|
113
|
+
executables:
|
114
|
+
- spectro
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files:
|
117
|
+
- README.md
|
118
|
+
files:
|
119
|
+
- README.md
|
120
|
+
- bin/spectro
|
121
|
+
- lib/spectro.rb
|
122
|
+
- lib/spectro/client.rb
|
123
|
+
- lib/spectro/compiler.rb
|
124
|
+
- lib/spectro/config.rb
|
125
|
+
- lib/spectro/database.rb
|
126
|
+
- lib/spectro/exception.rb
|
127
|
+
- lib/spectro/exception/undefined_method_definition.rb
|
128
|
+
- lib/spectro/exception/unknown_mock_response.rb
|
129
|
+
- lib/spectro/mock.rb
|
130
|
+
- lib/spectro/spec.rb
|
131
|
+
- lib/spectro/spec/parser.rb
|
132
|
+
- lib/spectro/spec/rule.rb
|
133
|
+
- lib/spectro/spec/signature.rb
|
134
|
+
homepage: http://github.com/robertodecurnex/spectro
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: 2.0.0
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.4.5
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Specs driven social meta-programming
|
158
|
+
test_files: []
|
159
|
+
has_rdoc:
|