dynamic_parser 0.0.0.pre.5
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/.env.sample +2 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +3 -0
- data/Gemfile +20 -0
- data/LICENSE +5 -0
- data/Rakefile +17 -0
- data/Readme.md +119 -0
- data/dynamic_parser.gemspec +35 -0
- data/lib/dynamic_parser/micro_parser.rb +4 -0
- data/lib/dynamic_parser/micro_parsers/stateful.rb +24 -0
- data/lib/dynamic_parser/micro_parsers/stateless.rb +15 -0
- data/lib/dynamic_parser/parser.rb +38 -0
- data/lib/dynamic_parser/regex_cache.rb +29 -0
- data/lib/dynamic_parser/version.rb +10 -0
- data/lib/dynamic_parser.rb +38 -0
- data/spec/dynamic_parser/composite_parser_spec.rb +51 -0
- data/spec/dynamic_parser/dynamic_parser_spec.rb +8 -0
- data/spec/dynamic_parser/regex_cache_spec.rb +43 -0
- data/spec/dynamic_parser/stateful_parser_spec.rb +30 -0
- data/spec/dynamic_parser/stateless_parser_spec.rb +27 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/composite_parser.rb +6 -0
- data/spec/support/stateful_parser.rb +32 -0
- data/spec/support/stateless_parser.rb +17 -0
- data/tmp/.keep +0 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 668b59c691f0ece7f5d016d3bb331be4a6c091c3
|
4
|
+
data.tar.gz: 20867ccb02b864d02279363c017de1a807495317
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6605d86ec4a72a7d0ceb616393e4d5e94e9afffb40318cfa866dea5a81a0ff8a734f7a62ac5eb8449e8d06813dcc3aa160726435afc533d21bb7ce6c8b23f1ca
|
7
|
+
data.tar.gz: 855ed95b2776315aebd83c0279e9af6130fb3e7e9b30a7f4c2e535fb3c6b824af78bc45ce20429535522541bc7c3136d27f8b9ad90f05d3ed02efdcecc291393
|
data/.env.sample
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format documentation
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/.yardopts
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rubysl', platform: :rbx
|
4
|
+
gem 'yajl-ruby', :platforms=>[:rbx,:ruby]
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'dotenv'
|
8
|
+
gem 'rake'
|
9
|
+
gem 'pry'
|
10
|
+
gem 'pry-nav'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem 'rspec'
|
15
|
+
gem 'rspec-mocks'
|
16
|
+
gem 'rspec-expectations'
|
17
|
+
gem 'factory_girl', github: 'thoughtbot/factory_girl'
|
18
|
+
gem 'yard'
|
19
|
+
gem "codeclimate-test-reporter", require: nil
|
20
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
Copyright (c) Leghoo.com
|
2
|
+
|
3
|
+
Dynamic Parser is intellectual property of Leghoo.com, and it source should not be published in any way - partially or otherwise - unless by explicit written authorization.
|
4
|
+
|
5
|
+
As intellectual property, if falls under the Non-Disclosure Agreement rules.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
RSpec::Core::RakeTask.new
|
6
|
+
|
7
|
+
task :default => :console
|
8
|
+
|
9
|
+
task :environment do
|
10
|
+
require './spec/spec_helper'
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'Opens a Pry/IRB session with the environment loaded'
|
14
|
+
task :console => :environment do
|
15
|
+
#gotcha!
|
16
|
+
binding.pry
|
17
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
[](https://codeclimate.com/github/lucasmartins/dynamic_parser) [](https://codeclimate.com/github/lucasmartins/dynamic_parser) [ ](https://codeship.io/projects/24259)
|
2
|
+
|
3
|
+
Dynamic Parser
|
4
|
+
==============
|
5
|
+
|
6
|
+
**IN PROGRESS**
|
7
|
+
|
8
|
+
Install
|
9
|
+
=======
|
10
|
+
|
11
|
+
Just add it to your Gemfile - not really
|
12
|
+
```ruby
|
13
|
+
gem 'dynamic_parser', github: 'agentevirtual/dynamic_parser'
|
14
|
+
```
|
15
|
+
|
16
|
+
Use
|
17
|
+
===
|
18
|
+
|
19
|
+
Your Dynamic Parser may be a composite of both `Stateless` and `Stateful` parsers. To build a composite/dynamic paser, first you need one or more `MicroParsers`.
|
20
|
+
|
21
|
+
The following samples will expect a text/String as the received artifact to be parsed, but you're free to use any kind of object/content.
|
22
|
+
|
23
|
+
## Stateless MicroParser
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# parses the artifact statically
|
27
|
+
class StatelessParser
|
28
|
+
include DynamicParser::MicroParser::Stateless
|
29
|
+
|
30
|
+
def self.detect(txt)
|
31
|
+
txt.include?('static')
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.parse(txt)
|
35
|
+
tokens = []
|
36
|
+
txt.split(' ').each_with_index do |piece, i|
|
37
|
+
tokens.push OpenStruct.new(index: i, content: piece)
|
38
|
+
end
|
39
|
+
tokens
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
## Stateful MicroParser
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class StatefulParser
|
48
|
+
include DynamicParser::MicroParser::Stateful
|
49
|
+
def initialize
|
50
|
+
@data = []
|
51
|
+
end
|
52
|
+
|
53
|
+
def detect(txt)
|
54
|
+
self.class.detect(txt)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.detect(txt)
|
58
|
+
if txt.match('stateful') == nil
|
59
|
+
false
|
60
|
+
else
|
61
|
+
true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def parse!(txt)
|
66
|
+
tokens = []
|
67
|
+
txt.split(' ').each_with_index do |piece, i|
|
68
|
+
@data.push OpenStruct.new(index: i, content: piece)
|
69
|
+
end
|
70
|
+
# you could be doing some IO here, like writing to a file, database, http...
|
71
|
+
end
|
72
|
+
|
73
|
+
def gimme_data
|
74
|
+
@data
|
75
|
+
end
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
## Composite Parser
|
80
|
+
|
81
|
+
When running a composite parser, all `MicroParsers` found at `.micro_parsers` will be filtered through the `.detect` method, and then called `.parse`/`#parse`.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
class CompositeParser
|
85
|
+
include DynamicParser::Parser
|
86
|
+
def self.micro_parsers
|
87
|
+
[StatefulParser, StatelessParser]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
# run you dynamic parser
|
94
|
+
CompositeParser.parse do |micro_parser, output|
|
95
|
+
case
|
96
|
+
when micro_parser==StatelessParser
|
97
|
+
# do something with output here
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
Docs
|
103
|
+
====
|
104
|
+
You should check the [factories](https://github.com/leghoo/dynamic_parser/tree/master/spec/factories) to learn what you need to build your objects, and the [tests](https://github.com/leghoo/dynamic_parser/tree/master/spec/DynamicParser) to learn how to use them. But hey, we have docs [right here](http://rdoc.info/github/leghoo/dynamic_parser/master/frames).
|
105
|
+
|
106
|
+
Roadmap
|
107
|
+
=======
|
108
|
+
|
109
|
+
- ...;
|
110
|
+
|
111
|
+
Contribute
|
112
|
+
==========
|
113
|
+
|
114
|
+
Just fork [DynamicParser](https://github.com/leghoo/dynamic_parser), add your feature+spec, and make a pull request.
|
115
|
+
|
116
|
+
License
|
117
|
+
=======
|
118
|
+
|
119
|
+
Please see [LICENSE](https://github.com/leghoo/dynamic_parser/blob/master/LICENSE) for licensing details.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dynamic_parser/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dynamic_parser"
|
7
|
+
s.version = DynamicParser::Version::STRING
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.required_ruby_version = ">= 2.1.0"
|
10
|
+
s.authors = ["Lucas Martins"]
|
11
|
+
s.email = ["lucasmartins@railsnapraia.com"]
|
12
|
+
s.homepage = "https://github.com/leghoo/dynamic_parser"
|
13
|
+
s.summary = "An interchangeble parser builder for Ruby"
|
14
|
+
s.description = s.summary
|
15
|
+
s.license = "LGPLv3"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
#s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
if RUBY_ENGINE=='rbx'
|
23
|
+
s.add_dependency 'rubysl'
|
24
|
+
end
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec", '2.14.1'
|
27
|
+
s.add_development_dependency "rspec-mocks", '2.14.4'
|
28
|
+
s.add_development_dependency "rspec-expectations", '2.14.4'
|
29
|
+
s.add_development_dependency "factory_girl", '4.4.0'
|
30
|
+
s.add_development_dependency "rake", '10.1.1'
|
31
|
+
s.add_development_dependency "pry", '0.9.12.4'
|
32
|
+
s.add_development_dependency "pry-nav", '0.2.3'
|
33
|
+
s.add_development_dependency "yard", '0.8.7.3'
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DynamicParser::MicroParser::Stateful
|
2
|
+
module ClassMethods
|
3
|
+
#This method must return true or false to tell if this MicroParser is responsible for parsing the given txt content.
|
4
|
+
def detect(txt)
|
5
|
+
true
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
#This method must return true or false to tell if this MicroParser is responsible for parsing the given txt content.
|
11
|
+
def detect(txt)
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse!(txt)
|
16
|
+
raise 'This method must parse the given content - statefully - and is not expected to return any value.'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.included(receiver)
|
21
|
+
receiver.extend ClassMethods
|
22
|
+
receiver.include InstanceMethods
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DynamicParser::MicroParser::Stateless
|
2
|
+
module ClassMethods
|
3
|
+
def detect(txt)
|
4
|
+
raise 'This method must return true or false to tell if this MicroParser is responsible for parsing the given txt content.'
|
5
|
+
end
|
6
|
+
|
7
|
+
def parse(txt)
|
8
|
+
raise 'This method must parse the given content - statelessly - and return the parsing result, if any.'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(receiver)
|
13
|
+
receiver.extend ClassMethods
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module DynamicParser::Parser
|
2
|
+
module ClassMethods
|
3
|
+
#filters the microparsers list for the given content
|
4
|
+
def build(txt)
|
5
|
+
parsers = []
|
6
|
+
self.micro_parsers.each do |parser|
|
7
|
+
parsers << parser if parser.detect(txt)
|
8
|
+
end
|
9
|
+
parsers
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse(txt, &block)
|
13
|
+
parsers = build(txt)
|
14
|
+
parsers.each do |micro_parser|
|
15
|
+
if micro_parser.ancestors.include?(DynamicParser::MicroParser::Stateful)
|
16
|
+
micro_parser.new.parse!(txt)
|
17
|
+
elsif micro_parser.ancestors.include?(DynamicParser::MicroParser::Stateless)
|
18
|
+
if block_given?
|
19
|
+
block.call(micro_parser, micro_parser.parse(txt))
|
20
|
+
else
|
21
|
+
raise 'You must give a block for Stateless parsers'
|
22
|
+
end
|
23
|
+
else
|
24
|
+
raise "#{micro_parser} is not a valid MicroParser!"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
parsers.size
|
28
|
+
end
|
29
|
+
|
30
|
+
def micro_parsers
|
31
|
+
raise 'This method should return an Array of MicroParsers'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.included(receiver)
|
36
|
+
receiver.extend ClassMethods
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module DynamicParser::RegexCache
|
4
|
+
|
5
|
+
def self.match(regex, txt, &block)
|
6
|
+
raise 'you must specify a block' unless block_given?
|
7
|
+
retrieved_data = fetch("#{digest(regex.to_s)}/#{digest(txt)}") do
|
8
|
+
matched = txt.match(regex)
|
9
|
+
block.call(matched)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
def self.fetch(key, expiration=300, &block)
|
15
|
+
raise 'you must specify a block' unless block_given?
|
16
|
+
if defined?(Rails)
|
17
|
+
Rails.cache.fetch(key, :expires_in => expiration) do
|
18
|
+
block.call
|
19
|
+
end
|
20
|
+
else
|
21
|
+
puts "[DynamicParser] No known driver available for caching!"
|
22
|
+
@cache ||= block.call
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.digest(s)
|
27
|
+
Digest::MD5.hexdigest(s)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
begin
|
2
|
+
require 'dotenv'
|
3
|
+
Dotenv.load
|
4
|
+
rescue LoadError => e
|
5
|
+
puts "dotenv is not available"
|
6
|
+
end
|
7
|
+
require 'bundler'
|
8
|
+
|
9
|
+
Encoding.default_internal = "utf-8"
|
10
|
+
Encoding.default_external = "utf-8"
|
11
|
+
|
12
|
+
module DynamicParser
|
13
|
+
require_relative 'dynamic_parser/regex_cache'
|
14
|
+
require_relative 'dynamic_parser/micro_parser'
|
15
|
+
require_relative 'dynamic_parser/parser'
|
16
|
+
require_relative 'dynamic_parser/version'
|
17
|
+
|
18
|
+
# alias method
|
19
|
+
def logger
|
20
|
+
DynamicParser.logger
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the lib logger object
|
24
|
+
def self.logger
|
25
|
+
@logger || initialize_logger
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initializes logger with DynamicParser setup
|
29
|
+
def self.initialize_logger(log_target = STDOUT)
|
30
|
+
oldlogger = @logger
|
31
|
+
@logger = Logger.new(log_target)
|
32
|
+
@logger.level = Logger::INFO
|
33
|
+
@logger.progname = 'dynamic_parser'
|
34
|
+
oldlogger.close if oldlogger && !$TESTING # don't want to close testing's STDOUT logging
|
35
|
+
@logger
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CompositeParser do
|
4
|
+
let(:parser) { CompositeParser }
|
5
|
+
let(:content_to_parse_statefully) { 'Parse me statefully!' }
|
6
|
+
let(:content_to_parse_statically) { 'Parse me statically!' }
|
7
|
+
let(:content_to_parse) { 'Parse me statefully! Parse me statically!' }
|
8
|
+
|
9
|
+
describe '.build' do
|
10
|
+
it 'builds a microparser Array for the static parser' do
|
11
|
+
expect(parser.build(content_to_parse_statefully)).to eq([StatefulParser])
|
12
|
+
end
|
13
|
+
it 'builds a microparser Array for the stateful parser' do
|
14
|
+
expect(parser.build(content_to_parse_statically)).to eq([StatelessParser])
|
15
|
+
end
|
16
|
+
it 'builds a microparser Array for the both parsers' do
|
17
|
+
expect(parser.build(content_to_parse)).to match_array([StatelessParser,StatefulParser])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.parse' do
|
22
|
+
context 'stateful only' do
|
23
|
+
it 'parses the content returning the number of MicroParsers involved' do
|
24
|
+
expect(parser.parse(content_to_parse_statefully)).to eq(1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'static only' do
|
29
|
+
it 'raises error when no block given' do
|
30
|
+
expect{parser.parse(content_to_parse_statically)}.to raise_error
|
31
|
+
end
|
32
|
+
it 'parses the content and runs the given block' do
|
33
|
+
parser.parse(content_to_parse_statically) do |parser, result|
|
34
|
+
expect(parser).to eq(StatelessParser)
|
35
|
+
expect(result.to_s).to eq("[#<OpenStruct index=0, content=\"Parse\">, #<OpenStruct index=1, content=\"me\">, #<OpenStruct index=2, content=\"statically!\">]")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'static & stateful' do
|
41
|
+
it 'parses the content and runs the given block' do
|
42
|
+
parser.parse(content_to_parse) do |parser, result|
|
43
|
+
expect(parser).to eq(StatelessParser)
|
44
|
+
expect(result.to_s).to eq("[#<OpenStruct index=0, content=\"Parse\">, #<OpenStruct index=1, content=\"me\">, #<OpenStruct index=2, content=\"statefully!\">, #<OpenStruct index=3, content=\"Parse\">, #<OpenStruct index=4, content=\"me\">, #<OpenStruct index=5, content=\"statically!\">]")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DynamicParser::RegexCache do
|
4
|
+
|
5
|
+
describe '.match' do
|
6
|
+
it 'runs without a cache driver' do
|
7
|
+
expect do
|
8
|
+
DynamicParser::RegexCache.match(/txt/,'txt') do |matched|
|
9
|
+
matched.to_s
|
10
|
+
end
|
11
|
+
end.not_to raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns the expect content' do
|
15
|
+
expect(
|
16
|
+
DynamicParser::RegexCache.match(/txt/,'some txt content') do |matched|
|
17
|
+
matched.to_s
|
18
|
+
end
|
19
|
+
).to eq('txt')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'caches the expect content' do
|
23
|
+
class Dummy
|
24
|
+
def self.call
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
Dummy.should_receive(:call).once
|
29
|
+
|
30
|
+
DynamicParser::RegexCache.match(/txt/,'some txt content') do |matched|
|
31
|
+
Dummy.call
|
32
|
+
matched.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
DynamicParser::RegexCache.match(/txt/,'some txt content') do |matched|
|
36
|
+
Dummy.call
|
37
|
+
matched.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StatefulParser do
|
4
|
+
let(:parser) { StatefulParser.new }
|
5
|
+
let(:content_to_parse) { 'Parse me statefully!' }
|
6
|
+
let(:content_to_reject) { 'Do not parse this!' }
|
7
|
+
|
8
|
+
describe ".detect" do
|
9
|
+
context 'parseable content' do
|
10
|
+
it "returns true" do
|
11
|
+
expect(parser.detect(content_to_parse)).to eq(true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context 'rejectable content' do
|
15
|
+
it "returns false" do
|
16
|
+
expect(parser.detect(content_to_reject)).to eq(false)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#parse' do
|
22
|
+
before(:each) do
|
23
|
+
parser.parse!(content_to_parse)
|
24
|
+
end
|
25
|
+
it 'parses the content properly' do
|
26
|
+
expect(parser.gimme_data.to_s).to eq("[#<OpenStruct index=0, content=\"Parse\">, #<OpenStruct index=1, content=\"me\">, #<OpenStruct index=2, content=\"statefully!\">]")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe StatelessParser do
|
4
|
+
let(:parser) { StatelessParser }
|
5
|
+
let(:content_to_parse) { 'Parse me statically!' }
|
6
|
+
let(:content_to_reject) { 'Do not parse this!' }
|
7
|
+
|
8
|
+
describe ".detect" do
|
9
|
+
context 'parseable content' do
|
10
|
+
it "returns true" do
|
11
|
+
expect(parser.detect(content_to_parse)).to eq(true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context 'rejectable content' do
|
15
|
+
it "returns false" do
|
16
|
+
expect(parser.detect(content_to_reject)).to eq(false)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.parse' do
|
22
|
+
it 'parses the content properly returning its product' do
|
23
|
+
expect(parser.parse(content_to_parse).to_s).to eq("[#<OpenStruct index=0, content=\"Parse\">, #<OpenStruct index=1, content=\"me\">, #<OpenStruct index=2, content=\"statically!\">]")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
require 'pry'
|
4
|
+
require 'pry-nav'
|
5
|
+
require 'dynamic_parser'
|
6
|
+
require 'rspec'
|
7
|
+
require 'rspec/mocks'
|
8
|
+
require 'rspec/expectations'
|
9
|
+
require "pathname"
|
10
|
+
require 'factory_girl'
|
11
|
+
|
12
|
+
if ENV['TRAVIS']==true
|
13
|
+
begin
|
14
|
+
require 'coveralls'
|
15
|
+
Coveralls.wear!
|
16
|
+
rescue Exception => e
|
17
|
+
puts "Coveralls not available!"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
SPECDIR = Pathname.new(File.dirname(__FILE__))
|
22
|
+
TMPDIR = SPECDIR.join("tmp")
|
23
|
+
|
24
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|r| require r}
|
25
|
+
Dir[File.dirname(__FILE__) + "/factories/**/*.rb"].each {|r| require r}
|
26
|
+
|
27
|
+
RSpec.configure do |config|
|
28
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
29
|
+
config.order = :random
|
30
|
+
config.include FactoryGirl::Syntax::Methods
|
31
|
+
config.before { FileUtils.mkdir_p(TMPDIR) }
|
32
|
+
config.mock_with :rspec
|
33
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
class StatefulParser
|
4
|
+
include DynamicParser::MicroParser::Stateful
|
5
|
+
def initialize
|
6
|
+
@data = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def detect(txt)
|
10
|
+
self.class.detect(txt)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.detect(txt)
|
14
|
+
if txt.match('stateful') == nil
|
15
|
+
false
|
16
|
+
else
|
17
|
+
true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse!(txt)
|
22
|
+
tokens = []
|
23
|
+
txt.split(' ').each_with_index do |piece, i|
|
24
|
+
@data.push OpenStruct.new(index: i, content: piece)
|
25
|
+
end
|
26
|
+
# you could be doing some IO here, like writing to a file, database, http...
|
27
|
+
end
|
28
|
+
|
29
|
+
def gimme_data
|
30
|
+
@data
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
class StatelessParser
|
4
|
+
include DynamicParser::MicroParser::Stateless
|
5
|
+
|
6
|
+
def self.detect(txt)
|
7
|
+
txt.include?('static')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse(txt)
|
11
|
+
tokens = []
|
12
|
+
txt.split(' ').each_with_index do |piece, i|
|
13
|
+
tokens.push OpenStruct.new(index: i, content: piece)
|
14
|
+
end
|
15
|
+
tokens
|
16
|
+
end
|
17
|
+
end
|
data/tmp/.keep
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamic_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0.pre.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lucas Martins
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.14.1
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.14.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-mocks
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.14.4
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.14.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-expectations
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.14.4
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.14.4
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: factory_girl
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.4.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.4.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 10.1.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 10.1.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.9.12.4
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.9.12.4
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-nav
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.2.3
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.2.3
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: yard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.8.7.3
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.8.7.3
|
125
|
+
description: An interchangeble parser builder for Ruby
|
126
|
+
email:
|
127
|
+
- lucasmartins@railsnapraia.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".env.sample"
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".ruby-version"
|
136
|
+
- ".yardopts"
|
137
|
+
- Gemfile
|
138
|
+
- LICENSE
|
139
|
+
- Rakefile
|
140
|
+
- Readme.md
|
141
|
+
- dynamic_parser.gemspec
|
142
|
+
- lib/dynamic_parser.rb
|
143
|
+
- lib/dynamic_parser/micro_parser.rb
|
144
|
+
- lib/dynamic_parser/micro_parsers/stateful.rb
|
145
|
+
- lib/dynamic_parser/micro_parsers/stateless.rb
|
146
|
+
- lib/dynamic_parser/parser.rb
|
147
|
+
- lib/dynamic_parser/regex_cache.rb
|
148
|
+
- lib/dynamic_parser/version.rb
|
149
|
+
- spec/dynamic_parser/composite_parser_spec.rb
|
150
|
+
- spec/dynamic_parser/dynamic_parser_spec.rb
|
151
|
+
- spec/dynamic_parser/regex_cache_spec.rb
|
152
|
+
- spec/dynamic_parser/stateful_parser_spec.rb
|
153
|
+
- spec/dynamic_parser/stateless_parser_spec.rb
|
154
|
+
- spec/spec_helper.rb
|
155
|
+
- spec/support/composite_parser.rb
|
156
|
+
- spec/support/stateful_parser.rb
|
157
|
+
- spec/support/stateless_parser.rb
|
158
|
+
- tmp/.keep
|
159
|
+
homepage: https://github.com/leghoo/dynamic_parser
|
160
|
+
licenses:
|
161
|
+
- LGPLv3
|
162
|
+
metadata: {}
|
163
|
+
post_install_message:
|
164
|
+
rdoc_options: []
|
165
|
+
require_paths:
|
166
|
+
- lib
|
167
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 2.1.0
|
172
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - ">"
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: 1.3.1
|
177
|
+
requirements: []
|
178
|
+
rubyforge_project:
|
179
|
+
rubygems_version: 2.2.2
|
180
|
+
signing_key:
|
181
|
+
specification_version: 4
|
182
|
+
summary: An interchangeble parser builder for Ruby
|
183
|
+
test_files:
|
184
|
+
- spec/dynamic_parser/composite_parser_spec.rb
|
185
|
+
- spec/dynamic_parser/dynamic_parser_spec.rb
|
186
|
+
- spec/dynamic_parser/regex_cache_spec.rb
|
187
|
+
- spec/dynamic_parser/stateful_parser_spec.rb
|
188
|
+
- spec/dynamic_parser/stateless_parser_spec.rb
|
189
|
+
- spec/spec_helper.rb
|
190
|
+
- spec/support/composite_parser.rb
|
191
|
+
- spec/support/stateful_parser.rb
|
192
|
+
- spec/support/stateless_parser.rb
|
193
|
+
has_rdoc:
|