mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
hwhoops
This commit is contained in:
@@ -2,8 +2,7 @@ before_install: sudo apt-get install libicu-dev -y
|
|||||||
rvm:
|
rvm:
|
||||||
- 1.8.7
|
- 1.8.7
|
||||||
- 1.9.2
|
- 1.9.2
|
||||||
- jruby
|
- 1.9.3
|
||||||
- rbx
|
|
||||||
- ree
|
- ree
|
||||||
notifications:
|
notifications:
|
||||||
disabled: true
|
disabled: true
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ module Linguist
|
|||||||
#
|
#
|
||||||
# Returns a content type String.
|
# Returns a content type String.
|
||||||
def content_type
|
def content_type
|
||||||
@content_type ||= binary? ? mime_type :
|
@content_type ||= (binary_mime_type? || binary?) ? mime_type :
|
||||||
(encoding ? "text/plain; charset=#{encoding.downcase}" : "text/plain")
|
(encoding ? "text/plain; charset=#{encoding.downcase}" : "text/plain")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -423,8 +423,15 @@ module Linguist
|
|||||||
def guess_cls_language
|
def guess_cls_language
|
||||||
if lines.grep(/^(%|\\)/).any?
|
if lines.grep(/^(%|\\)/).any?
|
||||||
Language['TeX']
|
Language['TeX']
|
||||||
else
|
elsif lines.grep(/^\s*(CLASS|METHOD|INTERFACE).*:\s*/i).any? || lines.grep(/^\s*(USING|DEFINE)/i).any?
|
||||||
Language['OpenEdge ABL']
|
Language['OpenEdge ABL']
|
||||||
|
elsif lines.grep(/\{$/).any? || lines.grep(/\}$/).any?
|
||||||
|
Language['Apex']
|
||||||
|
elsif lines.grep(/^(\'\*|Attribute|Option|Sub|Private|Protected|Public|Friend)/i).any?
|
||||||
|
Language['Visual Basic']
|
||||||
|
else
|
||||||
|
# The most common language should be the fallback
|
||||||
|
Language['TeX']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
require 'yaml'
|
require 'escape_utils'
|
||||||
require 'pygments'
|
require 'pygments'
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
module Linguist
|
module Linguist
|
||||||
# Language names that are recognizable by GitHub. Defined languages
|
# Language names that are recognizable by GitHub. Defined languages
|
||||||
@@ -193,6 +194,13 @@ module Linguist
|
|||||||
@unpopular ||= all.select(&:unpopular?).sort_by { |lang| lang.name.downcase }
|
@unpopular ||= all.select(&:unpopular?).sort_by { |lang| lang.name.downcase }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Public: A List of languages compatible with Ace.
|
||||||
|
#
|
||||||
|
# Returns an Array of Languages.
|
||||||
|
def self.ace_modes
|
||||||
|
@ace_modes ||= all.select(&:ace_mode).sort_by { |lang| lang.name.downcase }
|
||||||
|
end
|
||||||
|
|
||||||
# Internal: Initialize a new Language
|
# Internal: Initialize a new Language
|
||||||
#
|
#
|
||||||
# attributes - A hash of attributes
|
# attributes - A hash of attributes
|
||||||
@@ -213,6 +221,8 @@ module Linguist
|
|||||||
@lexer = Pygments::Lexer.find_by_name(attributes[:lexer] || name) ||
|
@lexer = Pygments::Lexer.find_by_name(attributes[:lexer] || name) ||
|
||||||
raise(ArgumentError, "#{@name} is missing lexer")
|
raise(ArgumentError, "#{@name} is missing lexer")
|
||||||
|
|
||||||
|
@ace_mode = attributes[:ace_mode]
|
||||||
|
|
||||||
# Set legacy search term
|
# Set legacy search term
|
||||||
@search_term = attributes[:search_term] || default_alias_name
|
@search_term = attributes[:search_term] || default_alias_name
|
||||||
|
|
||||||
@@ -285,6 +295,17 @@ module Linguist
|
|||||||
# Returns the Lexer
|
# Returns the Lexer
|
||||||
attr_reader :lexer
|
attr_reader :lexer
|
||||||
|
|
||||||
|
# Public: Get Ace mode
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
#
|
||||||
|
# # => "text"
|
||||||
|
# # => "javascript"
|
||||||
|
# # => "c_cpp"
|
||||||
|
#
|
||||||
|
# Returns a String name or nil
|
||||||
|
attr_reader :ace_mode
|
||||||
|
|
||||||
# Public: Get extensions
|
# Public: Get extensions
|
||||||
#
|
#
|
||||||
# Examples
|
# Examples
|
||||||
@@ -322,6 +343,19 @@ module Linguist
|
|||||||
# Returns the extensions Array
|
# Returns the extensions Array
|
||||||
attr_reader :filenames
|
attr_reader :filenames
|
||||||
|
|
||||||
|
# Public: Get URL escaped name.
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
#
|
||||||
|
# "C%23"
|
||||||
|
# "C%2B%2B"
|
||||||
|
# "Common%20Lisp"
|
||||||
|
#
|
||||||
|
# Returns the escaped String.
|
||||||
|
def escaped_name
|
||||||
|
EscapeUtils.escape_url(name).gsub('+', '%20')
|
||||||
|
end
|
||||||
|
|
||||||
# Internal: Get default alias name
|
# Internal: Get default alias name
|
||||||
#
|
#
|
||||||
# Returns the alias name String
|
# Returns the alias name String
|
||||||
@@ -403,6 +437,7 @@ module Linguist
|
|||||||
:type => options['type'],
|
:type => options['type'],
|
||||||
:aliases => options['aliases'],
|
:aliases => options['aliases'],
|
||||||
:lexer => options['lexer'],
|
:lexer => options['lexer'],
|
||||||
|
:ace_mode => options['ace_mode'],
|
||||||
:group_name => options['group'],
|
:group_name => options['group'],
|
||||||
:searchable => options.key?('searchable') ? options['searchable'] : true,
|
:searchable => options.key?('searchable') ? options['searchable'] : true,
|
||||||
:search_term => options['search_term'],
|
:search_term => options['search_term'],
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
# lexer - An explicit lexer String (defaults to name.downcase)
|
# lexer - An explicit lexer String (defaults to name.downcase)
|
||||||
# aliases - An Array of additional aliases (implicitly
|
# aliases - An Array of additional aliases (implicitly
|
||||||
# includes name.downcase)
|
# includes name.downcase)
|
||||||
|
# ace_mode - A String name of Ace Mode (if available)
|
||||||
# extension - An Array of associated extensions
|
# extension - An Array of associated extensions
|
||||||
# primary_extension - A String for the main extension associated with
|
# primary_extension - A String for the main extension associated with
|
||||||
# the langauge. (defaults to extensions.first)
|
# the langauge. (defaults to extensions.first)
|
||||||
@@ -54,6 +55,12 @@ Ada:
|
|||||||
- .adb
|
- .adb
|
||||||
- .ads
|
- .ads
|
||||||
|
|
||||||
|
Apex:
|
||||||
|
type: programming
|
||||||
|
lexer: Text only
|
||||||
|
extensions:
|
||||||
|
- .cls
|
||||||
|
|
||||||
AppleScript:
|
AppleScript:
|
||||||
aliases:
|
aliases:
|
||||||
- osascript
|
- osascript
|
||||||
@@ -137,6 +144,7 @@ C:
|
|||||||
|
|
||||||
C#:
|
C#:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: csharp
|
||||||
search_term: csharp
|
search_term: csharp
|
||||||
aliases:
|
aliases:
|
||||||
- csharp
|
- csharp
|
||||||
@@ -145,6 +153,7 @@ C#:
|
|||||||
|
|
||||||
C++:
|
C++:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: c_cpp
|
||||||
search_term: cpp
|
search_term: cpp
|
||||||
aliases:
|
aliases:
|
||||||
- cpp
|
- cpp
|
||||||
@@ -185,6 +194,7 @@ CMake:
|
|||||||
- CMakeLists.txt
|
- CMakeLists.txt
|
||||||
|
|
||||||
CSS:
|
CSS:
|
||||||
|
ace_mode: css
|
||||||
extensions:
|
extensions:
|
||||||
- .css
|
- .css
|
||||||
|
|
||||||
@@ -195,6 +205,7 @@ ChucK:
|
|||||||
|
|
||||||
Clojure:
|
Clojure:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: clojure
|
||||||
primary_extension: .clj
|
primary_extension: .clj
|
||||||
extensions:
|
extensions:
|
||||||
- .clj
|
- .clj
|
||||||
@@ -202,6 +213,7 @@ Clojure:
|
|||||||
|
|
||||||
CoffeeScript:
|
CoffeeScript:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: coffee
|
||||||
aliases:
|
aliases:
|
||||||
- coffee
|
- coffee
|
||||||
extensions:
|
extensions:
|
||||||
@@ -212,6 +224,7 @@ CoffeeScript:
|
|||||||
ColdFusion:
|
ColdFusion:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Coldfusion HTML
|
lexer: Coldfusion HTML
|
||||||
|
ace_mode: coldfusion
|
||||||
search_term: cfm
|
search_term: cfm
|
||||||
aliases:
|
aliases:
|
||||||
- cfm
|
- cfm
|
||||||
@@ -227,6 +240,7 @@ Common Lisp:
|
|||||||
primary_extension: .lisp
|
primary_extension: .lisp
|
||||||
extensions:
|
extensions:
|
||||||
- .lisp
|
- .lisp
|
||||||
|
- .lsp
|
||||||
- .ny
|
- .ny
|
||||||
|
|
||||||
Coq:
|
Coq:
|
||||||
@@ -295,6 +309,13 @@ Dylan:
|
|||||||
extensions:
|
extensions:
|
||||||
- .dylan
|
- .dylan
|
||||||
|
|
||||||
|
Ecere Projects:
|
||||||
|
type: data
|
||||||
|
group: JavaScript
|
||||||
|
lexer: JSON
|
||||||
|
extensions:
|
||||||
|
- .epj
|
||||||
|
|
||||||
Eiffel:
|
Eiffel:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Text only
|
lexer: Text only
|
||||||
@@ -328,7 +349,7 @@ Erlang:
|
|||||||
|
|
||||||
F#:
|
F#:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: OCaml
|
lexer: FSharp
|
||||||
search_term: ocaml
|
search_term: ocaml
|
||||||
extensions:
|
extensions:
|
||||||
- .fs
|
- .fs
|
||||||
@@ -371,7 +392,6 @@ Fancy:
|
|||||||
|
|
||||||
Fantom:
|
Fantom:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Java
|
|
||||||
extensions:
|
extensions:
|
||||||
- .fan
|
- .fan
|
||||||
|
|
||||||
@@ -437,7 +457,7 @@ Groff:
|
|||||||
|
|
||||||
Groovy:
|
Groovy:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Java
|
ace_mode: groovy
|
||||||
primary_extension: .groovy
|
primary_extension: .groovy
|
||||||
extensions:
|
extensions:
|
||||||
- .gradle
|
- .gradle
|
||||||
@@ -455,6 +475,7 @@ Groovy Server Pages:
|
|||||||
|
|
||||||
HTML:
|
HTML:
|
||||||
type: markup
|
type: markup
|
||||||
|
ace_mode: html
|
||||||
primary_extension: .html
|
primary_extension: .html
|
||||||
extensions:
|
extensions:
|
||||||
- .htm
|
- .htm
|
||||||
@@ -487,6 +508,7 @@ HTML+PHP:
|
|||||||
HaXe:
|
HaXe:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: haXe
|
lexer: haXe
|
||||||
|
ace_mode: haxe
|
||||||
extensions:
|
extensions:
|
||||||
- .hx
|
- .hx
|
||||||
- .hxml
|
- .hxml
|
||||||
@@ -535,13 +557,14 @@ Ioke:
|
|||||||
JSON:
|
JSON:
|
||||||
type: data
|
type: data
|
||||||
group: JavaScript
|
group: JavaScript
|
||||||
lexer: JavaScript
|
ace_mode: json
|
||||||
searchable: false
|
searchable: false
|
||||||
extensions:
|
extensions:
|
||||||
- .json
|
- .json
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: java
|
||||||
extensions:
|
extensions:
|
||||||
- .java
|
- .java
|
||||||
- .pde
|
- .pde
|
||||||
@@ -557,6 +580,7 @@ Java Server Pages:
|
|||||||
|
|
||||||
JavaScript:
|
JavaScript:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: javascript
|
||||||
aliases:
|
aliases:
|
||||||
- js
|
- js
|
||||||
- node
|
- node
|
||||||
@@ -565,6 +589,7 @@ JavaScript:
|
|||||||
- .bones
|
- .bones
|
||||||
- .jake
|
- .jake
|
||||||
- .js
|
- .js
|
||||||
|
- .jsfl
|
||||||
- .jsm
|
- .jsm
|
||||||
- .jss
|
- .jss
|
||||||
- .jsx
|
- .jsx
|
||||||
@@ -574,6 +599,14 @@ JavaScript:
|
|||||||
filenames:
|
filenames:
|
||||||
- Jakefile
|
- Jakefile
|
||||||
|
|
||||||
|
Kotlin:
|
||||||
|
type: programming
|
||||||
|
lexer: Kotlin
|
||||||
|
extensions:
|
||||||
|
- .kt
|
||||||
|
- .ktm
|
||||||
|
- .kts
|
||||||
|
|
||||||
LLVM:
|
LLVM:
|
||||||
extensions:
|
extensions:
|
||||||
- .ll
|
- .ll
|
||||||
@@ -602,6 +635,7 @@ Logtalk:
|
|||||||
|
|
||||||
Lua:
|
Lua:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: lua
|
||||||
primary_extension: .lua
|
primary_extension: .lua
|
||||||
extensions:
|
extensions:
|
||||||
- .lua
|
- .lua
|
||||||
@@ -624,6 +658,7 @@ Mako:
|
|||||||
Markdown:
|
Markdown:
|
||||||
type: markup
|
type: markup
|
||||||
lexer: Text only
|
lexer: Text only
|
||||||
|
ace_mode: markdown
|
||||||
primary_extension: .md
|
primary_extension: .md
|
||||||
extensions:
|
extensions:
|
||||||
- .markdown
|
- .markdown
|
||||||
@@ -698,6 +733,7 @@ NumPy:
|
|||||||
|
|
||||||
OCaml:
|
OCaml:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: ocaml
|
||||||
primary_extension: .ml
|
primary_extension: .ml
|
||||||
extensions:
|
extensions:
|
||||||
- .ml
|
- .ml
|
||||||
@@ -729,7 +765,6 @@ Objective-J:
|
|||||||
|
|
||||||
Opa:
|
Opa:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Text only
|
|
||||||
extensions:
|
extensions:
|
||||||
- .opa
|
- .opa
|
||||||
|
|
||||||
@@ -747,14 +782,13 @@ OpenEdge ABL:
|
|||||||
- openedge
|
- openedge
|
||||||
- abl
|
- abl
|
||||||
primary_extension: .p
|
primary_extension: .p
|
||||||
overrides:
|
|
||||||
- .cls
|
|
||||||
extensions:
|
extensions:
|
||||||
- .cls
|
- .cls
|
||||||
- .p
|
- .p
|
||||||
|
|
||||||
PHP:
|
PHP:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: php
|
||||||
extensions:
|
extensions:
|
||||||
- .aw
|
- .aw
|
||||||
- .ctp
|
- .ctp
|
||||||
@@ -763,6 +797,8 @@ PHP:
|
|||||||
- .php4
|
- .php4
|
||||||
- .php5
|
- .php5
|
||||||
- .phpt
|
- .phpt
|
||||||
|
filenames:
|
||||||
|
- Phakefile
|
||||||
|
|
||||||
Parrot:
|
Parrot:
|
||||||
type: programming
|
type: programming
|
||||||
@@ -789,6 +825,7 @@ Parrot Assembly:
|
|||||||
|
|
||||||
Perl:
|
Perl:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: perl
|
||||||
overrides:
|
overrides:
|
||||||
- .pl
|
- .pl
|
||||||
- .t
|
- .t
|
||||||
@@ -804,9 +841,9 @@ Perl:
|
|||||||
- .psgi
|
- .psgi
|
||||||
- .t
|
- .t
|
||||||
|
|
||||||
Powershell:
|
PowerShell:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Text only
|
ace_mode: powershell
|
||||||
aliases:
|
aliases:
|
||||||
- posh
|
- posh
|
||||||
extensions:
|
extensions:
|
||||||
@@ -825,6 +862,8 @@ Puppet:
|
|||||||
lexer: Text only
|
lexer: Text only
|
||||||
extensions:
|
extensions:
|
||||||
- .pp
|
- .pp
|
||||||
|
filenames:
|
||||||
|
- Modulefile
|
||||||
|
|
||||||
Pure Data:
|
Pure Data:
|
||||||
type: programming
|
type: programming
|
||||||
@@ -834,6 +873,7 @@ Pure Data:
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: python
|
||||||
primary_extension: .py
|
primary_extension: .py
|
||||||
extensions:
|
extensions:
|
||||||
- .py
|
- .py
|
||||||
@@ -897,6 +937,7 @@ Redcode:
|
|||||||
|
|
||||||
Ruby:
|
Ruby:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: ruby
|
||||||
aliases:
|
aliases:
|
||||||
- jruby
|
- jruby
|
||||||
- macruby
|
- macruby
|
||||||
@@ -937,11 +978,13 @@ Rust:
|
|||||||
SCSS:
|
SCSS:
|
||||||
type: markup
|
type: markup
|
||||||
group: CSS
|
group: CSS
|
||||||
|
ace_mode: scss
|
||||||
extensions:
|
extensions:
|
||||||
- .scss
|
- .scss
|
||||||
|
|
||||||
SQL:
|
SQL:
|
||||||
type: data
|
type: data
|
||||||
|
ace_mode: sql
|
||||||
searchable: false
|
searchable: false
|
||||||
extensions:
|
extensions:
|
||||||
- .sql
|
- .sql
|
||||||
@@ -962,6 +1005,7 @@ Sass:
|
|||||||
|
|
||||||
Scala:
|
Scala:
|
||||||
type: programming
|
type: programming
|
||||||
|
ace_mode: scala
|
||||||
primary_extension: .scala
|
primary_extension: .scala
|
||||||
extensions:
|
extensions:
|
||||||
- .sbt
|
- .sbt
|
||||||
@@ -1052,7 +1096,10 @@ Tcsh:
|
|||||||
|
|
||||||
TeX:
|
TeX:
|
||||||
type: markup
|
type: markup
|
||||||
|
ace_mode: latex
|
||||||
primary_extension: .tex
|
primary_extension: .tex
|
||||||
|
overrides:
|
||||||
|
- .cls
|
||||||
extensions:
|
extensions:
|
||||||
- .aux
|
- .aux
|
||||||
- .cls
|
- .cls
|
||||||
@@ -1063,15 +1110,23 @@ TeX:
|
|||||||
- .tex
|
- .tex
|
||||||
- .toc
|
- .toc
|
||||||
|
|
||||||
|
Tea:
|
||||||
|
type: markup
|
||||||
|
lexer: Tea
|
||||||
|
extensions:
|
||||||
|
- .tea
|
||||||
|
|
||||||
Text:
|
Text:
|
||||||
type: data
|
type: data
|
||||||
lexer: Text only
|
lexer: Text only
|
||||||
|
ace_mode: text
|
||||||
extensions:
|
extensions:
|
||||||
- .txt
|
- .txt
|
||||||
|
|
||||||
Textile:
|
Textile:
|
||||||
type: markup
|
type: markup
|
||||||
lexer: Text only
|
lexer: Text only
|
||||||
|
ace_mode: textile
|
||||||
extensions:
|
extensions:
|
||||||
- .textile
|
- .textile
|
||||||
|
|
||||||
@@ -1092,7 +1147,7 @@ Twig:
|
|||||||
|
|
||||||
VHDL:
|
VHDL:
|
||||||
type: programming
|
type: programming
|
||||||
lexer: Text only
|
lexer: vhdl
|
||||||
primary_extension: .vhd
|
primary_extension: .vhd
|
||||||
extensions:
|
extensions:
|
||||||
- .vhd
|
- .vhd
|
||||||
@@ -1138,6 +1193,7 @@ Visual Basic:
|
|||||||
|
|
||||||
XML:
|
XML:
|
||||||
type: markup
|
type: markup
|
||||||
|
ace_mode: xml
|
||||||
primary_extension: .xml
|
primary_extension: .xml
|
||||||
extensions:
|
extensions:
|
||||||
- .glade
|
- .glade
|
||||||
@@ -1184,6 +1240,14 @@ YAML:
|
|||||||
filenames:
|
filenames:
|
||||||
- .gemrc
|
- .gemrc
|
||||||
|
|
||||||
|
eC:
|
||||||
|
type: programming
|
||||||
|
search_term: ec
|
||||||
|
primary_extension: .ec
|
||||||
|
extensions:
|
||||||
|
- .ec
|
||||||
|
- .eh
|
||||||
|
|
||||||
mupad:
|
mupad:
|
||||||
lexer: MuPAD
|
lexer: MuPAD
|
||||||
extensions:
|
extensions:
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
require 'mime/types'
|
require 'mime/types'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
|
||||||
|
class MIME::Type
|
||||||
|
attr_accessor :override
|
||||||
|
end
|
||||||
|
|
||||||
# Register additional mime type extensions
|
# Register additional mime type extensions
|
||||||
#
|
#
|
||||||
# Follows same format as mime-types data file
|
# Follows same format as mime-types data file
|
||||||
@@ -33,6 +37,8 @@ File.read(File.expand_path("../mimes.yml", __FILE__)).lines.each do |line|
|
|||||||
mime_type.encoding = encoding
|
mime_type.encoding = encoding
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mime_type.override = true
|
||||||
|
|
||||||
# Kind of hacky, but we need to reindex the mime type after making changes
|
# Kind of hacky, but we need to reindex the mime type after making changes
|
||||||
MIME::Types.add_type_variant(mime_type)
|
MIME::Types.add_type_variant(mime_type)
|
||||||
MIME::Types.index_extensions(mime_type)
|
MIME::Types.index_extensions(mime_type)
|
||||||
@@ -72,6 +78,9 @@ module Linguist
|
|||||||
guesses = ::MIME::Types.type_for(ext_or_mime_type)
|
guesses = ::MIME::Types.type_for(ext_or_mime_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Use custom override first
|
||||||
|
guesses.detect { |type| type.override } ||
|
||||||
|
|
||||||
# Prefer text mime types over binary
|
# Prefer text mime types over binary
|
||||||
guesses.detect { |type| type.ascii? } ||
|
guesses.detect { |type| type.ascii? } ||
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
- ^tools/
|
- ^tools/
|
||||||
|
|
||||||
# Node depedencies
|
# Node depedencies
|
||||||
- ^node_modules/
|
- node_modules/
|
||||||
|
|
||||||
# Vendored depedencies
|
# Vendored depedencies
|
||||||
- vendor/
|
- vendor/
|
||||||
@@ -88,4 +88,9 @@
|
|||||||
|
|
||||||
# NuGet
|
# NuGet
|
||||||
- ^[Pp]ackages/
|
- ^[Pp]ackages/
|
||||||
|
|
||||||
|
# ExtJS
|
||||||
|
- (^|/)ext(js)?(-\d\.\d\.\d)?(-gpl)?/
|
||||||
|
|
||||||
|
# Samples folders
|
||||||
- ^[Ss]amples/
|
- ^[Ss]amples/
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|||||||
|
|
||||||
s.add_dependency 'charlock_holmes', '~> 0.6.6'
|
s.add_dependency 'charlock_holmes', '~> 0.6.6'
|
||||||
s.add_dependency 'escape_utils', '~> 0.2.3'
|
s.add_dependency 'escape_utils', '~> 0.2.3'
|
||||||
s.add_dependency 'mime-types', '~> 1.16'
|
s.add_dependency 'mime-types', '~> 1.18'
|
||||||
s.add_dependency 'pygments.rb', '~> 0.2.7'
|
s.add_dependency 'pygments.rb', '~> 0.2.8'
|
||||||
s.add_development_dependency 'rake'
|
s.add_development_dependency 'rake'
|
||||||
end
|
end
|
||||||
|
|||||||
458
test/fixtures/ArrayUtils.cls
vendored
Normal file
458
test/fixtures/ArrayUtils.cls
vendored
Normal file
@@ -0,0 +1,458 @@
|
|||||||
|
/* ============================================================
|
||||||
|
* This code is part of the "apex-lang" open source project avaiable at:
|
||||||
|
*
|
||||||
|
* http://code.google.com/p/apex-lang/
|
||||||
|
*
|
||||||
|
* This code is licensed under the Apache License, Version 2.0. You may obtain a
|
||||||
|
* copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* ============================================================
|
||||||
|
*/
|
||||||
|
global class ArrayUtils {
|
||||||
|
|
||||||
|
global static String[] EMPTY_STRING_ARRAY = new String[]{};
|
||||||
|
global static Integer MAX_NUMBER_OF_ELEMENTS_IN_LIST {get{return 1000;}}
|
||||||
|
|
||||||
|
global static List<String> objectToString(List<Object> objects){
|
||||||
|
List<String> strings = null;
|
||||||
|
if(objects != null){
|
||||||
|
strings = new List<String>();
|
||||||
|
if(objects.size() > 0){
|
||||||
|
for(Object obj : objects){
|
||||||
|
if(obj instanceof String){
|
||||||
|
strings.add((String)obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Object[] reverse(Object[] anArray) {
|
||||||
|
if (anArray == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Integer i = 0;
|
||||||
|
Integer j = anArray.size() - 1;
|
||||||
|
Object tmp;
|
||||||
|
while (j > i) {
|
||||||
|
tmp = anArray[j];
|
||||||
|
anArray[j] = anArray[i];
|
||||||
|
anArray[i] = tmp;
|
||||||
|
j--;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return anArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static SObject[] reverse(SObject[] anArray) {
|
||||||
|
if (anArray == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Integer i = 0;
|
||||||
|
Integer j = anArray.size() - 1;
|
||||||
|
SObject tmp;
|
||||||
|
while (j > i) {
|
||||||
|
tmp = anArray[j];
|
||||||
|
anArray[j] = anArray[i];
|
||||||
|
anArray[i] = tmp;
|
||||||
|
j--;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return anArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<String> lowerCase(List<String> strs){
|
||||||
|
List<String> returnValue = null;
|
||||||
|
if(strs != null){
|
||||||
|
returnValue = new List<String>();
|
||||||
|
if(strs.size() > 0){
|
||||||
|
for(String str : strs){
|
||||||
|
returnValue.add(str == null ? null : str.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<String> upperCase(List<String> strs){
|
||||||
|
List<String> returnValue = null;
|
||||||
|
if(strs != null){
|
||||||
|
returnValue = new List<String>();
|
||||||
|
if(strs.size() > 0){
|
||||||
|
for(String str : strs){
|
||||||
|
returnValue.add(str == null ? null : str.toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<String> trim(List<String> strs){
|
||||||
|
List<String> returnValue = null;
|
||||||
|
if(strs != null){
|
||||||
|
returnValue = new List<String>();
|
||||||
|
if(strs.size() > 0){
|
||||||
|
for(String str : strs){
|
||||||
|
returnValue.add(str == null ? null : str.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Object[] mergex(Object[] array1, Object[] array2){
|
||||||
|
if(array1 == null){ return array2; }
|
||||||
|
if(array2 == null){ return array1; }
|
||||||
|
Object[] merged = new Object[array1.size() + array2.size()];
|
||||||
|
for(Integer i = 0; i < array1.size(); i++){
|
||||||
|
merged[i] = array1[i];
|
||||||
|
}
|
||||||
|
for(Integer i = 0; i < array2.size(); i++){
|
||||||
|
merged[i+array1.size()] = array2[i];
|
||||||
|
}
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static SObject[] mergex(SObject[] array1, SObject[] array2){
|
||||||
|
if(array1 == null){ return array2; }
|
||||||
|
if(array2 == null){ return array1; }
|
||||||
|
if(array1.size() <= 0){ return array2; }
|
||||||
|
List<SObject> merged = new List<SObject>();
|
||||||
|
for(SObject sObj : array1){ merged.add(sObj); }
|
||||||
|
for(SObject sObj : array2){ merged.add(sObj); }
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Boolean isEmpty(Object[] objectArray){
|
||||||
|
if(objectArray == null){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return objectArray.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Boolean isEmpty(SObject[] objectArray){
|
||||||
|
if(objectArray == null){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return objectArray.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Boolean isNotEmpty(Object[] objectArray){
|
||||||
|
return !isEmpty(objectArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Boolean isNotEmpty(SObject[] objectArray){
|
||||||
|
return !isEmpty(objectArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static Object[] pluck(SObject[] objectArray, String fieldName){
|
||||||
|
if(isEmpty(objectArray) || fieldName == null || fieldName.trim() == null || fieldName.trim().length() == 0){
|
||||||
|
return new Object[]{};
|
||||||
|
}
|
||||||
|
Object[] plucked = new Object[objectArray.size()];
|
||||||
|
for(Integer i = 0; i < objectArray.size(); i++){
|
||||||
|
plucked[i] = objectArray[i].get(fieldName);
|
||||||
|
}
|
||||||
|
return plucked;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
global static String toString(Object[] objectArray){
|
||||||
|
if(objectArray == null){
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
String returnValue = '{';
|
||||||
|
for(Integer i = 0; i < objectArray.size(); i++){
|
||||||
|
if(i!=0){ returnValue += ','; }
|
||||||
|
returnValue += '\'' + objectArray[i] + '\'';
|
||||||
|
}
|
||||||
|
returnValue += '}';
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static String toString(SObject[] objectArray){
|
||||||
|
if(objectArray == null){
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
String returnValue = '{';
|
||||||
|
for(Integer i = 0; i < objectArray.size(); i++){
|
||||||
|
if(i!=0){ returnValue += ','; }
|
||||||
|
returnValue += '\'' + objectArray[i] + '\'';
|
||||||
|
}
|
||||||
|
returnValue += '}';
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static void assertArraysAreEqual(Object[] expected, Object[] actual){
|
||||||
|
//check to see if one param is null but the other is not
|
||||||
|
System.assert((expected == null && actual == null)|| (expected != null && actual != null),
|
||||||
|
'Assertion failed, the following two arrays are not equal. Expected: '
|
||||||
|
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||||
|
if(expected != null && actual != null){
|
||||||
|
System.assert(expected.size() == actual.size(), 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||||
|
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||||
|
for(Integer i = 0; i < expected.size(); i++){
|
||||||
|
System.assert(expected[i] == actual[i], 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||||
|
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global static void assertArraysAreEqual(SObject[] expected, SObject[] actual){
|
||||||
|
//check to see if one param is null but the other is not
|
||||||
|
System.assert((expected == null && actual == null)|| (expected != null && actual != null),
|
||||||
|
'Assertion failed, the following two arrays are not equal. Expected: '
|
||||||
|
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||||
|
if(expected != null && actual != null){
|
||||||
|
System.assert(expected.size() == actual.size(), 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||||
|
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||||
|
for(Integer i = 0; i < expected.size(); i++){
|
||||||
|
System.assert(expected[i] == actual[i], 'Assertion failed, the following two arrays are not equal. Expected: '
|
||||||
|
+ ArrayUtils.toString(expected) + ', Actual: ' + ArrayUtils.toString(actual));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<Object> merg(List<Object> list1, List<Object> list2) {
|
||||||
|
List<Object> returnList = new List<Object>();
|
||||||
|
if(list1 != null && list2 != null && (list1.size()+list2.size()) > MAX_NUMBER_OF_ELEMENTS_IN_LIST){
|
||||||
|
throw new IllegalArgumentException('Lists cannot be merged because new list would be greater than maximum number of elements in a list: ' + MAX_NUMBER_OF_ELEMENTS_IN_LIST);
|
||||||
|
}
|
||||||
|
if(isNotEmpty(list1)){
|
||||||
|
for(Object elmt : list1){
|
||||||
|
returnList.add(elmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isNotEmpty(list2)){
|
||||||
|
for(Object elmt : list2){
|
||||||
|
returnList.add(elmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
global static List<SObject> merg(List<SObject> list1, List<SObject> list2) {
|
||||||
|
if(list1 != null && list2 != null && (list1.size()+list2.size()) > MAX_NUMBER_OF_ELEMENTS_IN_LIST){
|
||||||
|
throw new IllegalArgumentException('Lists cannot be merged because new list would be greater than maximum number of elements in a list: ' + MAX_NUMBER_OF_ELEMENTS_IN_LIST);
|
||||||
|
}
|
||||||
|
if(isEmpty(list1) && isEmpty(list2)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<SObject> returnList = new List<SObject>();
|
||||||
|
if(list1 != null){
|
||||||
|
for(SObject elmt : list1){
|
||||||
|
returnList.add(elmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(list2 != null){
|
||||||
|
for(SObject elmt : list2){
|
||||||
|
returnList.add(elmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<Object> subset(List<Object> aList, Integer count) {
|
||||||
|
return subset(aList,0,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<Object> subset(List<Object> list1, Integer startIndex, Integer count) {
|
||||||
|
List<Object> returnList = new List<Object>();
|
||||||
|
if(list1 != null && list1.size() > 0 && startIndex >= 0 && startIndex <= list1.size()-1 && count > 0){
|
||||||
|
for(Integer i = startIndex; i < list1.size() && i - startIndex < count; i++){
|
||||||
|
returnList.add(list1.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
global static List<SObject> subset(List<SObject> aList, Integer count) {
|
||||||
|
return subset(aList,0,count);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<SObject> subset(List<SObject> list1, Integer startIndex, Integer count) {
|
||||||
|
List<SObject> returnList = null;
|
||||||
|
if(list1 != null && list1.size() > 0 && startIndex <= list1.size()-1 && count > 0){
|
||||||
|
returnList = new List<SObject>();
|
||||||
|
for(Integer i = startIndex; i < list1.size() && i - startIndex < count; i++){
|
||||||
|
returnList.add(list1.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===============================================
|
||||||
|
//LIST/ARRAY SORTING
|
||||||
|
//===============================================
|
||||||
|
|
||||||
|
//FOR FORCE.COM PRIMITIVES (Double,Integer,ID,etc.):
|
||||||
|
global static List<Object> qsort(List<Object> theList) {
|
||||||
|
return qsort(theList,new PrimitiveComparator());
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<Object> qsort(List<Object> theList, Boolean sortAsc) {
|
||||||
|
return qsort(theList,new PrimitiveComparator(),sortAsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<Object> qsort(List<Object> theList, ObjectComparator comparator) {
|
||||||
|
return qsort(theList,comparator,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<Object> qsort(List<Object> theList, ObjectComparator comparator, Boolean sortAsc) {
|
||||||
|
return qsort(theList, 0, (theList == null ? 0 : theList.size()-1),comparator,sortAsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//FOR SALESFORCE OBJECTS (sObjects):
|
||||||
|
global static List<SObject> qsort(List<SObject> theList, ISObjectComparator comparator) {
|
||||||
|
return qsort(theList,comparator,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<SObject> qsort(List<SObject> theList, ISObjectComparator comparator,Boolean sortAsc ) {
|
||||||
|
return qsort(theList, 0, (theList == null ? 0 : theList.size()-1),comparator,sortAsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Object> qsort(List<Object> theList,
|
||||||
|
Integer lo0,
|
||||||
|
Integer hi0,
|
||||||
|
ObjectComparator comparator,
|
||||||
|
Boolean sortAsc){
|
||||||
|
Integer lo = lo0;
|
||||||
|
Integer hi = hi0;
|
||||||
|
|
||||||
|
if (lo >= hi) {
|
||||||
|
return theList;
|
||||||
|
} else if( lo == hi - 1 ) {
|
||||||
|
|
||||||
|
if (( comparator.compare(theList[lo],theList[hi])>0 && sortAsc) ||
|
||||||
|
(comparator.compare(theList[lo],theList[hi])<0 && !sortAsc)
|
||||||
|
) {
|
||||||
|
Object prs = theList[lo];
|
||||||
|
theList[lo] = theList[hi];
|
||||||
|
theList[hi] = prs;
|
||||||
|
}
|
||||||
|
return theList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object pivot = theList[(lo + hi) / 2];
|
||||||
|
theList[(lo + hi) / 2] = theList[hi];
|
||||||
|
theList[hi] = pivot;
|
||||||
|
|
||||||
|
while( lo < hi ) {
|
||||||
|
while ((comparator.compare(theList[lo], pivot)<=0 && lo < hi && sortAsc) ||
|
||||||
|
(comparator.compare(theList[lo], pivot)>=0 && lo < hi && !sortAsc)
|
||||||
|
) { lo++; }
|
||||||
|
while (( comparator.compare(pivot,theList[hi])<=0 && lo < hi && sortAsc) ||
|
||||||
|
( comparator.compare(pivot,theList[hi])>=0 && lo < hi && !sortAsc)
|
||||||
|
) { hi--; }
|
||||||
|
|
||||||
|
if( lo < hi ){
|
||||||
|
Object prs = theList[lo];
|
||||||
|
theList[lo] = theList[hi];
|
||||||
|
theList[hi] = prs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
theList[hi0] = theList[hi];
|
||||||
|
theList[hi] = pivot;
|
||||||
|
|
||||||
|
qsort(theList, lo0, lo-1,comparator,sortAsc);
|
||||||
|
qsort(theList, hi+1, hi0,comparator,sortAsc);
|
||||||
|
return theList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static List<SObject> qsort(List<SObject> theList,
|
||||||
|
Integer lo0,
|
||||||
|
Integer hi0,
|
||||||
|
ISObjectComparator comparator,
|
||||||
|
Boolean sortAsc){
|
||||||
|
Integer lo = lo0;
|
||||||
|
Integer hi = hi0;
|
||||||
|
|
||||||
|
if (lo >= hi) {
|
||||||
|
return theList;
|
||||||
|
} else if( lo == hi - 1 ) {
|
||||||
|
|
||||||
|
if (( comparator.compare(theList[lo],theList[hi])>0 && sortAsc) ||
|
||||||
|
(comparator.compare(theList[lo],theList[hi])<0 && !sortAsc)
|
||||||
|
) {
|
||||||
|
SObject prs = theList[lo];
|
||||||
|
theList[lo] = theList[hi];
|
||||||
|
theList[hi] = prs;
|
||||||
|
}
|
||||||
|
return theList;
|
||||||
|
}
|
||||||
|
|
||||||
|
SObject pivot = theList[(lo + hi) / 2];
|
||||||
|
theList[(lo + hi) / 2] = theList[hi];
|
||||||
|
theList[hi] = pivot;
|
||||||
|
|
||||||
|
while( lo < hi ) {
|
||||||
|
while ((comparator.compare(theList[lo], pivot)<=0 && lo < hi && sortAsc) ||
|
||||||
|
(comparator.compare(theList[lo], pivot)>=0 && lo < hi && !sortAsc)
|
||||||
|
) { lo++; }
|
||||||
|
while (( comparator.compare(pivot,theList[hi])<=0 && lo < hi && sortAsc) ||
|
||||||
|
( comparator.compare(pivot,theList[hi])>=0 && lo < hi && !sortAsc)
|
||||||
|
) { hi--; }
|
||||||
|
|
||||||
|
if( lo < hi ){
|
||||||
|
SObject prs = theList[lo];
|
||||||
|
theList[lo] = theList[hi];
|
||||||
|
theList[hi] = prs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
theList[hi0] = theList[hi];
|
||||||
|
theList[hi] = pivot;
|
||||||
|
|
||||||
|
qsort(theList, lo0, lo-1,comparator,sortAsc);
|
||||||
|
qsort(theList, hi+1, hi0,comparator,sortAsc);
|
||||||
|
return theList;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
global static List<Object> unique(List<Object> theList) {
|
||||||
|
List<Object> uniques = new List<Object>();
|
||||||
|
Set<Object> keys = new Set<Object>();
|
||||||
|
if(theList != null && theList.size() > 0){
|
||||||
|
for(Object obj : theList){
|
||||||
|
if(keys.contains(obj)){
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
keys.add(obj);
|
||||||
|
uniques.add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uniques;
|
||||||
|
}
|
||||||
|
|
||||||
|
global static List<SObject> unique(List<SObject> theList) {
|
||||||
|
if(theList == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<SObject> uniques = createEmptySObjectList(theList.get(0));
|
||||||
|
Set<String> keys = new Set<String>();
|
||||||
|
if(theList != null && theList.size() > 0){
|
||||||
|
String key = null;
|
||||||
|
for(SObject obj : theList){
|
||||||
|
key = obj == null ? null : ''+obj;
|
||||||
|
if(keys.contains(key)){
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
keys.add(key);
|
||||||
|
uniques.add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uniques;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
574
test/fixtures/Email.cls
vendored
Normal file
574
test/fixtures/Email.cls
vendored
Normal file
@@ -0,0 +1,574 @@
|
|||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
File : Email
|
||||||
|
Purpose : Abstraction of an Email message
|
||||||
|
Description : Holds information needed for an email message - senders,
|
||||||
|
recipients, subject, a message body, attachment files, and
|
||||||
|
other extra information such as importance, priority,
|
||||||
|
sensitivity, custom reply-to addresses, delivery receipts,
|
||||||
|
read receipts, custom sent date, reply-by date, and expire date.
|
||||||
|
Author(s) : Abe Voelker
|
||||||
|
Created : Sat Jul 17 16:27:05 CDT 2010
|
||||||
|
----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
USING Progress.Lang.*.
|
||||||
|
|
||||||
|
|
||||||
|
CLASS email.Email USE-WIDGET-POOL:
|
||||||
|
|
||||||
|
&SCOPED-DEFINE QUOTES """"
|
||||||
|
&SCOPED-DEFINE CR CHR(13)
|
||||||
|
&SCOPED-DEFINE LF CHR(10)
|
||||||
|
&SCOPED-DEFINE DEFAULT_MIME_BOUNDARY "!@#$%^&*+-._MIME_BOUNDARY_.-+*&^%$#@!"
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
Purpose:
|
||||||
|
Notes:
|
||||||
|
------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DEFINE PRIVATE VARIABLE objSendEmailAlgorithm AS email.SendEmailAlgorithm NO-UNDO.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttSenders NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttSenders cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttToRecipients NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttToRecipients cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttCCRecipients NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttCCRecipients cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttBCCRecipients NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttBCCRecipients cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttReplyToRecipients NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttReplyToRecipients cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttReadReceiptRecipients NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttReadReceiptRecipients cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttDeliveryReceiptRecipients NO-UNDO
|
||||||
|
FIELD cEmailAddress AS CHARACTER
|
||||||
|
FIELD cRealName AS CHARACTER INITIAL ?
|
||||||
|
INDEX IXPK_ttDeliveryReceiptRecipients cEmailAddress.
|
||||||
|
|
||||||
|
DEFINE PRIVATE TEMP-TABLE ttAttachments NO-UNDO
|
||||||
|
FIELD cFileName AS CHARACTER
|
||||||
|
FIELD lcData AS Object /* Longchar object */
|
||||||
|
FIELD lBase64Encode AS LOGICAL.
|
||||||
|
|
||||||
|
DEFINE PRIVATE VARIABLE cMimeBoundary AS CHARACTER NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE lcBody AS LONGCHAR NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE lBodyIsBase64 AS LOGICAL NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE cSubject AS CHARACTER NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE mptrAttachments AS MEMPTR NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE cImportance AS CHARACTER NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE cSensitivity AS CHARACTER NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE cPriority AS CHARACTER NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE dttmtzSentDate AS DATETIME-TZ INITIAL ? NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE dttmtzReplyByDate AS DATETIME-TZ INITIAL ? NO-UNDO.
|
||||||
|
DEFINE PRIVATE VARIABLE dttmtzExpireDate AS DATETIME-TZ INITIAL ? NO-UNDO.
|
||||||
|
|
||||||
|
DEFINE PRIVATE VARIABLE cNewLine AS CHARACTER NO-UNDO.
|
||||||
|
|
||||||
|
/* Other email headers: */
|
||||||
|
|
||||||
|
CONSTRUCTOR PUBLIC Email (INPUT ipobjSendEmailAlgorithm AS email.SendEmailAlgorithm):
|
||||||
|
SUPER ().
|
||||||
|
ASSIGN objSendEmailAlgorithm = ipobjSendEmailAlgorithm
|
||||||
|
cMimeBoundary = {&DEFAULT_MIME_BOUNDARY}
|
||||||
|
lBodyIsBase64 = TRUE.
|
||||||
|
IF (OPSYS BEGINS "WIN") THEN
|
||||||
|
ASSIGN cNewLine = {&CR} + {&LF}.
|
||||||
|
ELSE
|
||||||
|
ASSIGN cNewLine = {&LF}.
|
||||||
|
END CONSTRUCTOR.
|
||||||
|
|
||||||
|
DESTRUCTOR PUBLIC Email ():
|
||||||
|
FOR EACH ttAttachments:
|
||||||
|
IF VALID-OBJECT(ttAttachments.lcData) THEN
|
||||||
|
DELETE OBJECT ttAttachments.lcData NO-ERROR.
|
||||||
|
END. /* FOR EACH ttAttachments */
|
||||||
|
END DESTRUCTOR.
|
||||||
|
|
||||||
|
/* Add a sender ("From:" address) to the email */
|
||||||
|
METHOD PUBLIC VOID addSender(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttSenders
|
||||||
|
WHERE ttSenders.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttSenders.
|
||||||
|
ASSIGN ttSenders.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a sender ("From:" address) (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addSender(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttSenders
|
||||||
|
WHERE ttSenders.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttSenders.
|
||||||
|
ASSIGN ttSenders.cEmailAddress = ipcEmailAddress
|
||||||
|
ttSenders.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a "To:" recipient to the email */
|
||||||
|
METHOD PUBLIC VOID addToRecipient(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttToRecipients
|
||||||
|
WHERE ttToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttToRecipients.
|
||||||
|
ASSIGN ttToRecipients.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a "To:" recipient (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addToRecipient(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttToRecipients
|
||||||
|
WHERE ttToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttToRecipients.
|
||||||
|
ASSIGN ttToRecipients.cEmailAddress = ipcEmailAddress
|
||||||
|
ttToRecipients.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a "CC:" recipient to the email */
|
||||||
|
METHOD PUBLIC VOID addCCRecipient(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttCCRecipients
|
||||||
|
WHERE ttCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttCCRecipients.
|
||||||
|
ASSIGN ttCCRecipients.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a "CC:" recipient (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addCCRecipient(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttCCRecipients
|
||||||
|
WHERE ttCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttCCRecipients.
|
||||||
|
ASSIGN ttCCRecipients.cEmailAddress = ipcEmailAddress
|
||||||
|
ttToRecipients.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a "BCC:" recipient to the email */
|
||||||
|
METHOD PUBLIC VOID addBCCRecipient(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttBCCRecipients
|
||||||
|
WHERE ttBCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttBCCRecipients.
|
||||||
|
ASSIGN ttBCCRecipients.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a "BCC:" recipient (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addBCCRecipient(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttBCCRecipients
|
||||||
|
WHERE ttBCCRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttBCCRecipients.
|
||||||
|
ASSIGN ttBCCRecipients.cEmailAddress = ipcEmailAddress
|
||||||
|
ttToRecipients.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a reply-to recipient to the email */
|
||||||
|
METHOD PUBLIC VOID addReplyToRecipient(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttReplyToRecipients
|
||||||
|
WHERE ttReplyToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttReplyToRecipients.
|
||||||
|
ASSIGN ttReplyToRecipients.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a reply-to recipient (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addReplyToRecipient(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttReplyToRecipients
|
||||||
|
WHERE ttReplyToRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttReplyToRecipients.
|
||||||
|
ASSIGN ttReplyToRecipients.cEmailAddress = ipcEmailAddress
|
||||||
|
ttReplyToRecipients.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a delivery receipt recipient to the email */
|
||||||
|
METHOD PUBLIC VOID addDeliveryReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttDeliveryReceiptRecipients
|
||||||
|
WHERE ttDeliveryReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttDeliveryReceiptRecipients.
|
||||||
|
ASSIGN ttDeliveryReceiptRecipients.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a delivery receipt recipient (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addDeliveryReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttDeliveryReceiptRecipients
|
||||||
|
WHERE ttDeliveryReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttDeliveryReceiptRecipients.
|
||||||
|
ASSIGN ttDeliveryReceiptRecipients.cEmailAddress = ipcEmailAddress
|
||||||
|
ttDeliveryReceiptRecipients.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a read receipt recipient to the email */
|
||||||
|
METHOD PUBLIC VOID addReadReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttReadReceiptRecipients
|
||||||
|
WHERE ttReadReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttReadReceiptRecipients.
|
||||||
|
ASSIGN ttReadReceiptRecipients.cEmailAddress = ipcEmailAddress.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a read receipt recipient (with Real Name) to the email */
|
||||||
|
METHOD PUBLIC VOID addReadReceiptRecipient(INPUT ipcEmailAddress AS CHARACTER,
|
||||||
|
INPUT ipcRealName AS CHARACTER):
|
||||||
|
IF NOT CAN-FIND(FIRST ttReadReceiptRecipients
|
||||||
|
WHERE ttReadReceiptRecipients.cEmailAddress EQ ipcEmailAddress) THEN DO:
|
||||||
|
CREATE ttReadReceiptRecipients.
|
||||||
|
ASSIGN ttReadReceiptRecipients.cEmailAddress = ipcEmailAddress
|
||||||
|
ttReadReceiptRecipients.cRealName = ipcRealName.
|
||||||
|
END.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the subject of the email */
|
||||||
|
METHOD PUBLIC VOID setSubject(INPUT ipcSubject AS CHARACTER):
|
||||||
|
ASSIGN cSubject = ipcSubject.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the importance of the email. H = High, L = Low, anything else = Medium/None */
|
||||||
|
METHOD PUBLIC VOID setImportance(INPUT ipcImportance AS CHARACTER):
|
||||||
|
ASSIGN cImportance = ipcImportance.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the sensitivity of the email. */
|
||||||
|
/* Possible values (from RFC 2156): "Personal", "Private", or "Company confidential" ("Company-confidential") */
|
||||||
|
METHOD PUBLIC VOID setSensitivity(INPUT ipcSensitivity AS CHARACTER):
|
||||||
|
ASSIGN cSensitivity = ipcSensitivity.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the priority of the email (to affect transmission speed and delivery) */
|
||||||
|
/* Possible values (from RFC 2156): "normal", "urgent", or "non-urgent" */
|
||||||
|
METHOD PUBLIC VOID setPriority(INPUT ipcPriority AS CHARACTER):
|
||||||
|
ASSIGN cPriority = ipcPriority.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the date/time the email was sent */
|
||||||
|
METHOD PUBLIC VOID setSentDate(INPUT ipdttmtzSentDate AS DATETIME-TZ):
|
||||||
|
ASSIGN dttmtzSentDate = ipdttmtzSentDate.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the date/time recipient(s) should reply by */
|
||||||
|
METHOD PUBLIC VOID setReplyByDate(INPUT ipdttmtzReplyByDate AS DATETIME-TZ):
|
||||||
|
ASSIGN dttmtzReplyByDate = ipdttmtzReplyByDate.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the date/time the message expires */
|
||||||
|
METHOD PUBLIC VOID setExpireDate(INPUT ipdttmtzExpireDate AS DATETIME-TZ):
|
||||||
|
ASSIGN dttmtzExpireDate = ipdttmtzExpireDate.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* If send email algorithm not set in constructor, you must set it using this method before the email can be sent */
|
||||||
|
METHOD PUBLIC VOID setSendEmailAlgorithm(INPUT ipobjSendEmailAlgorithm AS email.SendEmailAlgorithm):
|
||||||
|
ASSIGN objSendEmailAlgorithm = ipobjSendEmailAlgorithm.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
METHOD PUBLIC VOID setBodyText(INPUT ipcBodyText AS CHARACTER):
|
||||||
|
ASSIGN lcBody = ipcBodyText.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
METHOD PUBLIC VOID setBodyText(INPUT iplcBodyText AS LONGCHAR):
|
||||||
|
ASSIGN lcBody = iplcBodyText.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Set the body by reading in an external file */
|
||||||
|
METHOD PUBLIC CHARACTER setBodyFile(INPUT ipcBodyFile AS CHARACTER):
|
||||||
|
FILE-INFO:FILE-NAME = ipcBodyFile.
|
||||||
|
IF FILE-INFO:FULL-PATHNAME EQ ? THEN
|
||||||
|
RETURN "Cannot locate file '" + ipcBodyFile + "' in the filesystem!".
|
||||||
|
IF INDEX(FILE-INFO:FILE-TYPE, "R") EQ 0 THEN
|
||||||
|
RETURN "File '" + FILE-INFO:FULL-PATHNAME + "' exists but is not readable!".
|
||||||
|
COPY-LOB FROM FILE FILE-INFO:FULL-PATHNAME TO OBJECT lcBody NO-ERROR.
|
||||||
|
IF ERROR-STATUS:ERROR THEN
|
||||||
|
RETURN "Error copying from file: " + ERROR-STATUS:GET-MESSAGE(1).
|
||||||
|
RETURN "". /* Success */
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Body defaults to base64 encoding, but can be manually disabled */
|
||||||
|
METHOD PUBLIC VOID setBodyEncoding(INPUT iplBase64Encode AS LOGICAL):
|
||||||
|
ASSIGN lBodyIsBase64 = iplBase64Encode.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Add a non-encoded file attachment to the email */
|
||||||
|
METHOD PUBLIC CHARACTER addTextAttachment(INPUT ipcFileName AS CHARACTER):
|
||||||
|
DEFINE VARIABLE lcTemp AS LONGCHAR NO-UNDO.
|
||||||
|
FILE-INFO:FILE-NAME = ipcFileName.
|
||||||
|
IF FILE-INFO:FULL-PATHNAME EQ ? THEN
|
||||||
|
RETURN "Cannot locate file '" + ipcFileName + "' in the filesystem!".
|
||||||
|
IF INDEX(FILE-INFO:FILE-TYPE, "R") EQ 0 THEN
|
||||||
|
RETURN "File '" + FILE-INFO:FULL-PATHNAME + "' exists but is not readable!".
|
||||||
|
/* Load file into memory */
|
||||||
|
COPY-LOB FROM FILE FILE-INFO:FULL-PATHNAME TO OBJECT lcTemp NO-ERROR.
|
||||||
|
IF ERROR-STATUS:ERROR THEN
|
||||||
|
RETURN "Error copying from file: " + ERROR-STATUS:GET-MESSAGE(1).
|
||||||
|
CREATE ttAttachments.
|
||||||
|
ASSIGN ttAttachments.cFileName = ipcFileName
|
||||||
|
ttAttachments.lcData = NEW email.LongcharWrapper(lcTemp)
|
||||||
|
ttAttachments.lBase64Encode = FALSE.
|
||||||
|
RETURN "". /* Success */
|
||||||
|
END.
|
||||||
|
|
||||||
|
/* Add a file attachment to the email; it defaults to base-64 encoding */
|
||||||
|
METHOD PUBLIC CHARACTER addAttachment(INPUT ipcFileName AS CHARACTER):
|
||||||
|
DEFINE VARIABLE lcTemp AS LONGCHAR NO-UNDO.
|
||||||
|
FILE-INFO:FILE-NAME = ipcFileName.
|
||||||
|
IF FILE-INFO:FULL-PATHNAME EQ ? THEN
|
||||||
|
RETURN "Cannot locate file '" + ipcFileName + "' in the filesystem!".
|
||||||
|
IF INDEX(FILE-INFO:FILE-TYPE, "R") EQ 0 THEN
|
||||||
|
RETURN "File '" + FILE-INFO:FULL-PATHNAME + "' exists but is not readable!".
|
||||||
|
/* Load file into memory */
|
||||||
|
COPY-LOB FROM FILE FILE-INFO:FULL-PATHNAME TO OBJECT lcTemp NO-ERROR.
|
||||||
|
IF ERROR-STATUS:ERROR THEN
|
||||||
|
RETURN "Error copying from file: " + ERROR-STATUS:GET-MESSAGE(1).
|
||||||
|
CREATE ttAttachments.
|
||||||
|
ASSIGN ttAttachments.cFileName = ipcFileName
|
||||||
|
ttAttachments.lcData = NEW email.LongcharWrapper(EmailClient.Util:ConvertDataToBase64(lcTemp))
|
||||||
|
ttAttachments.lBase64Encode = TRUE.
|
||||||
|
RETURN "". /* Success */
|
||||||
|
END.
|
||||||
|
|
||||||
|
/* Override default MIME boundary */
|
||||||
|
METHOD PUBLIC VOID setMimeBoundary(INPUT ipcMimeBoundary AS CHARACTER):
|
||||||
|
ASSIGN cMimeBoundary = ipcMimeBoundary.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Return a concatenated list of To:, CC:, and BCC: recipients */
|
||||||
|
METHOD PUBLIC CHARACTER getRecipients():
|
||||||
|
DEFINE VARIABLE cRecipients AS CHARACTER NO-UNDO.
|
||||||
|
|
||||||
|
FOR EACH ttToRecipients
|
||||||
|
BREAK BY ttToRecipients.cEmailAddress:
|
||||||
|
ASSIGN cRecipients = cRecipients + ttToRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttToRecipients.cEmailAddress) THEN DO:
|
||||||
|
ASSIGN cRecipients = cRecipients + ", ".
|
||||||
|
END.
|
||||||
|
END.
|
||||||
|
FOR EACH ttCCRecipients
|
||||||
|
BREAK BY ttCCRecipients.cEmailAddress:
|
||||||
|
IF FIRST(ttCCRecipients.cEmailAddress) AND
|
||||||
|
cRecipients NE "" THEN
|
||||||
|
ASSIGN cRecipients = cRecipients + ", ".
|
||||||
|
ASSIGN cRecipients = cRecipients + ttCCRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttCCRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cRecipients = cRecipients + ttCCRecipients.cEmailAddress.
|
||||||
|
END.
|
||||||
|
FOR EACH ttBCCRecipients
|
||||||
|
BREAK BY ttBCCRecipients.cEmailAddress:
|
||||||
|
IF FIRST(ttBCCRecipients.cEmailAddress) AND
|
||||||
|
cRecipients NE "" THEN
|
||||||
|
ASSIGN cRecipients = cRecipients + ", ".
|
||||||
|
ASSIGN cRecipients = cRecipients + ttBCCRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttBCCRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cRecipients = cRecipients + ttBCCRecipients.cEmailAddress.
|
||||||
|
END.
|
||||||
|
RETURN cRecipients.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Dumps all email message headers to CHAR */
|
||||||
|
METHOD PUBLIC CHARACTER getHeaders():
|
||||||
|
DEFINE VARIABLE cReturnData AS CHARACTER NO-UNDO.
|
||||||
|
|
||||||
|
/* Write the "From:" header */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "From:".
|
||||||
|
FOR EACH ttSenders
|
||||||
|
BREAK BY ttSenders.cEmailAddress:
|
||||||
|
IF ttSenders.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttSenders.cRealName + " <" + ttSenders.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttSenders.cEmailAddress.
|
||||||
|
IF NOT LAST(ttSenders.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END.
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "\n".
|
||||||
|
/* Write the "To:" header */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "To:".
|
||||||
|
FOR EACH ttToRecipients
|
||||||
|
BREAK BY ttToRecipients.cEmailAddress:
|
||||||
|
IF ttToRecipients.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttToRecipients.cRealName + " <" + ttToRecipients.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttToRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttToRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END.
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "\n".
|
||||||
|
/* Write the "Reply-To:" header */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "Reply-To:".
|
||||||
|
IF TEMP-TABLE ttReplyToRecipients:HAS-RECORDS THEN DO:
|
||||||
|
/* Use manually-overridden reply-to addresses */
|
||||||
|
FOR EACH ttReplyToRecipients
|
||||||
|
BREAK BY ttReplyToRecipients.cEmailAddress:
|
||||||
|
IF ttReplyToRecipients.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttReplyToRecipients.cRealName + " <" + ttReplyToRecipients.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttReplyToRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttReplyToRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END. /* FOR EACH ttReplyToRecipients ... */
|
||||||
|
END. /* IF TEMP-TABLE ttReplyToRecipients:HAS-RECORDS */
|
||||||
|
ELSE DO:
|
||||||
|
/* Write reply-to using sender addresses if reply-to addresses not manually overriddden */
|
||||||
|
FOR EACH ttSenders
|
||||||
|
BREAK BY ttSenders.cEmailAddress:
|
||||||
|
IF ttSenders.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttSenders.cRealName + " <" + ttSenders.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttSenders.cEmailAddress.
|
||||||
|
IF NOT LAST(ttSenders.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END.
|
||||||
|
END. /* ELSE / IF TEMP-TABLE ttReplyToRecipients:HAS-RECORDS */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "\n".
|
||||||
|
/* Write the "Cc:" header */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "Cc:".
|
||||||
|
FOR EACH ttCCRecipients
|
||||||
|
BREAK BY ttCCRecipients.cEmailAddress:
|
||||||
|
IF ttCCRecipients.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttCCRecipients.cRealName + " <" + ttCCRecipients.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttCCRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttCCRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END.
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "\n".
|
||||||
|
/* Write the "Bcc:" header */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "Bcc:".
|
||||||
|
FOR EACH ttBCCRecipients
|
||||||
|
BREAK BY ttBCCRecipients.cEmailAddress:
|
||||||
|
IF ttBCCRecipients.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttBCCRecipients.cRealName + " <" + ttBCCRecipients.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttBCCRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttBCCRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END.
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "\n".
|
||||||
|
/* If delivery recipients specified, write each recipient out */
|
||||||
|
IF TEMP-TABLE ttDeliveryReceiptRecipients:HAS-RECORDS THEN DO:
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "Return-Receipt-To:".
|
||||||
|
FOR EACH ttDeliveryReceiptRecipients
|
||||||
|
BREAK BY ttDeliveryReceiptRecipients.cEmailAddress:
|
||||||
|
IF ttDeliveryReceiptRecipients.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttDeliveryReceiptRecipients.cRealName + " <" + ttDeliveryReceiptRecipients.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttDeliveryReceiptRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttDeliveryReceiptRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END. /* FOR EACH ttDeliveryReceiptRecipients */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES}.
|
||||||
|
END. /* IF TEMP-TABLE ttDeliveryReceiptRecipients:HAS-RECORDS */
|
||||||
|
/* If read recipients specified, write each recipient out */
|
||||||
|
IF TEMP-TABLE ttReadReceiptRecipients:HAS-RECORDS THEN DO:
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES} + "Disposition-Notification-To:".
|
||||||
|
FOR EACH ttReadReceiptRecipients
|
||||||
|
BREAK BY ttReadReceiptRecipients.cEmailAddress:
|
||||||
|
IF ttReadReceiptRecipients.cRealName NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ttReadReceiptRecipients.cRealName + " <" + ttReadReceiptRecipients.cEmailAddress + ">".
|
||||||
|
ELSE
|
||||||
|
ASSIGN cReturnData = cReturnData + ttReadReceiptRecipients.cEmailAddress.
|
||||||
|
IF NOT LAST(ttReadReceiptRecipients.cEmailAddress) THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + ", ".
|
||||||
|
END. /* FOR EACH ttReadReceiptRecipients */
|
||||||
|
ASSIGN cReturnData = cReturnData + {"ES}.
|
||||||
|
END. /* IF TEMP-TABLE ttReadReceiptRecipients:HAS-RECORDS */
|
||||||
|
/* Write the "Subject:" header */
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Subject:" + cSubject + {"ES}.
|
||||||
|
/* Write the "Importance:" header */
|
||||||
|
IF cImportance BEGINS "H" THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Importance:High" + {"ES}.
|
||||||
|
ELSE IF cImportance BEGINS "L" THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Importance:Low" + {"ES}.
|
||||||
|
/* Write the "Sensitivity" header */
|
||||||
|
IF cSensitivity NE "" THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Sensitivity:" + cSensitivity + {"ES}.
|
||||||
|
/* Write the "Priority" header */
|
||||||
|
IF cPriority NE "" THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Priority:" + cPriority + {"ES}.
|
||||||
|
/* Write the "Date" (sent date) header */
|
||||||
|
IF dttmtzSentDate NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Date:" + email.Util:ABLDateTimeToEmail(dttmtzSentDate) + {"ES}.
|
||||||
|
IF dttmtzReplyByDate NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Reply-By:" + email.Util:ABLDateTimeToEmail(dttmtzReplyByDate) + {"ES}.
|
||||||
|
/* Write the "Expiry-Date" header */
|
||||||
|
IF dttmtzExpireDate NE ? THEN
|
||||||
|
ASSIGN cReturnData = cReturnData + "\n" + {"ES} + "Expiry-Date:" + email.Util:ABLDateTimeToEmail(dttmtzExpireDate) + {"ES}.
|
||||||
|
RETURN cReturnData.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
/* Dumps all email message payload data (body and attachments) to LONGCHAR */
|
||||||
|
METHOD PUBLIC LONGCHAR getPayload():
|
||||||
|
DEFINE VARIABLE lcReturnData AS LONGCHAR NO-UNDO.
|
||||||
|
|
||||||
|
/* If no body and no text, then return empty string ("") */
|
||||||
|
IF lcBody EQ "" AND NOT TEMP-TABLE ttAttachments:HAS-RECORDS THEN
|
||||||
|
RETURN lcReturnData.
|
||||||
|
|
||||||
|
/* Write payload header */
|
||||||
|
ASSIGN lcReturnData = "Mime-Version: 1.0" + cNewLine +
|
||||||
|
"Content-Type: multipart/mixed; boundary=" + cMimeBoundary + cNewLine + cNewLine.
|
||||||
|
|
||||||
|
/* Write out the email body, if it exists */
|
||||||
|
IF lcBody NE "" THEN DO:
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "--" + cMimeBoundary + cNewLine +
|
||||||
|
"Content-Type: text/plain; charset=~"us-ascii~"" + cNewLine.
|
||||||
|
IF lBodyIsBase64 THEN DO:
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "Content-Transfer-Encoding: base64" + cNewLine +
|
||||||
|
cNewLine +
|
||||||
|
email.Util:ConvertDataToBase64(lcBody) + cNewLine.
|
||||||
|
END.
|
||||||
|
ELSE DO:
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "Content-Transfer-Encoding: 7bit" + cNewLine +
|
||||||
|
cNewLine +
|
||||||
|
lcBody + cNewLine.
|
||||||
|
END.
|
||||||
|
END.
|
||||||
|
|
||||||
|
/* Write out each email attachment */
|
||||||
|
FOR EACH ttAttachments:
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "--" + cMimeBoundary + cNewLine.
|
||||||
|
IF ttAttachments.lBase64Encode THEN DO:
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "Content-Type: application/octet-stream" + cNewLine +
|
||||||
|
"Content-Disposition: attachment; filename=~"" + ttAttachments.cFileName + "~"" + cNewLine +
|
||||||
|
"Content-Transfer-Encoding: base64" + cNewLine + cNewLine +
|
||||||
|
CAST(ttAttachments.lcData, email.LongcharWrapper):getLongchar() + cNewLine.
|
||||||
|
END.
|
||||||
|
ELSE DO:
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "Content-Type: text/plain; charset=~"us-ascii~"" + cNewLine +
|
||||||
|
"Content-Disposition: attachment; filename=~"" + ttAttachments.cFileName + "~"" + cNewLine +
|
||||||
|
"Content-Transfer-Encoding: 7bit" + cNewLine + cNewLine +
|
||||||
|
CAST(ttAttachments.lcData, email.LongcharWrapper):getLongchar() + cNewLine.
|
||||||
|
END.
|
||||||
|
END.
|
||||||
|
|
||||||
|
/* Write payload footer */
|
||||||
|
ASSIGN lcReturnData = lcReturnData + "--" + cMimeBoundary + "--" + cNewLine.
|
||||||
|
|
||||||
|
RETURN lcReturnData.
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
METHOD PUBLIC CHARACTER send():
|
||||||
|
RETURN objSendEmailAlgorithm:sendEmail(INPUT THIS-OBJECT).
|
||||||
|
END METHOD.
|
||||||
|
|
||||||
|
END CLASS.
|
||||||
47
test/fixtures/Foo.kt
vendored
Normal file
47
test/fixtures/Foo.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package addressbook
|
||||||
|
|
||||||
|
class Contact(
|
||||||
|
val name : String,
|
||||||
|
val emails : List<EmailAddress>,
|
||||||
|
val addresses : List<PostalAddress>,
|
||||||
|
val phonenums : List<PhoneNumber>
|
||||||
|
)
|
||||||
|
|
||||||
|
class EmailAddress(
|
||||||
|
val user : String,
|
||||||
|
val host : String
|
||||||
|
)
|
||||||
|
|
||||||
|
class PostalAddress(
|
||||||
|
val streetAddress : String,
|
||||||
|
val city : String,
|
||||||
|
val zip : String,
|
||||||
|
val state : USState?,
|
||||||
|
val country : Country
|
||||||
|
) {
|
||||||
|
assert {(state == null) xor (country == Countries["US"]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
class PhoneNumber(
|
||||||
|
val country : Country,
|
||||||
|
val areaCode : Int,
|
||||||
|
val number : Long
|
||||||
|
)
|
||||||
|
|
||||||
|
object Countries {
|
||||||
|
fun get(id : CountryID) : Country = countryTable[id]
|
||||||
|
|
||||||
|
private var table : Map<String, Country>? = null
|
||||||
|
private val countryTable : Map<String, Country>
|
||||||
|
get() {
|
||||||
|
if (table == null) {
|
||||||
|
table = HashMap()
|
||||||
|
for (line in TextFile("countries.txt").lines(stripWhiteSpace = true)) {
|
||||||
|
table[line] = Country(line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Country(val name : String)
|
||||||
240
test/fixtures/cApplication.cls
vendored
Normal file
240
test/fixtures/cApplication.cls
vendored
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
VERSION 1.0 CLASS
|
||||||
|
BEGIN
|
||||||
|
MultiUse = -1 'True
|
||||||
|
Persistable = 0 'NotPersistable
|
||||||
|
DataBindingBehavior = 0 'vbNone
|
||||||
|
DataSourceBehavior = 0 'vbNone
|
||||||
|
MTSTransactionMode = 0 'NotAnMTSObject
|
||||||
|
END
|
||||||
|
Attribute VB_Name = "cApplication"
|
||||||
|
Attribute VB_GlobalNameSpace = False
|
||||||
|
Attribute VB_Creatable = True
|
||||||
|
Attribute VB_PredeclaredId = False
|
||||||
|
Attribute VB_Exposed = False
|
||||||
|
'*************************************************************************************************************************************************************************************************************************************************
|
||||||
|
'
|
||||||
|
' Copyright (c) David Briant 2009-2012 - All rights reserved
|
||||||
|
'
|
||||||
|
'*************************************************************************************************************************************************************************************************************************************************
|
||||||
|
|
||||||
|
Option Explicit
|
||||||
|
|
||||||
|
Private Declare Function apiSetProp Lib "user32" Alias "SetPropA" (ByVal hwnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
|
||||||
|
Private Declare Function apiGlobalAddAtom Lib "kernel32" Alias "GlobalAddAtomA" (ByVal lpString As String) As Long
|
||||||
|
Private Declare Function apiSetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Long) As Long
|
||||||
|
|
||||||
|
Private myMouseEventsForm As fMouseEventsForm
|
||||||
|
Private WithEvents myAST As cTP_AdvSysTray
|
||||||
|
Attribute myAST.VB_VarHelpID = -1
|
||||||
|
|
||||||
|
Private myClassName As String
|
||||||
|
Private myWindowName As String
|
||||||
|
Private Const TEN_MILLION As Single = 10000000
|
||||||
|
|
||||||
|
Private WithEvents myListener As VLMessaging.VLMMMFileListener
|
||||||
|
Attribute myListener.VB_VarHelpID = -1
|
||||||
|
Private WithEvents myMMFileTransports As VLMessaging.VLMMMFileTransports
|
||||||
|
Attribute myMMFileTransports.VB_VarHelpID = -1
|
||||||
|
|
||||||
|
Private myMachineID As Long
|
||||||
|
|
||||||
|
Private myRouterSeed As Long
|
||||||
|
Private myRouterIDsByMMTransportID As New Dictionary
|
||||||
|
Private myMMTransportIDsByRouterID As New Dictionary
|
||||||
|
|
||||||
|
Private myDirectoryEntriesByIDString As New Dictionary
|
||||||
|
|
||||||
|
Private Const GET_ROUTER_ID As String = "GET_ROUTER_ID"
|
||||||
|
Private Const GET_ROUTER_ID_REPLY As String = "GET_ROUTER_ID_REPLY"
|
||||||
|
Private Const REGISTER_SERVICE As String = "REGISTER_SERVICE"
|
||||||
|
Private Const REGISTER_SERVICE_REPLY As String = "REGISTER_SERVICE_REPLY"
|
||||||
|
Private Const UNREGISTER_SERVICE As String = "UNREGISTER_SERVICE"
|
||||||
|
Private Const UNREGISTER_SERVICE_REPLY As String = "UNREGISTER_SERVICE_REPLY"
|
||||||
|
Private Const GET_SERVICES As String = "GET_SERVICES"
|
||||||
|
Private Const GET_SERVICES_REPLY As String = "GET_SERVICES_REPLY"
|
||||||
|
|
||||||
|
|
||||||
|
'*************************************************************************************************************************************************************************************************************************************************
|
||||||
|
' Initialize / Release
|
||||||
|
'*************************************************************************************************************************************************************************************************************************************************
|
||||||
|
|
||||||
|
Private Sub class_Initialize()
|
||||||
|
Dim atomID As Long
|
||||||
|
Randomize
|
||||||
|
' hide us from the Applications list in the Windows Task Manager
|
||||||
|
App.TaskVisible = False
|
||||||
|
|
||||||
|
' listen for connections
|
||||||
|
myClassName = "VLMMachineRouter" & CStr(Int(Rnd() * TEN_MILLION) + 1)
|
||||||
|
Randomize
|
||||||
|
myWindowName = "VLMMachineRouter" & CStr(Int(Rnd() * TEN_MILLION) + 1)
|
||||||
|
Set myListener = New VLMMMFileListener
|
||||||
|
myListener.listenViaNamedWindow myClassName, myWindowName, 1024 * 8
|
||||||
|
Set myMMFileTransports = New VLMMMFileTransports
|
||||||
|
myRouterSeed = 1
|
||||||
|
|
||||||
|
' create tray icon
|
||||||
|
Set myMouseEventsForm = New fMouseEventsForm
|
||||||
|
Set myAST = New cTP_AdvSysTray
|
||||||
|
myAST.create myMouseEventsForm, myMouseEventsForm.icon, "VLM Directory"
|
||||||
|
'myAST.showBalloon "Current Shell32.dll version is " & myAST.shellVersion & ".x", "AdvSysTray VB Class", NIIF_INFO
|
||||||
|
|
||||||
|
' make myself easily found
|
||||||
|
apiSetProp myMouseEventsForm.hwnd, "IsVLMachineRouter", 1
|
||||||
|
apiSetProp myMouseEventsForm.hwnd, "WindowNameAtom", apiGlobalAddAtom(myWindowName)
|
||||||
|
apiSetProp myMouseEventsForm.hwnd, "ClassNameAtom", apiGlobalAddAtom(myClassName)
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub shutdown()
|
||||||
|
myAST.destroy
|
||||||
|
Set myAST = Nothing
|
||||||
|
Unload myMouseEventsForm
|
||||||
|
Set myMouseEventsForm = Nothing
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub myAST_RButtonUp()
|
||||||
|
Dim epm As New cTP_EasyPopupMenu, menuItemSelected As Long
|
||||||
|
'SetForegroundWindow myMouseEventsForm.hwnd
|
||||||
|
' epm.addMenuItem "Main form...", MF_STRING, 1
|
||||||
|
' epm.createSubmenu "Radio items"
|
||||||
|
' epm.addSubmenuItem "Radio item 1", MF_STRING, 2
|
||||||
|
' epm.addSubmenuItem "Radio item 2", MF_STRING, 3
|
||||||
|
' epm.addSubmenuItem "Radio item 3", MF_STRING, 4
|
||||||
|
' epm.checkRadioItem 0, 2, 1
|
||||||
|
' epm.addMenuItem "", MF_SEPARATOR, 0
|
||||||
|
' epm.addMenuItem "Disabled item", MF_GRAYED, 5
|
||||||
|
' epm.addMenuItem "Checked item", MF_CHECKED, 6
|
||||||
|
' epm.addMenuItem "", MF_SEPARATOR, 0
|
||||||
|
epm.addMenuItem "Exit", MF_STRING, 12
|
||||||
|
apiSetForegroundWindow myMouseEventsForm.hwnd
|
||||||
|
menuItemSelected = epm.trackMenu(myMouseEventsForm.hwnd)
|
||||||
|
Select Case menuItemSelected
|
||||||
|
Case 12
|
||||||
|
Set epm = Nothing
|
||||||
|
globalShutdown
|
||||||
|
End Select
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Sub myListener_newConnection(ByVal newTransport As VLMessaging.VLMMMFileTransport, oReceived As Boolean)
|
||||||
|
Dim id As Long
|
||||||
|
oReceived = True
|
||||||
|
id = myMMFileTransports.addTransport(newTransport)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Private Function messageFromBytes(buffer() As Byte) As VLMMessage
|
||||||
|
Dim i1 As Long, i2 As Long, messageArray As Variant, message As New VLMMessage
|
||||||
|
DBGetArrayBounds buffer, 1, i1, i2
|
||||||
|
messageArray = g_VLMUtils.BytesAsVariant(buffer, i2 + 1, 1)
|
||||||
|
message.fromMessageArray messageArray
|
||||||
|
Set messageFromBytes = message
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function messageToBytes(message As VLMMessage) As Byte()
|
||||||
|
Dim messageArray As Variant, length As Long, buffer() As Byte
|
||||||
|
message.toMessageArray messageArray
|
||||||
|
length = g_VLMUtils.LengthOfVariantAsBytes(messageArray)
|
||||||
|
DBCreateNewArrayOfBytes buffer, 1, length
|
||||||
|
g_VLMUtils.VariantAsBytes messageArray, buffer, length + 1, 1
|
||||||
|
messageToBytes = buffer
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Sub myMMFileTransports_bytesArrived(ByVal id As Long, buffer() As Byte, oReceived As Boolean)
|
||||||
|
Dim message As VLMMessage, toAddress As VLMAddress
|
||||||
|
oReceived = True
|
||||||
|
Set message = messageFromBytes(buffer)
|
||||||
|
Set toAddress = message.toAddress
|
||||||
|
On Error GoTo errorHandler
|
||||||
|
If (toAddress.MachineID = myMachineID Or toAddress.MachineID = 0) And toAddress.RouterID = 1 And toAddress.AgentID = 1 Then
|
||||||
|
handleMessageToRouter id, message
|
||||||
|
Else
|
||||||
|
routeMessage message
|
||||||
|
End If
|
||||||
|
Exit Sub
|
||||||
|
errorHandler:
|
||||||
|
MsgBox Err.Description & ", " & Erl
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub handleMessageToRouter(MMFileTransportID As Long, message As VLMMessage)
|
||||||
|
Dim reply As VLMMessage, transport As VLMMMFileTransport, RouterID As Long, address As New VLMAddress
|
||||||
|
Dim IDString As String, vs As Variant, i As Long, entries As New Collection, answer1D As Variant
|
||||||
|
|
||||||
|
Select Case True
|
||||||
|
|
||||||
|
Case message.subject = GET_ROUTER_ID
|
||||||
|
If myRouterIDsByMMTransportID.Exists(MMFileTransportID) Then
|
||||||
|
RouterID = myRouterIDsByMMTransportID(MMFileTransportID)
|
||||||
|
Else
|
||||||
|
myRouterSeed = myRouterSeed + 1
|
||||||
|
RouterID = myRouterSeed
|
||||||
|
myRouterIDsByMMTransportID(MMFileTransportID) = RouterID
|
||||||
|
myMMTransportIDsByRouterID(RouterID) = MMFileTransportID
|
||||||
|
End If
|
||||||
|
Set reply = message.reply
|
||||||
|
reply.subject = GET_ROUTER_ID_REPLY
|
||||||
|
reply.Contents = RouterID
|
||||||
|
Set transport = myMMFileTransports.transport(MMFileTransportID)
|
||||||
|
transport.send messageToBytes(reply)
|
||||||
|
|
||||||
|
Case message.subject = REGISTER_SERVICE
|
||||||
|
address.initialise CLng(message.Contents(1)(1)), CLng(message.Contents(1)(2)), CLng(message.Contents(1)(3))
|
||||||
|
myDirectoryEntriesByIDString(directoryEntryIDString(CStr(message.Contents(2)), address)) = message.Contents
|
||||||
|
Set reply = message.reply
|
||||||
|
reply.subject = REGISTER_SERVICE_REPLY
|
||||||
|
Set transport = myMMFileTransports.transport(MMFileTransportID)
|
||||||
|
transport.send messageToBytes(reply)
|
||||||
|
|
||||||
|
Case message.subject = UNREGISTER_SERVICE
|
||||||
|
address.initialise CLng(message.Contents(1)(1)), CLng(message.Contents(1)(2)), CLng(message.Contents(1)(3))
|
||||||
|
IDString = directoryEntryIDString(CStr(message.Contents(2)), address)
|
||||||
|
If myDirectoryEntriesByIDString.Exists(IDString) Then myDirectoryEntriesByIDString.Remove IDString
|
||||||
|
Set reply = message.reply
|
||||||
|
reply.subject = UNREGISTER_SERVICE_REPLY
|
||||||
|
Set transport = myMMFileTransports.transport(MMFileTransportID)
|
||||||
|
transport.send messageToBytes(reply)
|
||||||
|
|
||||||
|
Case message.subject = GET_SERVICES
|
||||||
|
vs = myDirectoryEntriesByIDString.Items
|
||||||
|
For i = 0 To UBound(vs)
|
||||||
|
If IsEmpty(message.Contents) Then
|
||||||
|
entries.Add vs(i)
|
||||||
|
Else
|
||||||
|
If vs(i)(2) = message.Contents Then entries.Add vs(i)
|
||||||
|
End If
|
||||||
|
Next
|
||||||
|
If entries.Count > 0 Then
|
||||||
|
ReDim answer1D(1 To entries.Count)
|
||||||
|
For i = 1 To entries.Count
|
||||||
|
answer1D(i) = entries(i)
|
||||||
|
Next
|
||||||
|
End If
|
||||||
|
Set reply = message.reply
|
||||||
|
reply.subject = GET_SERVICES_REPLY
|
||||||
|
reply.Contents = answer1D
|
||||||
|
Set transport = myMMFileTransports.transport(MMFileTransportID)
|
||||||
|
transport.send messageToBytes(reply)
|
||||||
|
|
||||||
|
End Select
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Sub routeMessage(message As VLMMessage)
|
||||||
|
Dim buffer() As Byte, transport As VLMMMFileTransport
|
||||||
|
If message.toAddress.MachineID <> 0 And message.toAddress.MachineID <> myMachineID Then
|
||||||
|
' route to a remote machine
|
||||||
|
Else
|
||||||
|
' for the moment just route between MMFileTransports
|
||||||
|
If myMMTransportIDsByRouterID.Exists(message.toAddress.RouterID) Then
|
||||||
|
Set transport = myMMFileTransports(myMMTransportIDsByRouterID(message.toAddress.RouterID))
|
||||||
|
transport.send messageToBytes(message)
|
||||||
|
End If
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Function directoryEntryIDString(serviceType As String, address As VLMAddress)
|
||||||
|
directoryEntryIDString = serviceType & "<" & address.MachineID & "," & address.RouterID & "," & address.AgentID & ">"
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Sub myMMFileTransports_disconnecting(ByVal id As Long, oReceived As Boolean)
|
||||||
|
oReceived = True
|
||||||
|
End Sub
|
||||||
1
test/fixtures/foo.tea
vendored
Normal file
1
test/fixtures/foo.tea
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<% template foo() %>
|
||||||
14
test/fixtures/foo.vhd
vendored
Normal file
14
test/fixtures/foo.vhd
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- VHDL example file
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
|
||||||
|
entity inverter is
|
||||||
|
port(a : in std_logic;
|
||||||
|
b : out std_logic);
|
||||||
|
end entity;
|
||||||
|
|
||||||
|
architecture rtl of inverter is
|
||||||
|
begin
|
||||||
|
b <= not a;
|
||||||
|
end architecture;
|
||||||
8
test/fixtures/latex.cls
vendored
8
test/fixtures/latex.cls
vendored
@@ -1,8 +0,0 @@
|
|||||||
% latex.cls
|
|
||||||
%
|
|
||||||
% A barebones LaTeX2e class file
|
|
||||||
|
|
||||||
\def\author{Abe Voelker}
|
|
||||||
\def\fileversion{0.1}
|
|
||||||
\NeedsTeXFormat{LaTeX2e}
|
|
||||||
|
|
||||||
10
test/fixtures/openedge.cls
vendored
10
test/fixtures/openedge.cls
vendored
@@ -1,10 +0,0 @@
|
|||||||
USING Progress.Lang.*.
|
|
||||||
|
|
||||||
CLASS HelloWorld:
|
|
||||||
|
|
||||||
CONSTRUCTOR PUBLIC HelloWorld():
|
|
||||||
SUPER().
|
|
||||||
MESSAGE "Hello, world!".
|
|
||||||
END CONSTRUCTOR.
|
|
||||||
|
|
||||||
END CLASS.
|
|
||||||
245
test/fixtures/reedthesis.cls
vendored
Normal file
245
test/fixtures/reedthesis.cls
vendored
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
%
|
||||||
|
% This file is copyright (C) 2003 Sam Noble. It may be modified so long
|
||||||
|
% as my name is not removed and the modifier adds his name to the file.
|
||||||
|
% Redistribution permitted.
|
||||||
|
%
|
||||||
|
% 27 Jan 2004 Sam Noble Removed tocbibind dependency.
|
||||||
|
% 04 Dec 2001 Sam Noble Class file
|
||||||
|
% 03 Sep 1995 David Perkinson Title Page
|
||||||
|
% Acknowledgements Page, David Perkinson & Sam Noble
|
||||||
|
% May 2005 Patrick Carlisle Table of contents chapter definition
|
||||||
|
% 2004-2005 Ben Salzberg (BTS) a variety of tweaks here and in the template
|
||||||
|
%
|
||||||
|
% Oddities:
|
||||||
|
%
|
||||||
|
% We *ASSUME* that any time \cleardoublepage is called
|
||||||
|
% we actually want a blank back side with NO page number/heading
|
||||||
|
%
|
||||||
|
% Minor bug -- seems to be a more general LaTeX thing:
|
||||||
|
% If you use \frontmatter \mainmatter without any chapters inbetween
|
||||||
|
% be prepared to have the page numbering messed up. Not a big deal,
|
||||||
|
% but I'm not sure how to fix it.
|
||||||
|
%
|
||||||
|
%
|
||||||
|
|
||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProvidesClass{reedthesis}[2004/01/27 The Reed College Thesis Class]
|
||||||
|
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{book}}
|
||||||
|
\ProcessOptions\relax
|
||||||
|
\LoadClass{book}
|
||||||
|
\RequirePackage{fancyhdr}
|
||||||
|
|
||||||
|
% This gives us rules below the headers
|
||||||
|
\AtBeginDocument{%
|
||||||
|
\fancyhf{}
|
||||||
|
\fancyhead[LE,RO]{\thepage}
|
||||||
|
% \fancyhead[RE]{\slshape \leftmark}
|
||||||
|
% \fancyhead[LO]{\slshape \rightmark}
|
||||||
|
% The above makes your headers in all caps. If you would like different headers, choose one of the following options (be sure to remove the % symbol from both the right and left headers):
|
||||||
|
\fancyhead[RE]{\slshape \nouppercase \leftmark} % This makes the headers on the RIGHT side pages be italic and use lowercase With Capitals When Specified.
|
||||||
|
\fancyhead[LO]{\slshape \nouppercase \rightmark} % This does the same thing to the LEFT side pages
|
||||||
|
% or
|
||||||
|
% \fancyhead[RE]{\scshape \leftmark} % The RIGHT headers will be in small caps.
|
||||||
|
% \fancyhead[LO]{\scshape \rightmark} % And so will the LEFT headers
|
||||||
|
\pagestyle{fancy}
|
||||||
|
|
||||||
|
% Psych majors: You do not need the following six lines, as it conflicts with apacite, so comment them out.
|
||||||
|
\let\oldthebibliography=\thebibliography
|
||||||
|
\let\endoldthebibliography=\endthebibliography
|
||||||
|
\renewenvironment{thebibliography}[1]{
|
||||||
|
\oldthebibliography{#1}
|
||||||
|
\addcontentsline{toc}{chapter}{\bibname}
|
||||||
|
}{\endoldthebibliography}
|
||||||
|
%%%%%% end of things for psych majors to comment out
|
||||||
|
|
||||||
|
\let\oldtheindex=\theindex
|
||||||
|
\let\endoldtheindex=\endtheindex
|
||||||
|
\renewenvironment{theindex}{
|
||||||
|
\oldtheindex
|
||||||
|
\addcontentsline{toc}{chapter}{\indexname}
|
||||||
|
}{\endoldtheindex}
|
||||||
|
}
|
||||||
|
|
||||||
|
% Stolen from book.cls and modified
|
||||||
|
\let\RToldchapter\chapter
|
||||||
|
\renewcommand{\chapter}{\if@openright\RTcleardoublepage
|
||||||
|
\else\clearpage\fi
|
||||||
|
\thispagestyle{empty}%
|
||||||
|
\global\@topnum\z@
|
||||||
|
\@afterindentfalse
|
||||||
|
\secdef\@chapter\@schapter}
|
||||||
|
|
||||||
|
% Stolen from book.cls PBC 5/12/05
|
||||||
|
% Using this to actually show "Chapter 1" in TOC instead of "1"
|
||||||
|
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
|
||||||
|
\if@mainmatter
|
||||||
|
\refstepcounter{chapter}%
|
||||||
|
\typeout{\@chapapp\space\thechapter.}%
|
||||||
|
\addcontentsline{toc}{chapter}%
|
||||||
|
{\@chapapp\space\thechapter:\space#1}%
|
||||||
|
\else
|
||||||
|
\addcontentsline{toc}{chapter}{#1}%
|
||||||
|
\fi
|
||||||
|
\else
|
||||||
|
\addcontentsline{toc}{chapter}{#1}%
|
||||||
|
\fi
|
||||||
|
\chaptermark{#1}%
|
||||||
|
\addtocontents{lof}{\protect\addvspace{10\p@}}%
|
||||||
|
\addtocontents{lot}{\protect\addvspace{10\p@}}%
|
||||||
|
\if@twocolumn
|
||||||
|
\@topnewpage[\@makechapterhead{#2}]%
|
||||||
|
\else
|
||||||
|
\@makechapterhead{#2}%
|
||||||
|
\@afterheading
|
||||||
|
\fi}
|
||||||
|
|
||||||
|
\newcommand{\RTcleardoublepage}{
|
||||||
|
\clearpage\if@twoside \ifodd\c@page\else
|
||||||
|
\thispagestyle{empty}\hbox{}\newpage
|
||||||
|
\if@twocolumn\hbox{}\newpage\fi\fi\fi}
|
||||||
|
|
||||||
|
\let\RToldcleardoublepage\cleardoublepage
|
||||||
|
\renewcommand{\cleardoublepage}{\RTcleardoublepage}
|
||||||
|
|
||||||
|
% adjust margins for binding (changed 2007-04-24 tgp)
|
||||||
|
\setlength{\oddsidemargin}{.5in}
|
||||||
|
\setlength{\evensidemargin}{0in}
|
||||||
|
\setlength{\textwidth}{6.0in}
|
||||||
|
\setlength{\textheight}{9.0in}
|
||||||
|
\setlength\topmargin{0in}
|
||||||
|
\addtolength\topmargin{-\headheight}
|
||||||
|
\addtolength\topmargin{-\headsep}
|
||||||
|
|
||||||
|
%\setlength{\oddsidemargin}{.6in}
|
||||||
|
%\setlength{\evensidemargin}{0in}
|
||||||
|
%\setlength{\textwidth}{5.9in}
|
||||||
|
%\setlength\topmargin{0in}
|
||||||
|
%\addtolength\headheight{2.5pt}
|
||||||
|
%\addtolength\topmargin{-\headheight}
|
||||||
|
%\addtolength\topmargin{-\headsep}
|
||||||
|
%\addtolength\textheight{1in}
|
||||||
|
%\addtolength\textheight{\headheight}
|
||||||
|
%\addtolength\textheight{\headsep}
|
||||||
|
|
||||||
|
\def\division#1{\gdef \@division{#1}}
|
||||||
|
\def\@division{\@latex@warning@no@line{No \noexpand\division given}}
|
||||||
|
\def\department#1{\gdef \@department{#1}}
|
||||||
|
\def\@department{\@latex@warning@no@line{No \noexpand\department given}}
|
||||||
|
\def\thedivisionof#1{\gdef \@thedivisionof{#1}}
|
||||||
|
\def\@thedivisionof{The Division of}
|
||||||
|
\def\approvedforthe#1{\gdef \@approvedforthe{#1}}
|
||||||
|
\def\@approvedforthe{Division}
|
||||||
|
\def\advisor#1{\gdef \@advisor{#1}}
|
||||||
|
\def\@advisor{\@latex@warning@no@line{No \noexpand\advisor given}}
|
||||||
|
\def\altadvisor#1{\gdef \@altadvisor{#1} \@altadvisortrue}
|
||||||
|
\global\let\@altadvisor\@empty
|
||||||
|
\newif\if@altadvisor
|
||||||
|
\@altadvisorfalse
|
||||||
|
|
||||||
|
\renewcommand{\contentsname}{Table of Contents}
|
||||||
|
\renewcommand{\bibname}{References}
|
||||||
|
|
||||||
|
\renewcommand\l@chapter[2]{%
|
||||||
|
\ifnum \c@tocdepth >\m@ne
|
||||||
|
\addpenalty{-\@highpenalty}%
|
||||||
|
\vskip 1.0em \@plus\p@
|
||||||
|
\setlength\@tempdima{1.5em}%
|
||||||
|
\begingroup
|
||||||
|
\parindent \z@ \rightskip \@pnumwidth
|
||||||
|
\parfillskip -\@pnumwidth
|
||||||
|
\leavevmode \bfseries
|
||||||
|
\advance\leftskip\@tempdima
|
||||||
|
\hskip -\leftskip
|
||||||
|
#1\nobreak\normalfont
|
||||||
|
\leaders\hbox{$\m@th \mkern \@dotsep mu\hbox{.}\mkern \@dotsep mu$}\hfill
|
||||||
|
\nobreak\hb@xt@\@pnumwidth{\bfseries \hss #2}\par
|
||||||
|
\penalty\@highpenalty
|
||||||
|
\endgroup
|
||||||
|
\fi}
|
||||||
|
|
||||||
|
\newenvironment{abstract}{%
|
||||||
|
\if@twocolumn
|
||||||
|
\@restonecoltrue\onecolumn
|
||||||
|
\else
|
||||||
|
\@restonecolfalse
|
||||||
|
\fi
|
||||||
|
\chapter[Abstract]{}
|
||||||
|
\begin{center}
|
||||||
|
{\fontsize{14}{16}\selectfont \bfseries Abstract}
|
||||||
|
\end{center}
|
||||||
|
\fontsize{12}{14}\selectfont
|
||||||
|
}{\clearpage \if@restonecol\twocolumn\fi}%
|
||||||
|
|
||||||
|
\ifx\@pdfoutput\@undefined
|
||||||
|
\newcommand{\RTpercent}{\@percentchar\space}
|
||||||
|
\AtBeginDvi{\special{!\RTpercent Reed College LaTeX Thesis Class 2001/12/04 SN}}
|
||||||
|
\AtBeginDvi{\special{rawpostscript \RTpercent Reed College LaTeX Thesis Class 2001/12/04 SN}}
|
||||||
|
\else
|
||||||
|
\AtEndDocument{\pdfinfo{/Creator (Reed College LaTeX Thesis Class 2001/12/04 SN)}}
|
||||||
|
\fi
|
||||||
|
|
||||||
|
% I hacked the title page to all be the same font size
|
||||||
|
% as requested by the library, BTS 2005
|
||||||
|
|
||||||
|
\renewcommand{\maketitle}{%
|
||||||
|
{\pagestyle{empty}
|
||||||
|
\fontsize{12}{14}\selectfont
|
||||||
|
\begin{titlepage}
|
||||||
|
\newpage
|
||||||
|
\let\footnotesize\small
|
||||||
|
\let\footnoterule\relax
|
||||||
|
\let \footnote \thanks
|
||||||
|
|
||||||
|
\baselineskip = 1.4\baselineskip
|
||||||
|
\setbox0=\hbox{of the Requirements for the Degree}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\setcounter{page}{1}
|
||||||
|
\null\vfil
|
||||||
|
{\fontsize{12}{14}\selectfont \@title}
|
||||||
|
\vfil
|
||||||
|
\centerline{\hbox to \wd0 {\hbox{}\hrulefill\hbox{}}}
|
||||||
|
\vfil
|
||||||
|
A Thesis \\
|
||||||
|
Presented to \\
|
||||||
|
\@thedivisionof \ \@division \\
|
||||||
|
Reed College
|
||||||
|
\vfil
|
||||||
|
\centerline{\hbox to \wd0 {\hbox{}\hrulefill\hbox{}}}
|
||||||
|
\vfil
|
||||||
|
In Partial Fulfillment \\
|
||||||
|
of the Requirements for the Degree \\
|
||||||
|
Bachelor of Arts
|
||||||
|
\vfil
|
||||||
|
\centerline{\hbox to \wd0 {\hbox{}\hrulefill\hbox{}}}
|
||||||
|
\bigskip
|
||||||
|
\centerline{}
|
||||||
|
\bigskip
|
||||||
|
{\fontsize{12}{14}\selectfont \lineskip .75em
|
||||||
|
\begin{tabular}[t]{c}%
|
||||||
|
\@author
|
||||||
|
\end{tabular}\par}
|
||||||
|
\vskip 1.5em
|
||||||
|
{\fontsize{12}{14}\selectfont \@date \par}
|
||||||
|
\end{center}\par
|
||||||
|
\end{titlepage}
|
||||||
|
|
||||||
|
%% Approved for the division page
|
||||||
|
\cleardoublepage
|
||||||
|
{\fontsize{12}{14}
|
||||||
|
\setbox0=\hbox{Approved for the \@approvedforthe}
|
||||||
|
\thispagestyle{empty}
|
||||||
|
\null\vfil % just below center of page
|
||||||
|
\par\vskip 6cm % below center, not center
|
||||||
|
\centerline{\copy0} % approved
|
||||||
|
\centerline{(\@department)} %major
|
||||||
|
\vskip 1cm %space to sign
|
||||||
|
\centerline{\makebox[\wd0][c]{\hrulefill}
|
||||||
|
\if@altadvisor \makebox[.5in]{} \makebox[\wd0][c]{\hrulefill} \fi}
|
||||||
|
\centerline{\makebox[\wd0][c]{\@advisor}
|
||||||
|
\if@altadvisor \makebox[.5in]{} \makebox[\wd0][c]{\@altadvisor} \fi}
|
||||||
|
\par\vfil\null}
|
||||||
|
\cleardoublepage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_mime_type
|
def test_mime_type
|
||||||
assert_equal "application/octet-stream", blob("dog.o").mime_type
|
assert_equal "application/octet-stream", blob("dog.o").mime_type
|
||||||
|
assert_equal "application/ogg", blob("foo.ogg").mime_type
|
||||||
assert_equal "application/postscript", blob("octocat.ai").mime_type
|
assert_equal "application/postscript", blob("octocat.ai").mime_type
|
||||||
assert_equal "application/x-ruby", blob("grit.rb").mime_type
|
assert_equal "application/x-ruby", blob("grit.rb").mime_type
|
||||||
assert_equal "application/x-sh", blob("script.sh").mime_type
|
assert_equal "application/x-sh", blob("script.sh").mime_type
|
||||||
@@ -42,6 +43,7 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_content_type
|
def test_content_type
|
||||||
assert_equal "application/octet-stream", blob("dog.o").content_type
|
assert_equal "application/octet-stream", blob("dog.o").content_type
|
||||||
|
assert_equal "application/ogg", blob("foo.ogg").content_type
|
||||||
assert_equal "application/pdf", blob("foo.pdf").content_type
|
assert_equal "application/pdf", blob("foo.pdf").content_type
|
||||||
assert_equal "image/png", blob("foo.png").content_type
|
assert_equal "image/png", blob("foo.png").content_type
|
||||||
assert_equal "text/plain; charset=iso-8859-2", blob("README").content_type
|
assert_equal "text/plain; charset=iso-8859-2", blob("README").content_type
|
||||||
@@ -260,7 +262,7 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
def test_indexable
|
def test_indexable
|
||||||
assert blob("file.txt").indexable?
|
assert blob("file.txt").indexable?
|
||||||
assert blob("foo.rb").indexable?
|
assert blob("foo.rb").indexable?
|
||||||
assert !blob("defun.kt").indexable?
|
assert !blob("defu.nkt").indexable?
|
||||||
assert !blob("dump.sql").indexable?
|
assert !blob("dump.sql").indexable?
|
||||||
assert !blob("github.po").indexable?
|
assert !blob("github.po").indexable?
|
||||||
assert !blob("linguist.gem").indexable?
|
assert !blob("linguist.gem").indexable?
|
||||||
@@ -285,11 +287,18 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
assert_equal Language['Ruby'], blob("script.rb").language
|
assert_equal Language['Ruby'], blob("script.rb").language
|
||||||
assert_equal Language['Ruby'], blob("wrong_shebang.rb").language
|
assert_equal Language['Ruby'], blob("wrong_shebang.rb").language
|
||||||
assert_equal Language['Arduino'], blob("hello.ino").language
|
assert_equal Language['Arduino'], blob("hello.ino").language
|
||||||
|
assert_equal Language['VHDL'], blob("foo.vhd").language
|
||||||
assert_nil blob("octocat.png").language
|
assert_nil blob("octocat.png").language
|
||||||
|
|
||||||
# .cls disambiguation
|
# .cls disambiguation
|
||||||
assert_equal Language['OpenEdge ABL'], blob("openedge.cls").language
|
# https://github.com/abevoelker/abl-email-client/blob/master/com/abevoelker/email/Email.cls
|
||||||
assert_equal Language['TeX'], blob("latex.cls").language
|
assert_equal Language['OpenEdge ABL'], blob("Email.cls").language
|
||||||
|
# https://github.com/emcmanis/Thesis/blob/master/TeX/Thesis%20Template/reedthesis.cls
|
||||||
|
assert_equal Language['TeX'], blob("reedthesis.cls").language
|
||||||
|
# https://github.com/DangerMouseB/VLMessaging/blob/master/VLMMachineRouter/cApplication.cls
|
||||||
|
assert_equal Language['Visual Basic'], blob("cApplication.cls").language
|
||||||
|
# https://github.com/apex-commons/base/blob/master/src/classes/ArrayUtils.cls
|
||||||
|
assert_equal Language['Apex'], blob("ArrayUtils.cls").language
|
||||||
|
|
||||||
# .pl disambiguation
|
# .pl disambiguation
|
||||||
assert_equal Language['Prolog'], blob("test-prolog.pl").language
|
assert_equal Language['Prolog'], blob("test-prolog.pl").language
|
||||||
@@ -412,6 +421,12 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
|
|
||||||
# OpenEdge ABL / Progress
|
# OpenEdge ABL / Progress
|
||||||
assert_equal Language['OpenEdge ABL'], blob("openedge.p").language
|
assert_equal Language['OpenEdge ABL'], blob("openedge.p").language
|
||||||
|
|
||||||
|
# Tea
|
||||||
|
assert_equal Language['Tea'], blob("foo.tea").language
|
||||||
|
|
||||||
|
# Kotlin
|
||||||
|
assert_equal Language['Kotlin'], blob("Foo.kt").language
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_lexer
|
def test_lexer
|
||||||
@@ -421,6 +436,8 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
assert_equal Lexer['Ruby'], blob("grit.rb").lexer
|
assert_equal Lexer['Ruby'], blob("grit.rb").lexer
|
||||||
assert_equal Lexer['Scheme'], blob("dude.el").lexer
|
assert_equal Lexer['Scheme'], blob("dude.el").lexer
|
||||||
assert_equal Lexer['Text only'], blob("README").lexer
|
assert_equal Lexer['Text only'], blob("README").lexer
|
||||||
|
assert_equal Lexer['Tea'], blob("foo.tea").lexer
|
||||||
|
assert_equal Lexer['vhdl'], blob("foo.vhd").lexer
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_shebang_script
|
def test_shebang_script
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_ambiguous_extensions
|
def test_ambiguous_extensions
|
||||||
assert Language.ambiguous?('.cls')
|
assert Language.ambiguous?('.cls')
|
||||||
assert_equal Language['OpenEdge ABL'], Language.find_by_extension('cls')
|
assert_equal Language['TeX'], Language.find_by_extension('cls')
|
||||||
|
|
||||||
assert Language.ambiguous?('.h')
|
assert Language.ambiguous?('.h')
|
||||||
assert_equal Language['C'], Language.find_by_extension('h')
|
assert_equal Language['C'], Language.find_by_extension('h')
|
||||||
@@ -41,24 +41,24 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
assert_equal Lexer['C++'], Language['C++'].lexer
|
assert_equal Lexer['C++'], Language['C++'].lexer
|
||||||
assert_equal Lexer['Coldfusion HTML'], Language['ColdFusion'].lexer
|
assert_equal Lexer['Coldfusion HTML'], Language['ColdFusion'].lexer
|
||||||
assert_equal Lexer['Coq'], Language['Coq'].lexer
|
assert_equal Lexer['Coq'], Language['Coq'].lexer
|
||||||
|
assert_equal Lexer['FSharp'], Language['F#'].lexer
|
||||||
|
assert_equal Lexer['FSharp'], Language['F#'].lexer
|
||||||
assert_equal Lexer['Fortran'], Language['FORTRAN'].lexer
|
assert_equal Lexer['Fortran'], Language['FORTRAN'].lexer
|
||||||
assert_equal Lexer['Gherkin'], Language['Cucumber'].lexer
|
assert_equal Lexer['Gherkin'], Language['Cucumber'].lexer
|
||||||
|
assert_equal Lexer['Groovy'], Language['Groovy'].lexer
|
||||||
assert_equal Lexer['HTML'], Language['HTML'].lexer
|
assert_equal Lexer['HTML'], Language['HTML'].lexer
|
||||||
assert_equal Lexer['HTML+Django/Jinja'], Language['HTML+Django'].lexer
|
assert_equal Lexer['HTML+Django/Jinja'], Language['HTML+Django'].lexer
|
||||||
assert_equal Lexer['HTML+PHP'], Language['HTML+PHP'].lexer
|
assert_equal Lexer['HTML+PHP'], Language['HTML+PHP'].lexer
|
||||||
|
assert_equal Lexer['JSON'], Language['JSON'].lexer
|
||||||
assert_equal Lexer['Java'], Language['ChucK'].lexer
|
assert_equal Lexer['Java'], Language['ChucK'].lexer
|
||||||
assert_equal Lexer['Java'], Language['Groovy'].lexer
|
|
||||||
assert_equal Lexer['Java'], Language['Java'].lexer
|
assert_equal Lexer['Java'], Language['Java'].lexer
|
||||||
assert_equal Lexer['JavaScript'], Language['JSON'].lexer
|
|
||||||
assert_equal Lexer['JavaScript'], Language['JavaScript'].lexer
|
assert_equal Lexer['JavaScript'], Language['JavaScript'].lexer
|
||||||
assert_equal Lexer['MOOCode'], Language['Moocode'].lexer
|
assert_equal Lexer['MOOCode'], Language['Moocode'].lexer
|
||||||
assert_equal Lexer['MuPAD'], Language['mupad'].lexer
|
assert_equal Lexer['MuPAD'], Language['mupad'].lexer
|
||||||
assert_equal Lexer['NASM'], Language['Assembly'].lexer
|
assert_equal Lexer['NASM'], Language['Assembly'].lexer
|
||||||
assert_equal Lexer['OCaml'], Language['F#'].lexer
|
|
||||||
assert_equal Lexer['OCaml'], Language['OCaml'].lexer
|
assert_equal Lexer['OCaml'], Language['OCaml'].lexer
|
||||||
assert_equal Lexer['OpenEdge ABL'], Language['OpenEdge ABL'].lexer
|
|
||||||
assert_equal Lexer['Standard ML'], Language['Standard ML'].lexer
|
|
||||||
assert_equal Lexer['Ooc'], Language['ooc'].lexer
|
assert_equal Lexer['Ooc'], Language['ooc'].lexer
|
||||||
|
assert_equal Lexer['OpenEdge ABL'], Language['OpenEdge ABL'].lexer
|
||||||
assert_equal Lexer['REBOL'], Language['Rebol'].lexer
|
assert_equal Lexer['REBOL'], Language['Rebol'].lexer
|
||||||
assert_equal Lexer['RHTML'], Language['HTML+ERB'].lexer
|
assert_equal Lexer['RHTML'], Language['HTML+ERB'].lexer
|
||||||
assert_equal Lexer['RHTML'], Language['RHTML'].lexer
|
assert_equal Lexer['RHTML'], Language['RHTML'].lexer
|
||||||
@@ -69,6 +69,7 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
assert_equal Lexer['Scheme'], Language['Nu'].lexer
|
assert_equal Lexer['Scheme'], Language['Nu'].lexer
|
||||||
assert_equal Lexer['Scheme'], Language['Racket'].lexer
|
assert_equal Lexer['Scheme'], Language['Racket'].lexer
|
||||||
assert_equal Lexer['Scheme'], Language['Scheme'].lexer
|
assert_equal Lexer['Scheme'], Language['Scheme'].lexer
|
||||||
|
assert_equal Lexer['Standard ML'], Language['Standard ML'].lexer
|
||||||
assert_equal Lexer['TeX'], Language['TeX'].lexer
|
assert_equal Lexer['TeX'], Language['TeX'].lexer
|
||||||
assert_equal Lexer['Text only'], Language['Text'].lexer
|
assert_equal Lexer['Text only'], Language['Text'].lexer
|
||||||
assert_equal Lexer['Verilog'], Language['Verilog'].lexer
|
assert_equal Lexer['Verilog'], Language['Verilog'].lexer
|
||||||
@@ -112,7 +113,7 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
assert_equal Language['OpenEdge ABL'], Language.find_by_alias('progress')
|
assert_equal Language['OpenEdge ABL'], Language.find_by_alias('progress')
|
||||||
assert_equal Language['OpenEdge ABL'], Language.find_by_alias('abl')
|
assert_equal Language['OpenEdge ABL'], Language.find_by_alias('abl')
|
||||||
assert_equal Language['Parrot Internal Representation'], Language.find_by_alias('pir')
|
assert_equal Language['Parrot Internal Representation'], Language.find_by_alias('pir')
|
||||||
assert_equal Language['Powershell'], Language.find_by_alias('posh')
|
assert_equal Language['PowerShell'], Language.find_by_alias('posh')
|
||||||
assert_equal Language['Puppet'], Language.find_by_alias('puppet')
|
assert_equal Language['Puppet'], Language.find_by_alias('puppet')
|
||||||
assert_equal Language['Pure Data'], Language.find_by_alias('pure-data')
|
assert_equal Language['Pure Data'], Language.find_by_alias('pure-data')
|
||||||
assert_equal Language['Raw token data'], Language.find_by_alias('raw')
|
assert_equal Language['Raw token data'], Language.find_by_alias('raw')
|
||||||
@@ -196,7 +197,7 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
def test_programming
|
def test_programming
|
||||||
assert_equal :programming, Language['JavaScript'].type
|
assert_equal :programming, Language['JavaScript'].type
|
||||||
assert_equal :programming, Language['Perl'].type
|
assert_equal :programming, Language['Perl'].type
|
||||||
assert_equal :programming, Language['Powershell'].type
|
assert_equal :programming, Language['PowerShell'].type
|
||||||
assert_equal :programming, Language['Python'].type
|
assert_equal :programming, Language['Python'].type
|
||||||
assert_equal :programming, Language['Ruby'].type
|
assert_equal :programming, Language['Ruby'].type
|
||||||
end
|
end
|
||||||
@@ -249,9 +250,9 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
assert_equal Language['PHP'], Language.find_by_extension('php3')
|
assert_equal Language['PHP'], Language.find_by_extension('php3')
|
||||||
assert_equal Language['PHP'], Language.find_by_extension('php4')
|
assert_equal Language['PHP'], Language.find_by_extension('php4')
|
||||||
assert_equal Language['PHP'], Language.find_by_extension('php5')
|
assert_equal Language['PHP'], Language.find_by_extension('php5')
|
||||||
assert_equal Language['Powershell'], Language.find_by_extension('psm1')
|
assert_equal Language['PowerShell'], Language.find_by_extension('psm1')
|
||||||
assert_equal Language['Powershell'], Language.find_by_extension('ps1')
|
assert_equal Language['PowerShell'], Language.find_by_extension('ps1')
|
||||||
assert_nil Language.find_by_extension('.kt')
|
assert_nil Language.find_by_extension('.nkt')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_find_all_by_extension
|
def test_find_all_by_extension
|
||||||
@@ -270,7 +271,7 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
assert_equal Language['Ruby'], Language.find_by_filename('Rakefile')
|
assert_equal Language['Ruby'], Language.find_by_filename('Rakefile')
|
||||||
assert_nil Language.find_by_filename('rb')
|
assert_nil Language.find_by_filename('rb')
|
||||||
assert_nil Language.find_by_filename('.rb')
|
assert_nil Language.find_by_filename('.rb')
|
||||||
assert_nil Language.find_by_filename('.kt')
|
assert_nil Language.find_by_filename('.nkt')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_find
|
def test_find
|
||||||
@@ -291,12 +292,36 @@ class TestLanguage < Test::Unit::TestCase
|
|||||||
assert_equal 'Ruby', Language['Ruby'].name
|
assert_equal 'Ruby', Language['Ruby'].name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_escaped_name
|
||||||
|
assert_equal 'C', Language['C'].escaped_name
|
||||||
|
assert_equal 'C%23', Language['C#'].escaped_name
|
||||||
|
assert_equal 'C%2B%2B', Language['C++'].escaped_name
|
||||||
|
assert_equal 'Objective-C', Language['Objective-C'].escaped_name
|
||||||
|
assert_equal 'Common%20Lisp', Language['Common Lisp'].escaped_name
|
||||||
|
assert_equal 'Max%2FMSP', Language['Max/MSP'].escaped_name
|
||||||
|
end
|
||||||
|
|
||||||
def test_error_without_name
|
def test_error_without_name
|
||||||
assert_raise ArgumentError do
|
assert_raise ArgumentError do
|
||||||
Language.new :name => nil
|
Language.new :name => nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_ace_mode
|
||||||
|
assert_equal 'c_cpp', Language['C++'].ace_mode
|
||||||
|
assert_equal 'coffee', Language['CoffeeScript'].ace_mode
|
||||||
|
assert_equal 'csharp', Language['C#'].ace_mode
|
||||||
|
assert_equal 'css', Language['CSS'].ace_mode
|
||||||
|
assert_equal 'javascript', Language['JavaScript'].ace_mode
|
||||||
|
assert_equal 'text', Language['Text'].ace_mode
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_ace_modes
|
||||||
|
assert Language.ace_modes.include?(Language['Text'])
|
||||||
|
assert Language.ace_modes.include?(Language['Ruby'])
|
||||||
|
assert !Language.ace_modes.include?(Language['FORTRAN'])
|
||||||
|
end
|
||||||
|
|
||||||
def test_extensions
|
def test_extensions
|
||||||
assert Language['Perl'].extensions.include?('.pl')
|
assert Language['Perl'].extensions.include?('.pl')
|
||||||
assert Language['Python'].extensions.include?('.py')
|
assert Language['Python'].extensions.include?('.py')
|
||||||
|
|||||||
@@ -14,6 +14,20 @@ class TestMime < Test::Unit::TestCase
|
|||||||
# in mimes.yml. Its still useful to test even trivial cases since
|
# in mimes.yml. Its still useful to test even trivial cases since
|
||||||
# MIME::Type's extension lookup may return multiple matches and we
|
# MIME::Type's extension lookup may return multiple matches and we
|
||||||
# only pick one of them. Please keep this list alphabetized.
|
# only pick one of them. Please keep this list alphabetized.
|
||||||
|
assert_equal 'application/javascript', Mime.mime_for('.js')
|
||||||
|
assert_equal 'application/octet-stream', Mime.mime_for('.dll')
|
||||||
|
assert_equal 'application/octet-stream', Mime.mime_for('.dmg')
|
||||||
|
assert_equal 'application/octet-stream', Mime.mime_for('.exe')
|
||||||
|
assert_equal 'application/ogg', Mime.mime_for('.ogg')
|
||||||
|
assert_equal 'application/postscript', Mime.mime_for('.ai')
|
||||||
|
assert_equal 'application/postscript', Mime.mime_for('.eps')
|
||||||
|
assert_equal 'application/postscript', Mime.mime_for('.ps')
|
||||||
|
assert_equal 'application/vnd.adobe.air-application-installer-package+zip', Mime.mime_for('.air')
|
||||||
|
assert_equal 'application/vnd.oasis.opendocument.presentation', Mime.mime_for('.odp')
|
||||||
|
assert_equal 'application/vnd.oasis.opendocument.spreadsheet', Mime.mime_for('.ods')
|
||||||
|
assert_equal 'application/vnd.oasis.opendocument.text', Mime.mime_for('.odt')
|
||||||
|
assert_equal 'application/vnd.openofficeorg.extension', Mime.mime_for('.oxt')
|
||||||
|
assert_equal 'application/vnd.openxmlformats-officedocument.presentationml.presentation', Mime.mime_for('.pptx')
|
||||||
assert_equal 'application/x-chrome-extension', Mime.mime_for('.crx')
|
assert_equal 'application/x-chrome-extension', Mime.mime_for('.crx')
|
||||||
assert_equal 'application/x-debian-package', Mime.mime_for('.deb')
|
assert_equal 'application/x-debian-package', Mime.mime_for('.deb')
|
||||||
assert_equal 'application/x-iwork-keynote-sffkey', Mime.mime_for('.key')
|
assert_equal 'application/x-iwork-keynote-sffkey', Mime.mime_for('.key')
|
||||||
@@ -22,37 +36,19 @@ class TestMime < Test::Unit::TestCase
|
|||||||
assert_equal 'application/x-java-archive', Mime.mime_for('.ear')
|
assert_equal 'application/x-java-archive', Mime.mime_for('.ear')
|
||||||
assert_equal 'application/x-java-archive', Mime.mime_for('.jar')
|
assert_equal 'application/x-java-archive', Mime.mime_for('.jar')
|
||||||
assert_equal 'application/x-java-archive', Mime.mime_for('.war')
|
assert_equal 'application/x-java-archive', Mime.mime_for('.war')
|
||||||
assert_equal 'application/javascript', Mime.mime_for('.js')
|
|
||||||
assert_equal 'application/x-latex', Mime.mime_for('.latex')
|
assert_equal 'application/x-latex', Mime.mime_for('.latex')
|
||||||
assert_equal 'application/x-ms-xbap', Mime.mime_for('.xbap')
|
assert_equal 'application/x-ms-xbap', Mime.mime_for('.xbap')
|
||||||
assert_equal 'application/octet-stream', Mime.mime_for('.dll')
|
|
||||||
assert_equal 'application/octet-stream', Mime.mime_for('.dmg')
|
|
||||||
assert_equal 'application/octet-stream', Mime.mime_for('.exe')
|
|
||||||
assert_equal 'application/x-perl', Mime.mime_for('.pl')
|
assert_equal 'application/x-perl', Mime.mime_for('.pl')
|
||||||
assert_equal 'application/x-perl', Mime.mime_for('.pm')
|
assert_equal 'application/x-perl', Mime.mime_for('.pm')
|
||||||
assert_equal 'application/postscript', Mime.mime_for('.ai')
|
|
||||||
assert_equal 'application/postscript', Mime.mime_for('.eps')
|
|
||||||
assert_equal 'application/postscript', Mime.mime_for('.ps')
|
|
||||||
assert_equal 'application/x-python', Mime.mime_for('.py')
|
assert_equal 'application/x-python', Mime.mime_for('.py')
|
||||||
assert_equal 'application/x-ruby', Mime.mime_for('.rb')
|
assert_equal 'application/x-ruby', Mime.mime_for('.rb')
|
||||||
assert_equal 'application/x-sh', Mime.mime_for('.sh')
|
assert_equal 'application/x-sh', Mime.mime_for('.sh')
|
||||||
assert_equal 'application/x-shockwave-flash', Mime.mime_for('.swf')
|
assert_equal 'application/x-shockwave-flash', Mime.mime_for('.swf')
|
||||||
assert_equal 'application/x-silverlight-app', Mime.mime_for('.xap')
|
assert_equal 'application/x-silverlight-app', Mime.mime_for('.xap')
|
||||||
assert_equal 'application/x-supercollider', Mime.mime_for('.sc')
|
assert_equal 'application/x-supercollider', Mime.mime_for('.sc')
|
||||||
assert_equal 'application/vnd.adobe.air-application-installer-package+zip', Mime.mime_for('.air')
|
|
||||||
assert_equal 'application/vnd.oasis.opendocument.presentation', Mime.mime_for('.odp')
|
|
||||||
assert_equal 'application/vnd.oasis.opendocument.spreadsheet', Mime.mime_for('.ods')
|
|
||||||
assert_equal 'application/vnd.oasis.opendocument.text', Mime.mime_for('.odt')
|
|
||||||
assert_equal 'application/vnd.openofficeorg.extension', Mime.mime_for('.oxt')
|
|
||||||
assert_equal 'application/vnd.openxmlformats-officedocument.presentationml.presentation', Mime.mime_for('.pptx')
|
|
||||||
assert_equal 'application/xaml+xml', Mime.mime_for('.xaml')
|
assert_equal 'application/xaml+xml', Mime.mime_for('.xaml')
|
||||||
assert_equal 'text/cache-manifest', Mime.mime_for('.manifest')
|
assert_equal 'text/cache-manifest', Mime.mime_for('.manifest')
|
||||||
assert_equal 'text/html', Mime.mime_for('.html')
|
assert_equal 'text/html', Mime.mime_for('.html')
|
||||||
assert_equal 'text/x-nemerle', Mime.mime_for('.n')
|
|
||||||
assert_equal 'text/x-nimrod', Mime.mime_for('.nim')
|
|
||||||
assert_equal 'text/x-ocaml', Mime.mime_for('.ml')
|
|
||||||
assert_equal 'text/x-ocaml', Mime.mime_for('.sig')
|
|
||||||
assert_equal 'text/x-ocaml', Mime.mime_for('.sml')
|
|
||||||
assert_equal 'text/plain', Mime.mime_for('.c')
|
assert_equal 'text/plain', Mime.mime_for('.c')
|
||||||
assert_equal 'text/plain', Mime.mime_for('.cc')
|
assert_equal 'text/plain', Mime.mime_for('.cc')
|
||||||
assert_equal 'text/plain', Mime.mime_for('.cpp')
|
assert_equal 'text/plain', Mime.mime_for('.cpp')
|
||||||
@@ -63,8 +59,13 @@ class TestMime < Test::Unit::TestCase
|
|||||||
assert_equal 'text/plain', Mime.mime_for('.hpp')
|
assert_equal 'text/plain', Mime.mime_for('.hpp')
|
||||||
assert_equal 'text/plain', Mime.mime_for('.kt')
|
assert_equal 'text/plain', Mime.mime_for('.kt')
|
||||||
assert_equal 'text/x-logtalk', Mime.mime_for('.lgt')
|
assert_equal 'text/x-logtalk', Mime.mime_for('.lgt')
|
||||||
assert_equal 'text/x-rust', Mime.mime_for('.rs')
|
assert_equal 'text/x-nemerle', Mime.mime_for('.n')
|
||||||
|
assert_equal 'text/x-nimrod', Mime.mime_for('.nim')
|
||||||
|
assert_equal 'text/x-ocaml', Mime.mime_for('.ml')
|
||||||
|
assert_equal 'text/x-ocaml', Mime.mime_for('.sig')
|
||||||
|
assert_equal 'text/x-ocaml', Mime.mime_for('.sml')
|
||||||
assert_equal 'text/x-rust', Mime.mime_for('.rc')
|
assert_equal 'text/x-rust', Mime.mime_for('.rc')
|
||||||
|
assert_equal 'text/x-rust', Mime.mime_for('.rs')
|
||||||
assert_equal 'video/quicktime', Mime.mime_for('.mov')
|
assert_equal 'video/quicktime', Mime.mime_for('.mov')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class TestPathname < Test::Unit::TestCase
|
|||||||
assert_equal Language['Python'], Pathname.new("itty.py").language
|
assert_equal Language['Python'], Pathname.new("itty.py").language
|
||||||
assert_equal Language['Nu'], Pathname.new("itty.nu").language
|
assert_equal Language['Nu'], Pathname.new("itty.nu").language
|
||||||
|
|
||||||
assert_nil Pathname.new("defun.kt").language
|
assert_nil Pathname.new("defu.nkt").language
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_lexer
|
def test_lexer
|
||||||
@@ -50,13 +50,13 @@ class TestPathname < Test::Unit::TestCase
|
|||||||
assert_equal Lexer['Bash'], Pathname.new("file.ebuild").lexer
|
assert_equal Lexer['Bash'], Pathname.new("file.ebuild").lexer
|
||||||
assert_equal Lexer['Python'], Pathname.new("itty.py").lexer
|
assert_equal Lexer['Python'], Pathname.new("itty.py").lexer
|
||||||
assert_equal Lexer['Scheme'], Pathname.new("itty.nu").lexer
|
assert_equal Lexer['Scheme'], Pathname.new("itty.nu").lexer
|
||||||
assert_equal Lexer['Text only'], Pathname.new("defun.kt").lexer
|
assert_equal Lexer['Text only'], Pathname.new("defu.nkt").lexer
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_mime_type
|
def test_mime_type
|
||||||
assert_equal 'application/x-ruby', Pathname.new("file.rb").mime_type
|
assert_equal 'application/x-ruby', Pathname.new("file.rb").mime_type
|
||||||
assert_equal 'application/javascript', Pathname.new("file.js").mime_type
|
assert_equal 'application/javascript', Pathname.new("file.js").mime_type
|
||||||
assert_equal 'application/x-python', Pathname.new("itty.py").mime_type
|
assert_equal 'application/x-python', Pathname.new("itty.py").mime_type
|
||||||
assert_equal 'text/plain', Pathname.new("defun.kt").mime_type
|
assert_equal 'text/plain', Pathname.new("defu.nkt").mime_type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user