spectro 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://api.travis-ci.org/robertodecurnex/spectro.png)](https://travis-ci.org/robertodecurnex/spectro)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/robertodecurnex/spectro/badges/gpa.svg)](https://codeclimate.com/github/robertodecurnex/spectro)
|
7
|
+
[![Test Coverage](https://codeclimate.com/github/robertodecurnex/spectro/badges/coverage.svg)](https://codeclimate.com/github/robertodecurnex/spectro)
|
8
|
+
[![YARD Docs](https://img.shields.io/badge/YARD-Docs-blue.svg)](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:
|