stars 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,79 @@
1
+ #{"title"=>"6 stars: Why can't we hardware-accelerate animated gifs? I thought this was the future.", "pubDate"=>"Wed, 16 Feb 2011 05:56:32 +0000", "guid"=>"http://favstar.fm/users/holman/status/37752168152825856?6", "description"=>"Has been faved by 6 people<br /><br /><a href=\"http://favstar.fm/users/holman/status/37752168152825856\">This tweet</a>&nbsp;&nbsp;&nbsp;<a href=\"http://favstar.fm/users/holman/recent\">All Recent</a>", "link"=>"http://favstar.fm/users/holman/status/37752168152825856"}
2
+
3
+ module Stars
4
+ class Favstar < Service
5
+
6
+ base_uri 'favstar.fm'
7
+
8
+ attr_reader :posts
9
+
10
+ def name
11
+ "favstar"
12
+ end
13
+
14
+ def posts
15
+ parse_xml
16
+ @posts
17
+ end
18
+
19
+ def xml_feed
20
+ self.class.get("/users/#{username}/rss",
21
+ :format => :xml)['rss']['channel']['item']
22
+ end
23
+
24
+ def parse_xml
25
+ @posts = []
26
+
27
+ xml_feed.each do |xml|
28
+ @posts << parse_post(xml)
29
+ end
30
+ end
31
+
32
+ def parse_post(xml)
33
+ title = xml["title"]
34
+ Post.new(:name => parse_title(title),
35
+ :url => xml["guid"],
36
+ :service => name,
37
+ :date => DateTime.parse(xml["pubDate"]),
38
+ :stars_count => parse_stars(title))
39
+ end
40
+
41
+ # Parse the title from a Favstar RSS title.
42
+ #
43
+ # title - a Favstar-formatted String (x stars: title here)
44
+ #
45
+ # This splits on the first colon, and then use everything after that. To
46
+ # account for tweets with colons in them, we have to strip the first ": "
47
+ # String we find, and then shift the String back two characters.
48
+ def parse_title(title)
49
+ strip = title.split(':').first
50
+ title = title.gsub(strip,'')
51
+ title = title[2..-1] if title[0..1] == ": "
52
+ title
53
+ end
54
+
55
+ def parse_stars(title)
56
+ title.match(/[\d]+/)[0].to_i
57
+ end
58
+
59
+ def self.more(post)
60
+ # hardcode 17 to strip favstar domain for now
61
+ html = get(post.url[17..200], :format => :html)
62
+
63
+ output = ''
64
+
65
+ Nokogiri::HTML(html).css('div[id^="faved_by_others"] img').collect do |img|
66
+ output << " ★ #{img.attributes['alt'].value}\n"
67
+ end
68
+
69
+ Nokogiri::HTML(html).css('div[id^="rt_by_others"] img').collect do |img|
70
+ output << " RT #{img.attributes['alt'].value}\n"
71
+ end
72
+
73
+ output << "\n"
74
+ output << "More info at:\n"
75
+ output << " #{post.url}\n\n"
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,32 @@
1
+ module Stars
2
+ class Service
3
+ # Each Service is a party.
4
+ include HTTParty
5
+
6
+ # Returns a String name of the Service.
7
+ #
8
+ # We'll display this across Stars to identify this service.
9
+ def name ; end
10
+
11
+ def username
12
+ Stars.config.username(name)
13
+ end
14
+
15
+ # Returns an Array of Posts.
16
+ #
17
+ # This method — to be overriden by individual Service classes — returns an
18
+ # Array of Post items. Items in each Post should be associated with
19
+ # individual Star objects, so we can quickly iterate over a Post's Stars.
20
+ def posts ; end
21
+
22
+ def self.more(post) ; end
23
+
24
+ # Initializes a instance and returns the Posts.
25
+ #
26
+ # Creates a new instance of the Service and returns an Array of Post
27
+ # objects.
28
+ def self.posts
29
+ self.new.posts
30
+ end
31
+ end
32
+ end
data/lib/stars.rb CHANGED
@@ -1,8 +1,39 @@
1
- module Stars ; end
2
-
3
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/stars')
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
2
 
3
+ require 'date'
4
+ require 'fileutils'
5
5
  require 'httparty'
6
- require 'client'
7
- require 'favstar'
8
- require 'formatter'
6
+ require 'keep'
7
+ require 'nokogiri'
8
+ require 'open-uri'
9
+ require 'terminal-table/import'
10
+
11
+ require 'stars/client'
12
+ require 'stars/config'
13
+ require 'stars/post'
14
+
15
+ require 'stars/core_ext/string'
16
+
17
+ require 'stars/services/service'
18
+ require 'stars/services/convore'
19
+ require 'stars/services/favstar'
20
+
21
+ module Stars
22
+ VERSION = '0.5.0'
23
+
24
+ def self.config
25
+ @config ||= Config.new
26
+ end
27
+
28
+ def self.services
29
+ %w(favstar convore)
30
+ end
31
+
32
+ def self.installed_services
33
+ config.keep.keys
34
+ end
35
+
36
+ def self.uninstalled_services
37
+ services - installed_services
38
+ end
39
+ end
data/stars.gemspec CHANGED
@@ -1,72 +1,92 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
1
+ ## This is the rakegem gemspec template. Make sure you read and understand
2
+ ## all of the comments. Some sections require modification, and others can
3
+ ## be deleted if you don't need them. Once you understand the contents of
4
+ ## this file, feel free to delete any comments that begin with two hash marks.
5
+ ## You can find comprehensive Gem::Specification documentation, at
6
+ ## http://docs.rubygems.org/read/chapter/20
6
7
  Gem::Specification.new do |s|
7
- s.name = %q{stars}
8
- s.version = "0.4.0"
9
-
8
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
9
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Zach Holman"]
12
- s.date = %q{2010-12-24}
13
- s.default_executable = %q{stars}
14
- s.description = %q{Recent favstar faves on your command line.}
15
- s.email = %q{github.com@zachholman.com}
10
+ s.rubygems_version = '1.3.5'
11
+
12
+ ## Leave these as is they will be modified for you by the rake gemspec task.
13
+ ## If your rubyforge_project name is different, then edit it and comment out
14
+ ## the sub! line in the Rakefile
15
+ s.name = 'stars'
16
+ s.version = '0.5.0'
17
+ s.date = '2011-04-18'
18
+ s.rubyforge_project = 'stars'
19
+
20
+ ## Make sure your summary is short. The description may be as long
21
+ ## as you like.
22
+ s.summary = "Recent stars on your command line."
23
+ s.description = "Twitter stars, Convore stars. On the command line."
24
+
25
+ ## List the primary authors. If there are a bunch of authors, it's probably
26
+ ## better to set the email to an email list or something. If you don't have
27
+ ## a custom homepage, consider using your GitHub URL or the like.
28
+ s.authors = ["Zach Holman"]
29
+ s.email = 'github.com@zachholman.com'
30
+ s.homepage = 'https://github.com/holman/stars'
31
+
32
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
34
+ s.require_paths = %w[lib]
35
+
36
+ ## This sections is only necessary if you have C extensions.
37
+ #s.require_paths << 'ext'
38
+ #s.extensions = %w[ext/extconf.rb]
39
+
40
+ ## If your gem includes any executables, list them here.
16
41
  s.executables = ["stars"]
17
- s.extra_rdoc_files = [
18
- "LICENSE",
19
- "README.markdown"
20
- ]
21
- s.files = [
22
- ".document",
23
- ".gitignore",
24
- "LICENSE",
25
- "README.markdown",
26
- "Rakefile",
27
- "VERSION",
28
- "bin/stars",
29
- "lib/stars.rb",
30
- "lib/stars/client.rb",
31
- "lib/stars/favstar.rb",
32
- "lib/stars/formatter.rb",
33
- "stars.gemspec",
34
- "test/helper.rb",
35
- "test/test_client.rb",
36
- "test/test_favstar.rb",
37
- "test/test_formatter.rb",
38
- "test/test_stars.rb"
39
- ]
40
- s.homepage = %q{http://github.com/holman/stars}
42
+ s.default_executable = 'stars'
43
+
44
+ ## Specify any RDoc options here. You'll want to add your README and
45
+ ## LICENSE files to the extra_rdoc_files list.
41
46
  s.rdoc_options = ["--charset=UTF-8"]
42
- s.require_paths = ["lib"]
43
- s.rubygems_version = %q{1.3.7}
44
- s.summary = %q{Recent favstar faves on your command line}
45
- s.test_files = [
46
- "test/helper.rb",
47
- "test/test_client.rb",
48
- "test/test_favstar.rb",
49
- "test/test_formatter.rb",
50
- "test/test_stars.rb"
51
- ]
47
+ s.extra_rdoc_files = %w[README.markdown LICENSE]
52
48
 
53
- if s.respond_to? :specification_version then
54
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
- s.specification_version = 3
49
+ ## List your runtime dependencies here. Runtime dependencies are those
50
+ ## that are needed for an end user to actually USE your code.
51
+ s.add_dependency('httparty', [">= 0"])
52
+ s.add_dependency('terminal-table', [">= 0"])
53
+ s.add_dependency('nokogiri', [">= 0"])
54
+ s.add_dependency('keep', ["~> 0.0.3"])
56
55
 
57
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
- s.add_runtime_dependency(%q<httparty>, [">= 0"])
59
- s.add_runtime_dependency(%q<terminal-table>, [">= 0"])
60
- s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
61
- else
62
- s.add_dependency(%q<httparty>, [">= 0"])
63
- s.add_dependency(%q<terminal-table>, [">= 0"])
64
- s.add_dependency(%q<nokogiri>, [">= 0"])
65
- end
66
- else
67
- s.add_dependency(%q<httparty>, [">= 0"])
68
- s.add_dependency(%q<terminal-table>, [">= 0"])
69
- s.add_dependency(%q<nokogiri>, [">= 0"])
70
- end
71
- end
56
+ ## List your development dependencies here. Development dependencies are
57
+ ## those that are only needed during development
58
+ s.add_development_dependency('mocha', "~> 0.9.9")
59
+
60
+ ## Leave this section as-is. It will be automatically generated from the
61
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
62
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
63
+ # = MANIFEST =
64
+ s.files = %w[
65
+ Gemfile
66
+ Gemfile.lock
67
+ LICENSE
68
+ README.markdown
69
+ Rakefile
70
+ bin/stars
71
+ lib/stars.rb
72
+ lib/stars/client.rb
73
+ lib/stars/config.rb
74
+ lib/stars/core_ext/string.rb
75
+ lib/stars/post.rb
76
+ lib/stars/services/convore.rb
77
+ lib/stars/services/favstar.rb
78
+ lib/stars/services/service.rb
79
+ stars.gemspec
80
+ test/examples/stars.yml
81
+ test/helper.rb
82
+ test/test_client.rb
83
+ test/test_config.rb
84
+ test/test_favstar.rb
85
+ test/test_post.rb
86
+ ]
87
+ # = MANIFEST =
72
88
 
89
+ ## Test files will be grabbed from the file list. Make sure the path glob
90
+ ## matches what you actually use.
91
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
92
+ end
@@ -0,0 +1 @@
1
+ favstar: holman
data/test/helper.rb CHANGED
@@ -1,39 +1,22 @@
1
- require 'rubygems'
1
+ # coding: utf-8
2
+
2
3
  require 'test/unit'
3
- require 'rr'
4
4
 
5
5
  begin
6
+ require 'rubygems'
6
7
  require 'redgreen'
8
+ require 'leftright'
7
9
  rescue LoadError
8
10
  end
9
11
 
12
+ require 'mocha'
13
+
10
14
  $LOAD_PATH.unshift(File.dirname(__FILE__))
11
15
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+
12
17
  require 'stars'
13
18
 
14
- class Test::Unit::TestCase
15
-
16
- include RR::Adapters::TestUnit
17
-
18
- def favstar_tweet_hash
19
- [
20
- {
21
- "title"=>"2 stars: I pre-ordered an iPad, checked into lunch, and now you want me to follow someone just because it's Friday? I CAN'T KEEP UP WITH YOU GUYS",
22
- "pubDate"=>"Fri, 12 Mar 2010 20:43:40 +0000",
23
- "guid"=>"http://favstar.fm/users/holman/status/10389110831?2",
24
- "description"=>"Has been faved by 2 people<br /><br /><a href=\"http://favstar.fm/users/holman/status/10389110831\">This tweet</a>
25
- &nbsp;&nbsp;&nbsp;<a href=\"http://favstar.fm/users/holman/recent\">All Recent</a>",
26
- "link"=>"http://favstar.fm/users/holman/status/10389110831"
27
- },
28
- {
29
- "title"=>"1 star: In another life I want to be a pop star heartthrob who also codes Perl in his free time. That'll confuse those impressionable teen fangirls.",
30
- "pubDate"=>"Fri, 12 Mar 2010 20:13:46 +0000",
31
- "guid"=>"http://favstar.fm/users/holman/status/10387998839?1",
32
- "description"=>"Has been faved by 1 person<br /><br /><a href=\"http://favstar.fm/users/holman/status/10387998839\">This tweet</a>
33
- &nbsp;&nbsp;&nbsp;<a href=\"http://favstar.fm/users/holman/recent\">All Recent</a>",
34
- "link"=>"http://favstar.fm/users/holman/status/10387998839"
35
- }
36
- ]
37
- end
38
-
19
+ def global_setup
20
+ Stars::Config.any_instance.stubs(:config_path).
21
+ returns("test/examples/stars.yml")
39
22
  end
data/test/test_client.rb CHANGED
@@ -1,43 +1,26 @@
1
1
  require 'helper'
2
2
 
3
+ module Kernel
4
+ def system(s) ; end
5
+ def puts(s) ; end
6
+ end
7
+
3
8
  class TestClient < Test::Unit::TestCase
4
9
 
5
- def test_load_with_username
6
- mock(Stars::Client).system.with('clear').returns('')
7
- mock(Stars::Formatter).new.times(any_times).with_any_args
8
- mock(Stars::Client).puts.times(any_times).with_any_args
9
- mock(Stars::Client).print.times(any_times).with_any_args
10
- mock(Stars::Client).input.times(any_times).with_any_args.returns('q')
11
- Stars::Client.load!('holman')
12
- end
13
-
14
- def test_load_without_username
15
- mock(Stars::Client).system.with('clear').returns('')
16
- mock(Stars::Formatter).new.times(any_times).with_any_args
17
- mock(Stars::Client).puts.times(any_times).with_any_args
18
- mock(Stars::Client).print.times(any_times).with_any_args
19
- mock(Stars::Client).input.times(any_times).with_any_args.returns('q')
20
- Stars::Client.load!(nil)
21
- end
22
-
23
- def test_username_when_exists
24
- mock(File).exists?.with_any_args.returns(true)
25
- mock(File).read.with_any_args
26
- Stars::Client.username
10
+ def setup
11
+ global_setup
27
12
  end
28
-
29
- def test_username_when_nonexistant
30
- mock(File).exists?.with_any_args.returns(false)
31
- mock(Stars::Client).prompt_for_username
32
- Stars::Client.username
33
- end
34
-
35
- def test_write_home_config
36
- assert_equal Stars::Client.remember_username('holman'), 'holman'
13
+
14
+ def test_add_service
15
+ Stars.config.expects(:prompt_for_username).with('favstar').once
16
+ Stars::Client.any_instance.stubs(:display)
17
+ Stars::Client.any_instance.stubs(:star_loop)
18
+ Stars::Client.new(%w(add favstar))
37
19
  end
38
-
39
- def test_config_path
40
- assert Stars::Client.config_path.index('.stars')
20
+
21
+ def test_show_only_one_service
22
+ Stars::Favstar.expects(:posts).returns([])
23
+ Stars::Client.any_instance.stubs(:star_loop)
24
+ Stars::Client.new(['favstar'])
41
25
  end
42
-
43
26
  end
@@ -0,0 +1,29 @@
1
+ require 'helper'
2
+
3
+ class TestConfig < Test::Unit::TestCase
4
+
5
+ def setup
6
+ global_setup
7
+ @config = Stars::Config.new
8
+ end
9
+
10
+ def test_yaml_load
11
+ assert_equal 'holman', @config.username('favstar')
12
+ end
13
+
14
+ def test_prompt_for_username_existing_service
15
+ @config.keep.stubs(:present?).returns(true)
16
+ Keep.any_instance.expects(:get)
17
+ @config.prompt_for_username("favstar")
18
+ end
19
+
20
+ def test_add_username_to_nonexistent_service
21
+ Stars::Config.any_instance.expects(:exit)
22
+ @config.prompt_for_username("trololol")
23
+ end
24
+
25
+ def test_config_path
26
+ assert @config.config_path.kind_of?(String)
27
+ end
28
+
29
+ end
data/test/test_favstar.rb CHANGED
@@ -3,14 +3,26 @@ require 'helper'
3
3
  class TestFavstar < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
+ global_setup
6
7
  @favstar = Stars::Favstar.new
7
8
  end
8
-
9
- def test_parties_hard
10
- mock(Stars::Favstar).get('/users/holman/rss', :format => :xml) {
11
- {'rss' => {'channel' => {'item' => 'etc'} } }
12
- }
13
- @favstar.recent('holman')
9
+
10
+ def test_parse_title
11
+ title = "6 stars: Zach Holman is attractive and handsome."
12
+ parsed_title = @favstar.parse_title(title)
13
+ assert_equal "Zach Holman is attractive and handsome.", parsed_title
14
+ end
15
+
16
+ def test_parse_title_with_colons
17
+ title = "6 stars: Zach Holman is: attractive and handsome."
18
+ parsed_title = @favstar.parse_title(title)
19
+ assert_equal "Zach Holman is: attractive and handsome.", parsed_title
20
+ end
21
+
22
+ def test_parse_stars
23
+ title = "6 stars: Zach Holman is attractive and handsome."
24
+ parsed_stars = @favstar.parse_stars(title)
25
+ assert_equal 6, parsed_stars
14
26
  end
15
27
 
16
- end
28
+ end
data/test/test_post.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ class TestPost < Test::Unit::TestCase
4
+
5
+ def setup
6
+ global_setup
7
+ @post = Stars::Post.new(:name => 'post')
8
+ end
9
+
10
+ def test_short_name
11
+ s = ""
12
+ 36.times { s << "x" }
13
+ @post.name = s
14
+ assert_equal true, @post.short_name.include?('...')
15
+ end
16
+
17
+ def test_full_short_name
18
+ s = ""
19
+ 10.times { s << "x" }
20
+ @post.name = s
21
+ assert_equal false, @post.short_name.include?('...')
22
+ end
23
+
24
+ def test_moar
25
+ @post.stubs(:service).returns("Favstar")
26
+ Stars::Favstar.expects(:more).returns("favstar more")
27
+ assert_equal "favstar more", @post.more
28
+ end
29
+
30
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stars
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
5
- prerelease: false
4
+ hash: 11
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
8
+ - 5
9
9
  - 0
10
- version: 0.4.0
10
+ version: 0.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Zach Holman
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-24 00:00:00 -06:00
18
+ date: 2011-04-18 00:00:00 -07:00
19
19
  default_executable: stars
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -60,35 +60,71 @@ dependencies:
60
60
  version: "0"
61
61
  type: :runtime
62
62
  version_requirements: *id003
63
- description: Recent favstar faves on your command line.
63
+ - !ruby/object:Gem::Dependency
64
+ name: keep
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ hash: 25
72
+ segments:
73
+ - 0
74
+ - 0
75
+ - 3
76
+ version: 0.0.3
77
+ type: :runtime
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: mocha
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ hash: 41
88
+ segments:
89
+ - 0
90
+ - 9
91
+ - 9
92
+ version: 0.9.9
93
+ type: :development
94
+ version_requirements: *id005
95
+ description: Twitter stars, Convore stars. On the command line.
64
96
  email: github.com@zachholman.com
65
97
  executables:
66
98
  - stars
67
99
  extensions: []
68
100
 
69
101
  extra_rdoc_files:
70
- - LICENSE
71
102
  - README.markdown
103
+ - LICENSE
72
104
  files:
73
- - .document
74
- - .gitignore
105
+ - Gemfile
106
+ - Gemfile.lock
75
107
  - LICENSE
76
108
  - README.markdown
77
109
  - Rakefile
78
- - VERSION
79
110
  - bin/stars
80
111
  - lib/stars.rb
81
112
  - lib/stars/client.rb
82
- - lib/stars/favstar.rb
83
- - lib/stars/formatter.rb
113
+ - lib/stars/config.rb
114
+ - lib/stars/core_ext/string.rb
115
+ - lib/stars/post.rb
116
+ - lib/stars/services/convore.rb
117
+ - lib/stars/services/favstar.rb
118
+ - lib/stars/services/service.rb
84
119
  - stars.gemspec
120
+ - test/examples/stars.yml
85
121
  - test/helper.rb
86
122
  - test/test_client.rb
123
+ - test/test_config.rb
87
124
  - test/test_favstar.rb
88
- - test/test_formatter.rb
89
- - test/test_stars.rb
125
+ - test/test_post.rb
90
126
  has_rdoc: true
91
- homepage: http://github.com/holman/stars
127
+ homepage: https://github.com/holman/stars
92
128
  licenses: []
93
129
 
94
130
  post_install_message:
@@ -116,14 +152,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
152
  version: "0"
117
153
  requirements: []
118
154
 
119
- rubyforge_project:
120
- rubygems_version: 1.3.7
155
+ rubyforge_project: stars
156
+ rubygems_version: 1.6.2
121
157
  signing_key:
122
- specification_version: 3
123
- summary: Recent favstar faves on your command line
158
+ specification_version: 2
159
+ summary: Recent stars on your command line.
124
160
  test_files:
125
- - test/helper.rb
126
161
  - test/test_client.rb
162
+ - test/test_config.rb
127
163
  - test/test_favstar.rb
128
- - test/test_formatter.rb
129
- - test/test_stars.rb
164
+ - test/test_post.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE