syclink 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +33 -0
  6. data/LICENSE +21 -0
  7. data/README.md +191 -0
  8. data/README.rdoc +9 -0
  9. data/Rakefile +5 -0
  10. data/bin/syclink +290 -0
  11. data/doc/Gemfile.html +109 -0
  12. data/doc/Gemfile_lock.html +147 -0
  13. data/doc/LICENSE.html +129 -0
  14. data/doc/Object.html +188 -0
  15. data/doc/README_md.html +322 -0
  16. data/doc/README_rdoc.html +171 -0
  17. data/doc/SycLink/Designer.html +560 -0
  18. data/doc/SycLink/Exporter.html +149 -0
  19. data/doc/SycLink/Formatter.html +416 -0
  20. data/doc/SycLink/Infrastructure.html +297 -0
  21. data/doc/SycLink/Link.html +296 -0
  22. data/doc/SycLink/Website.html +428 -0
  23. data/doc/SycLink.html +127 -0
  24. data/doc/created.rid +31 -0
  25. data/doc/css/fonts.css +167 -0
  26. data/doc/css/rdoc.css +590 -0
  27. data/doc/fonts/Lato-Light.ttf +0 -0
  28. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  29. data/doc/fonts/Lato-Regular.ttf +0 -0
  30. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  31. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  32. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  33. data/doc/images/add.png +0 -0
  34. data/doc/images/arrow_up.png +0 -0
  35. data/doc/images/brick.png +0 -0
  36. data/doc/images/brick_link.png +0 -0
  37. data/doc/images/bug.png +0 -0
  38. data/doc/images/bullet_black.png +0 -0
  39. data/doc/images/bullet_toggle_minus.png +0 -0
  40. data/doc/images/bullet_toggle_plus.png +0 -0
  41. data/doc/images/date.png +0 -0
  42. data/doc/images/delete.png +0 -0
  43. data/doc/images/find.png +0 -0
  44. data/doc/images/loadingAnimation.gif +0 -0
  45. data/doc/images/macFFBgHack.png +0 -0
  46. data/doc/images/package.png +0 -0
  47. data/doc/images/page_green.png +0 -0
  48. data/doc/images/page_white_text.png +0 -0
  49. data/doc/images/page_white_width.png +0 -0
  50. data/doc/images/plugin.png +0 -0
  51. data/doc/images/ruby.png +0 -0
  52. data/doc/images/tag_blue.png +0 -0
  53. data/doc/images/tag_green.png +0 -0
  54. data/doc/images/transparent.png +0 -0
  55. data/doc/images/wrench.png +0 -0
  56. data/doc/images/wrench_orange.png +0 -0
  57. data/doc/images/zoom.png +0 -0
  58. data/doc/index.html +131 -0
  59. data/doc/js/darkfish.js +161 -0
  60. data/doc/js/jquery.js +4 -0
  61. data/doc/js/navigation.js +142 -0
  62. data/doc/js/navigation.js.gz +0 -0
  63. data/doc/js/search.js +109 -0
  64. data/doc/js/search_index.js +1 -0
  65. data/doc/js/search_index.js.gz +0 -0
  66. data/doc/js/searcher.js +228 -0
  67. data/doc/js/searcher.js.gz +0 -0
  68. data/doc/links_csv.html +113 -0
  69. data/doc/setup_md.html +192 -0
  70. data/doc/syclink_gemspec.html +133 -0
  71. data/doc/syclink_rdoc.html +154 -0
  72. data/doc/table_of_contents.html +336 -0
  73. data/doc/templates/example_html.html +399 -0
  74. data/doc/templates/links.html +116 -0
  75. data/doc/templates/stylesheets/style_css.html +170 -0
  76. data/doc/templates/stylesheets/style_css_map.html +111 -0
  77. data/doc/templates/stylesheets/style_css_scss.html +198 -0
  78. data/doc/templates/syc-link_html.html +235 -0
  79. data/lib/syclink/designer.rb +97 -0
  80. data/lib/syclink/designer_example.rb +9 -0
  81. data/lib/syclink/exporter.rb +17 -0
  82. data/lib/syclink/formatter.rb +70 -0
  83. data/lib/syclink/infrastructure.rb +44 -0
  84. data/lib/syclink/link.rb +62 -0
  85. data/lib/syclink/version.rb +7 -0
  86. data/lib/syclink/website.rb +62 -0
  87. data/lib/syclink/website_example.rb +68 -0
  88. data/lib/syclink.rb +7 -0
  89. data/setup.md +92 -0
  90. data/spec/syclink/designer_spec.rb +100 -0
  91. data/spec/syclink/link_spec.rb +47 -0
  92. data/spec/syclink/website_spec.rb +75 -0
  93. data/syclink.gemspec +23 -0
  94. data/syclink.rdoc +39 -0
  95. data/templates/links +4 -0
  96. data/templates/stylesheets/style.css +55 -0
  97. data/templates/stylesheets/style.css.map +7 -0
  98. data/templates/stylesheets/style.css.scss +76 -0
  99. data/templates/syc-link.html +123 -0
  100. data/templates/syclink.html.erb +63 -0
  101. metadata +193 -0
@@ -0,0 +1,70 @@
1
+ # Module that creates a link list and generates an html representation
2
+ module SycLink
3
+
4
+ # Methods to print data in a formatted way
5
+ module Formatter
6
+
7
+ # Based on the rows provided and the header values a table is printed
8
+ def table(rows, header)
9
+ columns = extract_columns(rows, header)
10
+ widths = max_column_widths(columns, header)
11
+ formatter = formatter_string(widths, " | ")
12
+ print_header(header, formatter)
13
+ print_horizontal_line("-", "-+-", widths)
14
+ print_table(columns, formatter)
15
+ end
16
+
17
+ # Extracts the columns to display in the table based on the header column
18
+ # names
19
+ def extract_columns(rows, header)
20
+ columns = []
21
+ header.each do |h|
22
+ columns << rows.map do |r|
23
+ r.send(h)
24
+ end
25
+ end
26
+ columns
27
+ end
28
+
29
+ # Determines max column widths for each column based on the data and header
30
+ # columns
31
+ def max_column_widths(columns, header)
32
+ row_column_widths = columns.map do |c|
33
+ c.reduce(0) { |m, v| [m, v.length].max }
34
+ end
35
+
36
+ header_column_widths = header.map { |h| h.length }
37
+
38
+ row_column_widths.zip(header_column_widths).map do |column|
39
+ column.reduce(0) { |m, v| [m, v].max }
40
+ end
41
+ end
42
+
43
+ # Creates a formatter string based on the widths and the column separator
44
+ def formatter_string(widhts, separator)
45
+ widhts.map do |width|
46
+ "%-#{width}s"
47
+ end.join(separator)
48
+ end
49
+
50
+ # Prints the table's header
51
+ def print_header(header, formatter)
52
+ puts cut(sprintf(formatter, *header), 80)
53
+ end
54
+
55
+ # Prints a horizontal line below the header
56
+ def print_horizontal_line(line, separator, widths)
57
+ puts cut(widths.map { |width| line * width }.join(separator), 80)
58
+ end
59
+
60
+ # Prints columns in a table format
61
+ def print_table(columns, formatter)
62
+ columns.transpose.each { |row| puts cut(sprintf(formatter, *row), 80) }
63
+ end
64
+
65
+ # Cuts the string down to the specified size
66
+ def cut(string, size)
67
+ string[0..size-1]
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,44 @@
1
+ # Module that creates a link list and generates an html representation
2
+ module SycLink
3
+
4
+ # Helper methods to setup the infrastructure for syclink
5
+ module Infrastructure
6
+
7
+ # Creates a directory if it does not exist
8
+ def create_directory_if_missing(directory)
9
+ unless File.exists? directory
10
+ Dir.mkdir directory
11
+ end
12
+ end
13
+
14
+ # Copies a file to a target directory
15
+ def copy_file_if_missing(file, to_directory)
16
+ unless File.exists? File.join(to_directory, File.basename(file))
17
+ FileUtils.cp(file, to_directory)
18
+ end
19
+ end
20
+
21
+ # Loads the configuration from a file
22
+ def load_config(file)
23
+ unless File.exists? file
24
+ File.open(file, 'w') do |f|
25
+ YAML.dump({ default_website: 'default' }, f)
26
+ end
27
+ end
28
+ YAML.load_file(file)
29
+ end
30
+
31
+ # Creates the filename of the website for saving, loading and deleting
32
+ def yaml_file(directory = '.', website)
33
+ File.join(directory, "#{website.downcase.gsub(/\s/, '-')}.website")
34
+ end
35
+
36
+ # Creates an html filename to save the html representation of the website
37
+ # to
38
+ def html_file(directory = '.', website)
39
+ File.join(directory, "#{website.downcase.gsub(/\s/, '-')}.html")
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,62 @@
1
+ # Module that creates a link list and generates an html representation
2
+ module SycLink
3
+
4
+ # Creates a link with url, name, description and tag
5
+ class Link
6
+
7
+ # Attributes that are accessible
8
+ ATTRS = [:url, :name, :description, :tag]
9
+
10
+ # Attribute accessors generated from ATTRS
11
+ attr_accessor *ATTRS
12
+
13
+ # Create a new link with url and params. If params are not provided
14
+ # defaults are used for name the url is used, description is empty and
15
+ # tag is set to 'untagged'
16
+ def initialize(url, params = {})
17
+ @url = url
18
+ params = defaults(url).merge(select_defined(params))
19
+ @name = params[:name]
20
+ @description = params[:description]
21
+ @tag = params[:tag]
22
+ end
23
+
24
+ # Updates the attributes of the link specified by args
25
+ def update(args)
26
+ select_defined(args).each do |attribute, value|
27
+ send("#{attribute}=", value)
28
+ end
29
+ end
30
+
31
+ # Checks whether the link matches the values provided by args and returns
32
+ # true if so otherwise false
33
+ def match?(args)
34
+ select_defined(args).reduce(true) do |sum, attribute|
35
+ sum = sum && (send(attribute[0]) == attribute[1])
36
+ end
37
+ end
38
+
39
+ # Checks whether the search string is contained in one or more of the
40
+ # attributes. If the search string is found true is returned otherwise
41
+ # false
42
+ def contains?(search)
43
+ search = search.delete(' ')
44
+ target = instance_variables.map { |v| instance_variable_get v }.join
45
+ target.downcase.delete(' ').scan(search).size > 0
46
+ end
47
+
48
+ private
49
+
50
+ # Specifies the default values
51
+ def defaults(url)
52
+ { name: url, description: "", tag: "untagged" }
53
+ end
54
+
55
+ # Based on the ATTRS the args are returned that are included in the ATTRS.
56
+ # args with nil values are omitted
57
+ def select_defined(args)
58
+ args.select { |k, v| (ATTRS.include? k) && !v.nil? }
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,7 @@
1
+ # Module that creates a link list and generates an html representation
2
+ module SycLink
3
+
4
+ # Version of the application
5
+ VERSION = '0.0.1'
6
+
7
+ end
@@ -0,0 +1,62 @@
1
+ require_relative 'exporter'
2
+
3
+ # Module that creates a link list and generates an html representation
4
+ module SycLink
5
+
6
+
7
+ # A Website is organizing a link list. The links can be added, updated and
8
+ # removed. It is also possible to search for links. And finally an html
9
+ # representation of the Website can be created.
10
+ class Website
11
+
12
+ include Exporter
13
+
14
+ # The links of the website
15
+ attr_reader :links
16
+ # The title of the website
17
+ attr_reader :title
18
+
19
+ # Create a new Website
20
+ def initialize(title = "Link List")
21
+ @links = []
22
+ @title = title
23
+ end
24
+
25
+ # Add a link to the website
26
+ def add_link(link)
27
+ links << link
28
+ end
29
+
30
+ # Remove a link from the website
31
+ def remove_link(link)
32
+ links.delete(link)
33
+ end
34
+
35
+ # List links that match the attributes
36
+ def list_links(args = {})
37
+ if args.empty?
38
+ links
39
+ else
40
+ links.select { |link| link.match? args }
41
+ end
42
+ end
43
+
44
+ # Finds all links that contain the search string
45
+ def find_links(search)
46
+ links.select { |link| link.contains? search }
47
+ end
48
+
49
+ # Groups the links on the provided attribute
50
+ def links_group_by(attribute)
51
+ links.map { |link| { key: link.send(attribute), link: link } }
52
+ .group_by { |entry| entry[:key] }
53
+ .each { |key, link| link.map! { |l| l[:link] }}
54
+ end
55
+
56
+ # List all attributes of the links
57
+ def link_attribute_list(attribute)
58
+ links.map { |link| link.send(attribute) }.uniq.sort
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'website'
2
+ require_relative 'link'
3
+
4
+ # Module that creates a link list and generates an html representation
5
+ module SycLink
6
+
7
+ website = SycLink::Website.new("Test")
8
+ links = [ [ "http://sugaryourcoffee.de",
9
+ {title: "Sugar Your Coffee", tag: "Home"}],
10
+ [ "https://github.com",
11
+ {title: "Github", description: "Repository", tag: "Development"}],
12
+ [ "https://github.com",
13
+ {title: "Github", description: "Repository", tag: "Learning"}],
14
+ [ "https://github.com",
15
+ {title: "Github", description: "Repository", tag: "Development"}],
16
+ [ "https://github.com",
17
+ {title: "Github", description: "Repository", tag: "Learning"}],
18
+ [ "https://github.com",
19
+ {title: "Github", description: "Repository", tag: "Development"}],
20
+ [ "https://github.com",
21
+ {title: "Github", description: "Repository", tag: "Development"}],
22
+ [ "https://github.com",
23
+ {title: "Github", description: "Repository", tag: "Development"}],
24
+ [ "https://github.com",
25
+ {title: "Github", description: "Repository", tag: "Learning"}],
26
+ [ "https://github.com",
27
+ {title: "Github", description: "Repository", tag: "Fun"}],
28
+ [ "https://github.com",
29
+ {title: "Github", description: "Repository", tag: "Development"}],
30
+ [ "https://github.com",
31
+ {title: "Github", description: "Repository", tag: "Fun"}],
32
+ [ "https://github.com",
33
+ {title: "Github", description: "Repository", tag: "Development"}],
34
+ [ "https://github.com",
35
+ {title: "Github", description: "Repository", tag: "Development"}],
36
+ [ "https://github.com",
37
+ {title: "Github", description: "Repository", tag: "Development"}],
38
+ [ "https://github.com",
39
+ {title: "Github", description: "Repository", tag: "Development"}],
40
+ [ "https://github.com",
41
+ {title: "Github", description: "Repository", tag: "Challenge"}],
42
+ [ "https://github.com",
43
+ {title: "Github", description: "Repository", tag: "Challenge"}],
44
+ [ "https://github.com",
45
+ {title: "Github", description: "Repository", tag: "Development"}],
46
+ [ "https://github.com",
47
+ {title: "Github", description: "Repository", tag: "Challenge"}],
48
+ [ "https://github.com",
49
+ {title: "Github", description: "Repository", tag: "Development"}],
50
+ [ "https://github.com",
51
+ {title: "Github", description: "Repository", tag: "Development"}],
52
+ [ "https://github.com",
53
+ {title: "Github", description: "Repository", tag: "Development"}],
54
+ [ "http://syc.dyndns.org:8080",
55
+ {title: "Secondhand", description: "Selling", tag: "Home"}],
56
+ [ "http://syc.dyndns.org:8081",
57
+ {title: "apptrack - application tracking",
58
+ description: "Application tracking made so easy that is even \
59
+ unbelivable to make it more easy peasy as it is today",
60
+ tag: "Home"}]]
61
+
62
+
63
+ links.each do |link|
64
+ website.add_link(SycLink::Link.new(link[0], link[1]))
65
+ end
66
+
67
+ puts website.to_html(File.read("./templates/syclink.html.erb"))
68
+ end
data/lib/syclink.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'syclink/designer'
2
+ require 'syclink/link'
3
+ require 'syclink/exporter'
4
+ require 'syclink/website'
5
+ require 'syclink/infrastructure'
6
+ require 'syclink/formatter'
7
+
data/setup.md ADDED
@@ -0,0 +1,92 @@
1
+ Create Directory Structure
2
+ ==========================
3
+ We follow the _RubyGems_ convention to organize a Ruby project. We create a
4
+ directory structure as follows.
5
+
6
+ ````
7
+ syclink
8
+ |
9
+ |--LICENSE
10
+ |--README.md
11
+ |--bin
12
+ | |--command-line-file-goes-here
13
+ |--lib
14
+ | |-syclink
15
+ | |--application-files-go-here
16
+ |
17
+ |--spec
18
+ | |--syclink
19
+ | |--test-files-go-here
20
+ |--templates
21
+ | |--syclink.html.erb
22
+ | |--stylesheets
23
+ | |--style.css.scss
24
+ | |--style.css
25
+ |--.rspec
26
+ |--.gitignore
27
+ ````
28
+
29
+ Organize the source code with Git
30
+ =================================
31
+ To organize our source we use _Git_ and have to do an initialize like so
32
+
33
+ $ git init
34
+
35
+ Then we have to create a repository at [Github](https://github.com) and push
36
+ our project to _Github_
37
+
38
+ $ git commit -m "first commit"
39
+ $ git remote add origin git@github.com:sugaryourcoffee/syclink.git
40
+ $ git push -u origin master
41
+
42
+ Create addtional basic files
43
+ ============================
44
+ We should add a README to describe our application and decide upon a license
45
+ we want to distribute it. We will use the [MIT License](http://opensource.org/licenses/MIT).
46
+ Also a _.gitignore_ file should be created to exclude i.e. temp-files from the
47
+ repository.
48
+
49
+ Select the Ruby version
50
+ =======================
51
+ For a new project we want to use the newst Ruby version. At this writing it is
52
+ verison 2.2.1. Suppose we use [RVM](https://rvm.io/). If not already installed
53
+ we install it with
54
+
55
+ $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
56
+ $ \curl -sSL https://get.rvm.io | bash -s stable
57
+ $ rvm install 2.2.1
58
+ $ rvm use 2.2.1
59
+
60
+ Install RSpec
61
+ =============
62
+ For tests we want to use _RSpec_. To install RSpec issue this command
63
+
64
+ $ gem install rspec
65
+
66
+ This will install the latest version. To see results of RSpec in color add
67
+ following line to _.rspec_ in the application's root directory
68
+
69
+ --color
70
+
71
+ Install Sass
72
+ ============
73
+ As we will create a html file with links we need to style with CSS. But instead
74
+ of using plain CSS we will use Scss. For that we need to install Sass
75
+
76
+ $ gem install sass
77
+
78
+ Then we can write stylesheets in the sassy style and when done compile them
79
+ to CSS with
80
+
81
+ $ sass templates/stylesheets/style.scss:templates/stylesheets/style.css
82
+
83
+ Distribution
84
+ ============
85
+ To distribute the application we need the Gemfile and a Rakefile with the
86
+ 'rubygems/package\_task'.
87
+
88
+ From the command line we call
89
+
90
+ $ rake package
91
+
92
+ This will create a gem package we can distribute
@@ -0,0 +1,100 @@
1
+ require 'syclink/designer.rb'
2
+
3
+ module SycLink
4
+
5
+ describe Designer do
6
+
7
+ before do
8
+ @designer = Designer.new
9
+ @designer.new_website("Test Site")
10
+ end
11
+
12
+ it "should add a link" do
13
+ @designer.add_link("http://example.com",
14
+ { name: "Example",
15
+ description: "An example website",
16
+ tag: "Test" })
17
+
18
+ expect(@designer.website.links.size).to eq 1
19
+ end
20
+
21
+ it "should add links from a file" do
22
+ links = [ "http://example.com;Example;An example website;Test",
23
+ "http://test.de;A test website;Test",
24
+ "http://challenge.org;A challenge website;Challenge" ]
25
+ File.write("links.tmp", links.join("\n"))
26
+
27
+ @designer.add_links_from_file("links.tmp")
28
+ expect(@designer.website.links.size).to eq 3
29
+
30
+ FileUtils.rm("links.tmp")
31
+ end
32
+
33
+ it "should find a link" do
34
+ @designer.add_link("http://example.com",
35
+ { name: "Example",
36
+ description: "An example website",
37
+ tag: "Test" })
38
+ expect(@designer.find_links("http://example.com")).to be_truthy
39
+ end
40
+
41
+ it "should update a link" do
42
+ @designer.add_link("http://example.com",
43
+ { name: "Example",
44
+ description: "An example website",
45
+ tag: "Test" })
46
+ @designer.update_link("http://example.com",
47
+ { name: "Reality",
48
+ description: "A reality website",
49
+ tag: "Reality" })
50
+
51
+ expect(@designer.find_links("http://example.com")
52
+ .first.name).to eq "Reality"
53
+ end
54
+
55
+ it "should list all links" do
56
+ @designer.add_link("http://example.com",
57
+ { name: "Example",
58
+ description: "An example website",
59
+ tag: "Test" })
60
+
61
+ expect(@designer.list_links).to eq @designer.website.links
62
+ end
63
+
64
+ it "should list links based on attributes" do
65
+ @designer.add_link("http://example.com",
66
+ { name: "Example",
67
+ description: "An example website",
68
+ tag: "Test" })
69
+ @designer.add_link("http://example.com",
70
+ { name: "Reality",
71
+ description: "A reality website",
72
+ tag: "Reality" })
73
+
74
+ expect(@designer.list_links({name: "Reality"}).size).to eq 1
75
+ end
76
+
77
+ it "should delete a link" do
78
+ @designer.add_link("http://example.com",
79
+ { tag: "Example", name: "Link" })
80
+ @designer.add_link("http://reality.com",
81
+ { tag: "Reality", name: "URL" })
82
+
83
+ expect(@designer.list_links.size).to eq 2
84
+ @designer.remove_links(["http://reality.com"])
85
+ expect(@designer.list_links.size).to eq 1
86
+ end
87
+
88
+ it "should save, load and delete a website" do
89
+ @designer.add_link("http://example.com",
90
+ { tag: "Loader" })
91
+ @designer.save_website(".")
92
+ @designer.load_website("test-site.website")
93
+ expect(@designer.website.title).to eq "Test Site"
94
+ @designer.delete_website(".")
95
+ expect(Dir["./website.website"]).to be_empty
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,47 @@
1
+ require 'syclink/link'
2
+
3
+ module SycLink
4
+
5
+ describe Link do
6
+
7
+ before do
8
+ @link = Link.new("http://example.com")
9
+ @link_complete = Link.new("http://example.com",
10
+ { name: "Example",
11
+ description: "For testing purposes",
12
+ tag: "Test" })
13
+ end
14
+
15
+ it "should create a link" do
16
+ expect(@link.url).to eq "http://example.com"
17
+ expect(@link.name).to eq "http://example.com"
18
+ expect(@link.description).to be_empty
19
+ expect(@link.tag).to eq "untagged"
20
+ end
21
+
22
+ it "should update a link" do
23
+ @link.update({name: "Example",
24
+ description: "For testing purposes",
25
+ tag: "Test"})
26
+ expect(@link.name).to eq "Example"
27
+ expect(@link.description).to eq "For testing purposes"
28
+ expect(@link.tag).to eq "Test"
29
+ end
30
+
31
+ it "should return true if search attributes match" do
32
+ expect(@link_complete.match?({url: "http://example.com"})).to be_truthy
33
+ expect(@link_complete.match?({url: "http://example.de"})).to be_falsey
34
+ expect(@link_complete.match?({url: "http://example.com",
35
+ name: "Example"})).to be_truthy
36
+ expect(@link_complete.match?({description: "For testing purposes",
37
+ tag: "Test"})).to be_truthy
38
+ expect(@link_complete.match?({tag: "Test"})).to be_truthy
39
+ end
40
+
41
+ it "should return true if search string is part of link attributes" do
42
+ expect(@link_complete.contains?("example.com")).to be_truthy
43
+ expect(@link_complete.contains?("nothing")).to be_falsey
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,75 @@
1
+ require 'syclink/website'
2
+
3
+ module SycLink
4
+
5
+ describe Website do
6
+
7
+ before do
8
+ @link = Link.new("http://example.com",
9
+ { name: "Example",
10
+ description: "An example website",
11
+ tag: "Test" })
12
+ @website = Website.new("Link List")
13
+ @template = <<-HERE.gsub(/^ {8}/, '')
14
+ <html>
15
+ <h1><%= title %></h1>
16
+ <% links.each do |link| %>
17
+ <a href='<%= link.url %>'><%= link.name %></a>
18
+ <%= link.description %> <%= link.tag %>
19
+ <% end %>
20
+ </html>
21
+ HERE
22
+ end
23
+
24
+ it "should add link" do
25
+ expect(@website.links).to eq []
26
+ @website.add_link(@link)
27
+ expect(@website.links).to eq [@link]
28
+ end
29
+
30
+ it "should delete link" do
31
+ @website.add_link(@link)
32
+ @website.remove_link(@link)
33
+ expect(@website.links).to eq []
34
+ end
35
+
36
+ it "should list links based on attributes" do
37
+ @website.add_link(@link)
38
+ expect(@website.list_links({name: "not there"}).size).to eq 0
39
+ expect(@website.list_links({name: "Example"}).size).to eq 1
40
+ expect(@website.list_links.size).to eq 1
41
+ end
42
+
43
+ it "should find links based on search string" do
44
+ @website.add_link(@link)
45
+ expect(@website.find_links("example.com")).to eq [@link]
46
+ expect(@website.find_links("website")).to eq [@link]
47
+ expect(@website.find_links("nothing")).to eq []
48
+ end
49
+
50
+ it "should create the html representation" do
51
+ @website.add_link(@link)
52
+ html = @website.to_html(@template)
53
+ expect(html).to include("<a href='http://example.com'>")
54
+ expect(html).to include("Example")
55
+ expect(html).to include("An example website")
56
+ expect(html).to include("Test")
57
+ end
58
+
59
+ it "should group links on tags" do
60
+ @website.add_link(@link)
61
+ @website.add_link(@link)
62
+ target = { "Test" => [@link, @link] }
63
+ expect(@website.links_group_by(:tag)).to eq target
64
+ end
65
+
66
+ it "should list all tags" do
67
+ @website.add_link(@link)
68
+ @website.add_link(@link)
69
+ target = [ @link.tag ]
70
+ expect(@website.link_attribute_list(:tag)).to eq target
71
+ end
72
+
73
+ end
74
+
75
+ end
data/syclink.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # Ensure we require the local version and not one we might have installed already
2
+ require File.join([File.dirname(__FILE__),'lib','syclink','version.rb'])
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'syclink'
5
+ s.version = SycLink::VERSION
6
+ s.author = 'Pierre Sugar'
7
+ s.email = 'pierre@sugaryourcoffee.de'
8
+ s.homepage = 'https://github.com/sugaryourcoffee/syclink'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'A link list html generator'
11
+ s.description = 'Create a link list and display it in a HTML file'
12
+ s.license = 'MIT license (MIT)'
13
+ s.files = `git ls-files`.split(" ")
14
+ s.require_paths << 'lib'
15
+ s.has_rdoc = true
16
+ s.extra_rdoc_files = ['README.rdoc','syclink.rdoc']
17
+ s.rdoc_options << '--title' << 'test' << '--main' << 'README.rdoc' << '-ri'
18
+ s.bindir = 'bin'
19
+ s.executables << 'syclink'
20
+ s.add_development_dependency('rspec', '3.3.1')
21
+ s.add_development_dependency('sass', '3.4.15')
22
+ s.add_runtime_dependency('gli','2.13.1')
23
+ end