sitebuilder 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +0 -0
- data/COPYING +32 -0
- data/README.rdoc +28 -0
- data/TODO.rdoc +9 -0
- data/lib/sitebuilder/array.rb +24 -0
- data/lib/sitebuilder/filesystem.rb +95 -0
- data/lib/sitebuilder/gen.rb +16 -0
- data/lib/sitebuilder/sitegenerator.rb +45 -0
- data/lib/sitebuilder/string.rb +40 -0
- data/lib/sitebuilder.rb +4 -0
- data/test/array_test.rb +35 -0
- data/test/data/testfile.txt +1 -0
- data/test/filesystem_test.rb +104 -0
- data/test/string_test.rb +81 -0
- metadata +73 -0
data/CHANGELOG
ADDED
File without changes
|
data/COPYING
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
SiteBuilder Licence
|
2
|
+
|
3
|
+
COPYRIGHT AND PERMISSION NOTICE
|
4
|
+
|
5
|
+
Copyright (c) 2009 Green Bar Software Limited, UK
|
6
|
+
|
7
|
+
All rights reserved.
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
10
|
+
copy of this software and associated documentation files (the
|
11
|
+
"Software"), to deal in the Software without restriction, including
|
12
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
distribute, and/or sell copies of the Software, and to permit persons
|
14
|
+
to whom the Software is furnished to do so, provided that the above
|
15
|
+
copyright notice(s) and this permission notice appear in all copies of
|
16
|
+
the Software and that both the above copyright notice(s) and this
|
17
|
+
permission notice appear in supporting documentation.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
20
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
22
|
+
OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
23
|
+
HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
|
24
|
+
INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
|
25
|
+
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
26
|
+
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
27
|
+
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
28
|
+
|
29
|
+
Except as contained in this notice, the name of a copyright holder
|
30
|
+
shall not be used in advertising or otherwise to promote the sale, use
|
31
|
+
or other dealings in this Software without prior written authorization
|
32
|
+
of the copyright holder.
|
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
= SiteBuilder
|
2
|
+
SiteBuilder is a rule-based static website generator. It performs an inorder traversal of each
|
3
|
+
file and directory in a source directory, applying exactly one transformation action per file.
|
4
|
+
|
5
|
+
Each transformation action gets the opportunity to write output to a corresponding directory in
|
6
|
+
a subdirectory of a destination directory.
|
7
|
+
|
8
|
+
* The action to be used on each file or directory is determined by file extension.
|
9
|
+
* Actions should not depend on the order in which they run, or on the output of other actions.
|
10
|
+
* Actions may use any part of the source directory.
|
11
|
+
* No action should change the source directory or its contents.
|
12
|
+
|
13
|
+
= How to use it
|
14
|
+
* Just a core object model & tests right now... needs to be completed.
|
15
|
+
|
16
|
+
== RDOC API
|
17
|
+
The rdoc can be found at http://www.greenbarsoft.co.uk/software/sitebuilder/rdoc/
|
18
|
+
|
19
|
+
== Compatibility
|
20
|
+
This project is being developed on OS X. Automated testing for Linux will be included in future releases.
|
21
|
+
|
22
|
+
== Licence
|
23
|
+
This is open source software and comes with no warranty. See COPYING for details.
|
24
|
+
|
25
|
+
|
26
|
+
http://www.greenbarsoft.co.uk
|
27
|
+
|
28
|
+
Copyright 2009 Green Bar Software Limited, UK
|
data/TODO.rdoc
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
== todo
|
2
|
+
* make template action
|
3
|
+
* merge a text formatter into template action
|
4
|
+
* make copy action
|
5
|
+
* make index action
|
6
|
+
* work out how to handle cross references
|
7
|
+
* work out how to handle non-fatal errors
|
8
|
+
* work out how to handle fatal errors
|
9
|
+
* integrate SemanticText action
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Array
|
2
|
+
|
3
|
+
# execute block for each element of array, passing the element as the block
|
4
|
+
# parameter until the block returns true
|
5
|
+
def each_until(&block)
|
6
|
+
return false if empty?
|
7
|
+
for i in 0..size
|
8
|
+
result_true = block.call(self[i])
|
9
|
+
break if result_true
|
10
|
+
end
|
11
|
+
if result_true
|
12
|
+
return true
|
13
|
+
else
|
14
|
+
return false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# return a subarray consisting of elements 2..n of the array
|
19
|
+
# (i.e. all except the first element)
|
20
|
+
def tail
|
21
|
+
return self[1,size-1] if size>1
|
22
|
+
return []
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'FileUtils'
|
2
|
+
module SiteBuilder
|
3
|
+
|
4
|
+
# Abstract class which is the abstract base class for file system instances
|
5
|
+
class FsEntry
|
6
|
+
# This is the canonical path to the file system entry
|
7
|
+
attr_reader :path
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@path = File.expand_path(path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.path==(other.path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def extname
|
18
|
+
File::extname(@path)
|
19
|
+
end
|
20
|
+
|
21
|
+
# the bare filename without the file extension
|
22
|
+
def extnless
|
23
|
+
b = basename
|
24
|
+
b[0,b.size-extname.size]
|
25
|
+
end
|
26
|
+
|
27
|
+
def basename
|
28
|
+
File::basename(@path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def dirname
|
32
|
+
File::dirname(@path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def ctime
|
36
|
+
File::ctime(@path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def size
|
40
|
+
File.size(@path)
|
41
|
+
end
|
42
|
+
|
43
|
+
# creates a file system entry for a fully qualified pathname
|
44
|
+
def self.fs_entry_from(f)
|
45
|
+
return FileEntry.new(f) if File.file?(f)
|
46
|
+
return DirEntry.new(f) if File.directory?(f)
|
47
|
+
UnknownEntry.new(f)
|
48
|
+
end
|
49
|
+
|
50
|
+
# creates a file system entry for a filename in the current file system entry object
|
51
|
+
def fs_entry_from(fs_entry)
|
52
|
+
FsEntry.fs_entry_from(File.join(@path, fs_entry))
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# I represent a file in the filesystem
|
58
|
+
class FileEntry < FsEntry
|
59
|
+
|
60
|
+
# I am visitable with a traverser.
|
61
|
+
def traverse(traverser)
|
62
|
+
traverser.traverse_file(self)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# I represent filesystem entries that have been detected but aren't supported.
|
67
|
+
class UnknownEntry < FsEntry
|
68
|
+
end
|
69
|
+
|
70
|
+
# I represent directories in the filesystem.
|
71
|
+
class DirEntry < FsEntry
|
72
|
+
|
73
|
+
# I am visitable with a Traverser. I perform inorder traversal of FsEntries.
|
74
|
+
def traverse(traverser)
|
75
|
+
traverser.traverse_dir(self)
|
76
|
+
Dir.new(@path).each do |stringpath|
|
77
|
+
subentry = fs_entry_from(stringpath)
|
78
|
+
subentry.traverse(traverser) unless stringpath=='.' || stringpath=='..'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# Visitor for traversing a filesystem
|
85
|
+
class Traverser
|
86
|
+
# callback when traversing a DirEntry object
|
87
|
+
def traverse_dir(dir_entry)
|
88
|
+
end
|
89
|
+
|
90
|
+
# callback when traversing a FileEntry object
|
91
|
+
def traverse_file(file_entry)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'sitebuilder/sitegenerator'
|
3
|
+
module SiteBuilder
|
4
|
+
|
5
|
+
swapout = File.join(ENV['SANDBOX'],'sitebuilder','examples','homepage','source')
|
6
|
+
replace = File.join(ENV['SANDBOX'],'sitebuilder','examples','homepage','dest')
|
7
|
+
|
8
|
+
s = SiteGenerator.new(swapout,replace)
|
9
|
+
s.add_action('.art') {|s,r| `cp #{s.path} #{r}`; puts "article template #{s.path}\n\t\t #{r}"}
|
10
|
+
s.add_action('.idx') {|s,r| `cp #{s.path} #{r}`; puts "index template #{s.path}\n\t\t #{r}"}
|
11
|
+
s.add_action('.png') {|s,r| `cp #{s.path} #{r}`; puts "png copy #{s.path}\n\t\t #{r}"}
|
12
|
+
s.add_action('.css') {|s,r| `cp #{s.path} #{r}`; puts "css copy #{s.path}\n\t\t #{r}"}
|
13
|
+
|
14
|
+
DirEntry.new(swapout).traverse(s)
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'sitebuilder/filesystem'
|
2
|
+
require 'sitebuilder/string'
|
3
|
+
|
4
|
+
module SiteBuilder
|
5
|
+
|
6
|
+
# I generate a target website directory from a source website directory
|
7
|
+
# using mapping rules that determine what should be done for each file
|
8
|
+
# of the source website directory.
|
9
|
+
class SiteGenerator < Traverser
|
10
|
+
|
11
|
+
# I set up the source website directory and the destination website directory.
|
12
|
+
def initialize(source, destination)
|
13
|
+
@swapout = source
|
14
|
+
@replace = destination
|
15
|
+
@actions = {}
|
16
|
+
@actions.default=Proc.new {|s,r| puts "default action source:#{s.path}\n\t\t destination:#{r}"}
|
17
|
+
end
|
18
|
+
|
19
|
+
# internal callback used to handle a source directory
|
20
|
+
def traverse_dir(dir_entry)
|
21
|
+
converted_path = dir_entry.path.clone
|
22
|
+
converted_path.substitute_prefix!(@swapout, @replace)
|
23
|
+
`mkdir #{converted_path}`
|
24
|
+
end
|
25
|
+
|
26
|
+
# internal callback used to handle a source file
|
27
|
+
def traverse_file(file_entry)
|
28
|
+
if !file_entry.path.index('.svn')
|
29
|
+
converted_path = file_entry.dirname
|
30
|
+
converted_path.substitute_prefix!(@swapout, @replace) #BUG? - no clone here?
|
31
|
+
@actions[file_entry.extname].call(file_entry, converted_path)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Add an action for a given source file extension. The action is given by a block which
|
36
|
+
# will be executed when traversal finds a matching file system entry matching the
|
37
|
+
# extension. The block is takes 2 arguments, first the FsEntry representing the source
|
38
|
+
# file system entry, and the second, a String which is the path to the destination
|
39
|
+
# directory.
|
40
|
+
def add_action(extension, &proc)
|
41
|
+
@actions[extension]=proc
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
# return true iff string commences with target
|
4
|
+
def begins_with(target)
|
5
|
+
self[0,target.size]==target
|
6
|
+
end
|
7
|
+
|
8
|
+
# return true iff string ends with target
|
9
|
+
def ends_with(target)
|
10
|
+
target_size = target.size
|
11
|
+
target==self[-target_size,target_size]
|
12
|
+
end
|
13
|
+
|
14
|
+
# return true iff string ends with target
|
15
|
+
# Case insensitive version.
|
16
|
+
def case_ends_with(target)
|
17
|
+
target_size = target.size
|
18
|
+
target.upcase==self.upcase[-target_size,target_size]
|
19
|
+
end
|
20
|
+
|
21
|
+
# iff string begins_with prefix, replace it with new_prefix
|
22
|
+
def substitute_prefix!(prefix,new_prefix)
|
23
|
+
return self if prefix != self[0,prefix.size]
|
24
|
+
self[0,prefix.size] = new_prefix
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# iff string begins_with prefix, return a clone on which the
|
29
|
+
# new_prefix has been substituted for prefix
|
30
|
+
def substitute_prefix(prefix,new_prefix)
|
31
|
+
result =self.clone
|
32
|
+
result.substitute_prefix!(prefix,new_prefix)
|
33
|
+
end
|
34
|
+
|
35
|
+
# returns substring to the righthand side of the rightmost occurrence of token
|
36
|
+
def rightmost_of_token(token)
|
37
|
+
rightmost_index = rindex(token)
|
38
|
+
rightmost_index.nil? ? '' : self[rightmost_index+1,size-rightmost_index]
|
39
|
+
end
|
40
|
+
end
|
data/lib/sitebuilder.rb
ADDED
data/test/array_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'sitebuilder/array'
|
4
|
+
|
5
|
+
class ArrayTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_tail
|
8
|
+
assert_equal([],[].tail);
|
9
|
+
assert_equal([],[1].tail);
|
10
|
+
assert_equal([2],[1,2].tail);
|
11
|
+
assert_equal([2,3],[1,2,3].tail);
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_each_until_empty
|
15
|
+
result = [].each_until {|i| true}
|
16
|
+
assert !result, "empty array should return false"
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_each_until_found
|
20
|
+
unit = [1,2,3,4,5]
|
21
|
+
pass_count = 0
|
22
|
+
result = unit.each_until {|i| pass_count=pass_count+1; true if i==3}
|
23
|
+
assert_equal(true, result, 'should return true')
|
24
|
+
assert_equal(3, pass_count,'should have traversed elements 1, 2 and 3')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_each_until_not_found
|
28
|
+
unit = [1,2,33,4,5]
|
29
|
+
pass_count = 0
|
30
|
+
result = unit.each_until {|i| pass_count=pass_count+1; true if i==3}
|
31
|
+
assert_equal(false, result, 'should return false')
|
32
|
+
assert_equal(unit.length+1, pass_count,'should have traversed elements 1, 2 and 33')
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
My ctime is used for tests.
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'mocha'
|
4
|
+
require 'sitebuilder/filesystem'
|
5
|
+
|
6
|
+
FS = File::SEPARATOR
|
7
|
+
TEST_DIRNAME = 'data'
|
8
|
+
TESTDATA_DIR = ENV['SANDBOX']+FS+'sitebuilder'+FS+'test'+FS+TEST_DIRNAME
|
9
|
+
TEST_FILENAME = 'testfile.txt'
|
10
|
+
TEST_FILEPATH = TESTDATA_DIR+FS+TEST_FILENAME
|
11
|
+
|
12
|
+
class FsEntryTest < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def test_instances_and_equality
|
15
|
+
a_file = SiteBuilder::FsEntry.new('/this/that/foo.txt')
|
16
|
+
another_file = SiteBuilder::FsEntry.new('/this/that/foo.txt')
|
17
|
+
different_file=SiteBuilder::FsEntry.new('/this/that/other.txt')
|
18
|
+
|
19
|
+
assert_equal(another_file, a_file)
|
20
|
+
assert_equal(a_file, another_file)
|
21
|
+
assert_not_equal(a_file, different_file)
|
22
|
+
assert_not_equal(another_file, different_file)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_extname
|
26
|
+
assert_equal('.txt', SiteBuilder::FsEntry.new('/this/that/foo.txt').extname)
|
27
|
+
assert_equal('', SiteBuilder::FsEntry.new('/this/that/foo.').extname)
|
28
|
+
assert_equal('', SiteBuilder::FsEntry.new('/this/that/foo').extname)
|
29
|
+
assert_equal('', SiteBuilder::FsEntry.new('/this/that/.foo').extname)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_extnless
|
33
|
+
assert_equal('foo', SiteBuilder::FsEntry.new('/this/that/foo.txt').extnless)
|
34
|
+
assert_equal('foo.',SiteBuilder::FsEntry.new('/this/that/foo.').extnless)
|
35
|
+
assert_equal('foo', SiteBuilder::FsEntry.new('/this/that/foo').extnless)
|
36
|
+
assert_equal('.foo',SiteBuilder::FsEntry.new('/this/that/.foo').extnless)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_basename
|
40
|
+
assert_equal('foo.txt', SiteBuilder::FsEntry.new('/this/that/foo.txt').basename)
|
41
|
+
assert_equal('foo.txt', SiteBuilder::FsEntry.new('/foo.txt').basename)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_dirname
|
45
|
+
assert_equal('/this/that', SiteBuilder::FsEntry.new('/this/that/foo.txt').dirname)
|
46
|
+
assert_equal('/this/that', SiteBuilder::FsEntry.new('/this/that/foo/').dirname)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_ctime
|
50
|
+
assert_equal(File::ctime(TEST_FILEPATH), SiteBuilder::FsEntry.new(TEST_FILEPATH).ctime)
|
51
|
+
assert SiteBuilder::FsEntry.new(TEST_FILEPATH).ctime.to_i > 0
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_size
|
55
|
+
assert_equal(28, SiteBuilder::FsEntry.new(TEST_FILEPATH).size)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_fs_entry_from
|
59
|
+
assert_equal SiteBuilder::FileEntry, SiteBuilder::FsEntry.fs_entry_from(TEST_FILEPATH).class
|
60
|
+
assert_equal SiteBuilder::DirEntry, SiteBuilder::FsEntry.fs_entry_from(TESTDATA_DIR).class
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_instance_fs_entry_from
|
64
|
+
instance = SiteBuilder::FsEntry.fs_entry_from(TESTDATA_DIR)
|
65
|
+
file_result = instance.fs_entry_from(TEST_FILENAME)
|
66
|
+
dir_result = instance.fs_entry_from('.')
|
67
|
+
|
68
|
+
assert_equal instance.path+FS+TEST_FILENAME, file_result.path
|
69
|
+
assert_equal instance.path, dir_result.path
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
class FileEntryTest < Test::Unit::TestCase
|
75
|
+
|
76
|
+
def test_traverse
|
77
|
+
traverser = SiteBuilder::Traverser.new
|
78
|
+
traverser.expects(:traverse_file).once().with do |file|
|
79
|
+
SiteBuilder::FileEntry==file.class && 'testfile.txt'==file.basename
|
80
|
+
end
|
81
|
+
traverser.expects(:traverse_dir).never()
|
82
|
+
|
83
|
+
file = SiteBuilder::FsEntry.fs_entry_from(TEST_FILEPATH)
|
84
|
+
file.traverse(traverser)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
class DirEntryTest < Test::Unit::TestCase
|
90
|
+
|
91
|
+
def test_traverse
|
92
|
+
traverser = SiteBuilder::Traverser.new
|
93
|
+
traverser.expects(:traverse_file).once().with do |file|
|
94
|
+
SiteBuilder::FileEntry==file.class && 'testfile.txt'==file.basename
|
95
|
+
end
|
96
|
+
traverser.expects(:traverse_dir).once().with do |dir|
|
97
|
+
SiteBuilder::DirEntry==dir.class && TESTDATA_DIR==dir.path
|
98
|
+
end
|
99
|
+
|
100
|
+
file = SiteBuilder::FsEntry.fs_entry_from(TESTDATA_DIR)
|
101
|
+
file.traverse(traverser)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
data/test/string_test.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'sitebuilder/string'
|
4
|
+
|
5
|
+
class ArrayTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_begins_with
|
8
|
+
assert "This is an arbitrary string.".begins_with('')
|
9
|
+
assert "This is an arbitrary string.".begins_with('T')
|
10
|
+
assert "This is an arbitrary string.".begins_with('This is ')
|
11
|
+
assert !("This is an arbitrary string.".begins_with('This xis '))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_ends_with
|
15
|
+
assert "This is an arbitrary string.".ends_with('ing.')
|
16
|
+
assert "This is an arbitrary string.".ends_with('')
|
17
|
+
assert !("This is an arbitrary string.".ends_with('ingx.'))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_case_ends_with
|
21
|
+
assert "This is an arbitrary string.".case_ends_with('ing.')
|
22
|
+
assert "This is an arbitrary string.".case_ends_with('')
|
23
|
+
assert !("This is an arbitrary string.".case_ends_with('ingx.'))
|
24
|
+
|
25
|
+
assert "This is an arbitrary striNg.".case_ends_with('ing.')
|
26
|
+
assert "This is an arbitrary string.".case_ends_with('iNg.')
|
27
|
+
assert !("This is an arbitrary string.".case_ends_with('ingX.'))
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_substitute_prefix_exclamation
|
31
|
+
unit = "This is an arbitrary string."
|
32
|
+
unit.substitute_prefix!("This is an","This is a very")
|
33
|
+
assert_equal "This is a very arbitrary string.", unit
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_substitute_prefix_exclamation_when_prefix_doesnt_match
|
37
|
+
unit = "The cat sat on the mat."
|
38
|
+
unit.substitute_prefix!("This is an","This is a very")
|
39
|
+
assert_equal "The cat sat on the mat.", unit
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_substitute_prefix_exclamation_when_prefix_doesnt_match_and_string_empty
|
43
|
+
unit = ""
|
44
|
+
unit.substitute_prefix!("This is an","This is a very")
|
45
|
+
assert_equal "", unit
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_substitute_prefix_exclamation_when_prefix_match_is_empty
|
49
|
+
unit = "This is an arbitrary string."
|
50
|
+
unit.substitute_prefix!("","This is a very")
|
51
|
+
assert_equal "This is a veryThis is an arbitrary string.", unit
|
52
|
+
end
|
53
|
+
|
54
|
+
################
|
55
|
+
|
56
|
+
def test_substitute_prefix
|
57
|
+
unit = "This is an arbitrary string."
|
58
|
+
assert_equal "This is a very arbitrary string.", unit.substitute_prefix("This is an","This is a very")
|
59
|
+
assert_equal "This is an arbitrary string.", unit
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_substitute_prefix_when_prefix_doesnt_match
|
63
|
+
unit = "The cat sat on the mat."
|
64
|
+
assert_equal "The cat sat on the mat.", unit.substitute_prefix("This is an","This is a very")
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_substitute_prefix_when_prefix_doesnt_match_and_string_empty
|
68
|
+
assert_equal "", "".substitute_prefix("This is an","This is a very")
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_substitute_prefix_when_prefix_match_is_empty
|
72
|
+
unit = "This is an arbitrary string."
|
73
|
+
assert_equal "This is a veryThis is an arbitrary string.", unit.substitute_prefix("","This is a very")
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_rightmost_of_token
|
77
|
+
assert_equal 'ring.', "This is an arbitrary string.".rightmost_of_token('t')
|
78
|
+
assert_equal '', "This is an arbitrary string.".rightmost_of_token('x')
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sitebuilder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dafydd Rees
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-03 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Static website generator using rule-based translation.
|
17
|
+
email: os@greenbarsoft.co.uk
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- CHANGELOG
|
24
|
+
- COPYING
|
25
|
+
- README.rdoc
|
26
|
+
- TODO.rdoc
|
27
|
+
files:
|
28
|
+
- lib/sitebuilder/array.rb
|
29
|
+
- lib/sitebuilder/filesystem.rb
|
30
|
+
- lib/sitebuilder/gen.rb
|
31
|
+
- lib/sitebuilder/sitegenerator.rb
|
32
|
+
- lib/sitebuilder/string.rb
|
33
|
+
- lib/sitebuilder.rb
|
34
|
+
- test/array_test.rb
|
35
|
+
- test/data/testfile.txt
|
36
|
+
- test/filesystem_test.rb
|
37
|
+
- test/string_test.rb
|
38
|
+
- CHANGELOG
|
39
|
+
- COPYING
|
40
|
+
- README.rdoc
|
41
|
+
- TODO.rdoc
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: http://www.greenbarsoft.co.uk/software/sitebuilder
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.3.5
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Static site generator
|
70
|
+
test_files:
|
71
|
+
- ./test/array_test.rb
|
72
|
+
- ./test/filesystem_test.rb
|
73
|
+
- ./test/string_test.rb
|