project ( http://nitlanguage.org ).
Files: *
-Copyright: 2004-2015 Jean Privat <jean@pryen.org>
+Copyright: 2004-2016 Jean Privat <jean@pryen.org>
2006-2008 Floréal Morandat <morandat@lirmm.fr>
2009 Julien Chevalier <chevjulien@gmail.com>
2009-2011 Jean-Sebastien Gelinas <calestar@gmail.com>
- 2009-2015 Alexis Laferrière <alexis.laf@xymus.net>
+ 2009-2016 Alexis Laferrière <alexis.laf@xymus.net>
2011 Matthieu Auger <matthieu.auger@gmail.com>
- 2011-2015 Alexandre Terrasa <alexandre@moz-code.org>
+ 2011-2016 Alexandre Terrasa <alexandre@moz-code.org>
2012 Alexandre Pennetier <alexandre.pennetier@me.com>
- 2013-2015 Lucas Bajolet <r4pass@hotmail.com>
+ 2013-2016 Lucas Bajolet <r4pass@hotmail.com>
2013 Stefan Lage <lagestfan@gmail.com>
2013 Nathan Heu <heu.nathan@courrier.uqam.ca>
2013 Matthieu Lucas <lucasmatthieu@gmail.com>
- 2014-2015 Romain Chanoir <romain.chanoir@viacesi.fr>
- 2014 Frédéric Vachon <fredvac@gmail.com>
+ 2014-2016 Romain Chanoir <romain.chanoir@viacesi.fr>
+ 2014-2015 Frédéric Vachon <fredvac@gmail.com>
2014 Johan Kayser <johan.kayser@viacesi.fr>
2014-2015 Julien Pagès <julien.projet@gmail.com>
2014 Geoffrey Hecht <geoffrey.hecht@gmail.com>
- 2014 Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
+ 2014-2016 Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
2015 Arthur Delamare <arthur.delamare@viacesi.fr>
+ 2015-2016 Mehdi Ait Younes <overpex@gmail.com>
+ 2015 Renata Carvalho <renatawm@gmail.com>
+ 2015 Simon Zeni <simonzeni@gmail.com>
+ 2015 Anis Boubaker <anis@boubaker.ca>
+ 2015 Istvan SZALAI <szalai972@gmail.com>
+ 2015 Hervé Matysiak <herve.matysiak@viacesi.fr>
+ 2015 Jean-Philippe Caissy <jean-philippe.caissy@shopify.com>
+ 2015 Alexandre Blondin Massé <alexandre.blondin.masse@gmail.com>
+ 2015-2016 Guilherme Mansur <guilhermerpmansur@gmail.com>
License: Apache 2.0 (see LICENSE)
Comment: The main license of the work, except for the following exceptions
Files: lib/*
clib/*
share/nitdoc/*
-Copyright: 2004-2015 Jean Privat <jean@pryen.org>
+Copyright: 2004-2016 Jean Privat <jean@pryen.org>
2006-2008 Floréal Morandat <morandat@lirmm.fr>
2009-2011 Jean-Sebastien Gelinas <calestar@gmail.com>
- 2009-2015 Alexis Laferrière <alexis.laf@xymus.net>
+ 2009-2016 Alexis Laferrière <alexis.laf@xymus.net>
2009 Julien Chevalier <chevjulien@gmail.com>
- 2011-2015 Alexandre Terrasa <alexandre@moz-concept.com>
+ 2011-2016 Alexandre Terrasa <alexandre@moz-concept.com>
2012 Alexandre Pennetier <alexandre.pennetier@me.com>
- 2013-2015 Lucas Bajolet <r4pass@hotmail.com>
+ 2013-2016 Lucas Bajolet <r4pass@hotmail.com>
2013 Nathan Heu <heu.nathan@courrier.uqam.ca>
2013 Matthieu Lucas <lucasmatthieu@gmail.com>
2013 Stefan Lage <lagestfan@gmail.com>
2014 Maxime Leroy <maxime.leroy76@gmail.com>
2014 Johann Dubois <johann.dubois@outlook.com>
2014-2015 Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
- 2014 Alexandre Blondin Massé <alexandre.blondin.masse@gmail.com>
+ 2014-2015 Alexandre Blondin Massé <alexandre.blondin.masse@gmail.com>
+ 2015 Mehdi Ait Younes <overpex@gmail.com>
+ 2015 Budi Kurniawan <budi2020@gmail.com>
+ 2015-2016 Philippe Pepos Petitclerc <ppeposp@gmail.com>
+ 2015-2016 Guilherme Mansur <guilhermerpmansur@gmail.com>
Licence: BSD 2 (see LICENSE-BSD)
Comment: Use of libraries and resources is basically unrestricted. We hold the copyright
on the compiler and the tools but not on the programs made by the users.
# Gen a test db with a random name (to avoid race conditions).
fun gen_test_db: MongoDb do
- var db_name = "test_nitrpg_{get_time}_{1000.rand}"
+ var testid = "NIT_TESTING_ID".environ.to_i
+ var db_name = "test_nitrpg_{testid}"
var db = load_db(db_name)
test_dbs.add db
return db
do
return command.to_cstring.system
end
+
+ # The pid of the program
+ fun pid: Int `{ return getpid(); `}
end
redef class NativeString
# SEE: `abstract_text::Text` for more info on the difference
# between `Text::bytelen` and `Text::length`.
fun to_s_full(bytelen, unilen: Int): String is abstract
+
+ # Copies the content of `src` to `self`
+ #
+ # NOTE: `self` must be large enough to withold `self.bytelen` bytes
+ fun fill_from(src: Text) do src.copy_to_native(self, src.bytelen, 0, 0)
end
redef class NativeArray[E]
end
return res
end
+
+ redef fun copy_to_native(dst, n, src_off, dst_off) do
+ _items.copy_to(dst, n, first_byte + src_off, dst_off)
+ end
end
# Immutable strings of characters.
end
redef fun copy_to_native(dest, n, src_offset, dest_offset) do
- var subs = new RopeSubstrings.from(self, src_offset)
- var st = src_offset - subs.pos
- var off = dest_offset
- while n > 0 do
- var it = subs.item
- if n > it.length then
- var cplen = it.length - st
- it._items.copy_to(dest, cplen, st, off)
- off += cplen
- n -= cplen
- else
- it._items.copy_to(dest, n, st, off)
- n = 0
- end
- subs.next
- st = 0
+ var l = _left
+ if src_offset < l.bytelen then
+ var lcopy = l.bytelen - src_offset
+ lcopy = if lcopy > n then n else lcopy
+ l.copy_to_native(dest, lcopy, src_offset, dest_offset)
+ dest_offset += lcopy
+ n -= lcopy
+ src_offset = 0
end
+ _right.copy_to_native(dest, n, src_offset, dest_offset)
end
# Returns a balanced version of `self`
module crapto
import english_utils
+import xor
--- /dev/null
+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
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import base64
+import crapto
+
+# Check usage
+if args.length != 1 then
+ print "Usage: repeating_key_xor_solve <cipher_file>"
+ exit 1
+end
+
+# Read the cipher from the file
+var cipher_bytes = args[0].to_path.read_all_bytes.decode_base64
+
+# Create a RepeatingKeyXorCipher object to manipulate your ciphertext
+var xorcipher = new RepeatingKeyXorCipher
+xorcipher.ciphertext = cipher_bytes
+
+# Try to find the best candidate key
+xorcipher.find_key
+
+# Decrypt the cipher according to the found key
+xorcipher.decrypt
+
+# Check the resulting plaintext out...
+print xorcipher.plaintext
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Cryptographic attacks and utilities for XOR-based algorithms.
+module xor
+
+import combinations
+import crypto
+import english_utils
+
+redef class SingleByteXorCipher
+ # Tries to find key using frequency analysis on all possible plaintexts.
+ # Populates `self.key`
+ fun find_key do
+
+ # Accumulate best result
+ var max = 0.0
+ var best = 0.to_b
+
+ # Iterate on possible values for a byte
+ var xor_b = new Bytes.with_capacity(1)
+ for b in [0 .. 255] do
+ # Need `Bytes` to pass to xor
+ xor_b[0] = b.to_b
+
+ # Xor and evaluate result
+ var xored = ciphertext.xorcipher(xor_b)
+ var result = xored.to_s.english_scoring
+ if result > max then
+ max = result
+ best = b.to_b
+ end
+ end
+
+ self.key = best
+
+ end
+end
+
+redef class RepeatingKeyXorCipher
+ # Attempts to find the key by using frequency analysis on the resulting plaintexts.
+ # Best key lengths are estimated using the hamming distance of blocks of keylength bytes.
+ # Ciphertext is then transposed in such a way that it can be solved by sequences of
+ # SingleByteXor (one for each offset in the key).
+ #
+ # `min_keylength` and `max_keylength` are limits as to what key lengths are tested.
+ # `considered_keylength_count` is the number of best key lengths that are kept to be
+ # analysed by the SingleByteXor frequency analysis.
+ fun find_key(min_keylength, max_keylength, considered_keylength_count: nullable Int) do
+
+ # Set default values
+ if min_keylength == null then min_keylength = 2
+ if max_keylength == null then max_keylength = 40
+ if considered_keylength_count == null then considered_keylength_count = 3
+
+ # Find the best candidate key lengths based on the normalized hamming distances
+ var best_sizes = get_normalized_hamming_distances(min_keylength, max_keylength, considered_keylength_count)
+
+ var best = 0.0
+ var best_key: nullable Bytes = null
+ for ks in best_sizes do
+
+ # Rearrange ciphertext to be in SingleByteXORable blocks
+ var transposed = transpose_ciphertext(ks)
+
+ var key = new Bytes.empty
+ for slot in transposed do
+ var sbx = new SingleByteXorCipher
+ sbx.ciphertext = slot
+ sbx.find_key
+ key.add sbx.key
+ end
+
+ # Evaluate the resulting plaintext based on english frequency analysis
+ var eng_score = ciphertext.xorcipher(key).to_s.english_scoring
+ if eng_score > best then
+ best_key = key
+ best = eng_score
+ end
+
+ assert best_key != null
+ self.key = best_key
+
+ end
+ end
+
+ # Computes the normalized hamming distances between blocks of ciphertext of length between `min_length` and `max_length`.
+ # The `considered_keylength_count` smallest results are returned
+ private fun get_normalized_hamming_distances(min_keylength, max_keylength, considered_keylength_count: Int): Array[Int] do
+
+ var normalized_distances = new HashMap[Float, Int]
+
+ # Iterate over all given key lengths
+ for ks in [min_keylength .. max_keylength[ do
+
+ # Initialize the blocks of size `ks`
+ var blocks = new Array[Bytes]
+ while (blocks.length + 1) * ks < ciphertext.length do
+ blocks.add(ciphertext.slice(blocks.length * ks, ks))
+ end
+
+ # Compute the normalized hamming distance with all block combinations
+ var pairs = new CombinationCollection[Bytes](blocks, 2)
+ var hamming_dists = new Array[Float]
+ for p in pairs do
+ hamming_dists.add(p[0].hamming_distance(p[1]).to_f / ks.to_f)
+ end
+
+ # Normalize the results based on the number of blocks
+ var normalized = 0.0
+ for dist in hamming_dists do normalized += dist
+ normalized /= hamming_dists.length.to_f
+ normalized_distances[normalized] = ks
+
+ end
+
+ # Collect the best candidates
+ var distances = normalized_distances.keys.to_a
+ default_comparator.sort(distances)
+ var best_distances = distances.subarray(0, considered_keylength_count)
+ var best_sizes = [for d in best_distances do normalized_distances[d]]
+
+ return best_sizes
+ end
+
+ # Returns a rearranged format of the ciphertext where every byte of a slot will be XORed with the same offset of a key of length `keylength`.
+ private fun transpose_ciphertext(keylength: Int): Array[Bytes] do
+ var transposed = new Array[Bytes]
+ for i in [0 .. keylength[ do
+ transposed.add(new Bytes.empty)
+ end
+
+ for byte_idx in [0 .. ciphertext.length[ do
+ transposed[byte_idx % keylength].add(ciphertext[byte_idx])
+ end
+
+ return transposed
+ end
+end
# See the License for the specific language governing permissions and
# limitations under the License.
-# Mix of all things cryptography-related
-module crypto
+# Basic cryptographic ciphers and utilities.
+module basic_ciphers
redef class Char
# Rotates self of `x`
end
redef class Bytes
-
- # Returns `self` xored with `key`
- #
- # The key is cycled through until the `self` has been completely xored.
- #
- # assert "goodmorning".to_bytes.xorcipher(" ".to_bytes) == "GOODMORNING".bytes
- fun xorcipher(key: Bytes): Bytes do
- var xored = new Bytes.with_capacity(self.length)
-
- for i in self.length.times do
- xored.add(self[i] ^ key[i % key.length])
+ # Computes the edit/hamming distance of two sequences of bytes.
+ #
+ # assert "this is a test".to_bytes.hamming_distance("wokka wokka!!!".bytes) == 37
+ # assert "this is a test".to_bytes.hamming_distance("this is a test".bytes) == 0
+ #
+ fun hamming_distance(other: SequenceRead[Byte]): Int do
+ var diff = 0
+ for idx in self.length.times do
+ var res_byte = self[idx] ^ other[idx]
+ for bit in [0..8[ do
+ if res_byte & 1u8 == 1u8 then diff += 1
+ res_byte = res_byte >> 1
+ end
end
-
- return xored
+ return diff
end
end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Mix of all things cryptography-related
+module crypto
+
+import basic_ciphers
+import xor_ciphers
[upstream]
browse=https://github.com/nitlang/nit/tree/master/lib/crypto.nit
git=https://github.com/nitlang/nit.git
-git.directory=lib/crypto.nit
+git.directory=lib/crypto/crypto.nit
homepage=http://nitlanguage.org
issues=https://github.com/nitlang/nit/issues
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# XOR oriented cryptographic ciphers and utilities.
+module xor_ciphers
+
+redef class Bytes
+ # Returns `self` xored with `key`
+ #
+ # The key is cycled through until the `self` has been completely xored.
+ #
+ # assert "goodmorning".to_bytes.xorcipher(" ".to_bytes) == "GOODMORNING".bytes
+ fun xorcipher(key: Bytes): Bytes do
+ var xored = new Bytes.with_capacity(self.length)
+
+ for i in self.length.times do
+ xored.add(self[i] ^ key[i % key.length])
+ end
+
+ return xored
+ end
+end
+
+# Base class to modelize cryptographic ciphers
+abstract class Cipher
+
+ # Encrypted data
+ var ciphertext = new Bytes.empty is writable
+
+ # Unencrypted data
+ var plaintext = new Bytes.empty is writable
+
+ # Encrypt plaintext and populate `self.ciphertext`
+ fun encrypt is abstract
+
+ # Decrypt ciphertext and populate `self.plaintext`
+ fun decrypt is abstract
+
+end
+
+# Simple XOR cipher where the whole plaintext is XORed with a single byte.
+class SingleByteXorCipher
+ super Cipher
+
+ # Cryptographic key used in encryption and decryption.
+ var key: Byte = 0.to_b
+
+ redef fun encrypt do
+ var key_bytes = new Bytes.with_capacity(1)
+ key_bytes.add(key)
+ ciphertext = plaintext.xorcipher(key_bytes)
+ end
+
+ redef fun decrypt do
+ var key_bytes = new Bytes.with_capacity(1)
+ key_bytes.add(key)
+ plaintext = ciphertext.xorcipher(key_bytes)
+ end
+end
+
+# XOR cipher where the key is repeated to match the length of the message.
+class RepeatingKeyXorCipher
+ super Cipher
+
+ # Cryptographic key used in encryption and decryption.
+ var key = new Bytes.empty
+
+ redef fun encrypt do
+ assert key.length > 0
+ ciphertext = plaintext.xorcipher(key)
+ end
+
+ redef fun decrypt do
+ assert key.length > 0
+ plaintext = ciphertext.xorcipher(key)
+ end
+end
## CUSTOMIZATION
-### `--sharedir`
-Directory containing nitdoc assets.
+### `--share-dir`
+Directory containing tools assets.
By default `$NIT_DIR/share/nitdoc/` is used.
Indicate the specific Nit compiler executable to use. See `--nitc`.
+### `NIT_TESTING`
+
+The environment variable `NIT_TESTING` is set to `true` during the execution of program tests.
+Some libraries of programs can use it to produce specific reproducible results; or just to exit their executions.
+
+Unit-tests may unset this environment variable to retrieve the original behavior of such piece of software.
+
+### `SRAND`
+
+In order to maximize reproducibility, `SRAND` is set to 0.
+This make the pseudo-random generator no random at all.
+See `Sys::srand` for details.
+
+To retrieve the randomness, unit-tests may unset this environment variable then call `srand`.
+
+### `NIT_TESTING_ID`
+
+Parallel executions can cause some race collisions on named resources (e.g. DB table names).
+To solve this issue, `NIT_TESTING_ID` is initialized with a distinct integer identifier that can be used to give unique names to resources.
+
+Note: `rand` is not a recommended way to get a distinct identifier because its randomness is disabled by default. See `SRAND`.
+
+
# SEE ALSO
The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>
var opt_source = new OptionString("Format to link source code (%f for filename, " +
"%l for first line, %L for last line)", "--source")
- # Directory where the CSS and JS is stored.
- var opt_sharedir = new OptionString("Directory containing nitdoc assets", "--sharedir")
-
# Use a shareurl instead of copy shared files.
#
# This is usefull if you don't want to store the Nitdoc templates with your
super
option_context.add_option(
- opt_source, opt_sharedir, opt_shareurl, opt_custom_title,
+ opt_source, opt_share_dir, opt_shareurl, opt_custom_title,
opt_custom_footer, opt_custom_intro, opt_custom_brand,
opt_github_upstream, opt_github_base_sha1, opt_github_gitdir,
opt_piwik_tracker, opt_piwik_site_id,
var output_dir = ctx.output_dir
if not output_dir.file_exists then output_dir.mkdir
# locate share dir
- var sharedir = ctx.opt_sharedir.value
- if sharedir == null then
- var dir = ctx.nit_dir
- sharedir = dir/"share/nitdoc"
- if not sharedir.file_exists then
- print "Error: cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
- abort
- end
- end
+ var sharedir = ctx.share_dir / "nitdoc"
# copy shared files
if ctx.opt_shareurl.value == null then
sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/* {output_dir.to_s.escape_to_sh}/")
import ordered_tree
private import more_collections
+redef class MEntity
+ # The visibility of the MEntity.
+ #
+ # MPackages, MGroups and MModules are always public.
+ # The visibility of `MClass` and `MProperty` is defined by the keyword used.
+ # `MClassDef` and `MPropDef` return the visibility of `MClass` and `MProperty`.
+ fun visibility: MVisibility do return public_visibility
+end
+
redef class Model
# All known classes
var mclasses = new Array[MClass]
# The visibility of the class
# In Nit, the visibility of a class cannot evolve in refinements
- var visibility: MVisibility
+ redef var visibility
init
do
redef var location: Location
+ redef fun visibility do return mclass.visibility
+
# Internal name combining the module and the class
# Example: "mymodule$MyClass"
redef var to_s is noinit
end
# The visibility of the property
- var visibility: MVisibility
+ redef var visibility
# Is the property usable as an initializer?
var is_autoinit = false is writable
redef var location: Location
+ redef fun visibility do return mproperty.visibility
+
init
do
mclassdef.mpropdefs.add(self)
var mmodules = new HashSet[MModule]
mmodules.add self
mmodules.add_all collect_ancestors(view)
- mmodules.add_all collect_parents(view)
- mmodules.add_all collect_children(view)
mmodules.add_all collect_descendants(view)
return view.mmodules_poset(mmodules)
end
return res
end
+ # Build a class hierarchy poset for `self` based on its ancestors and descendants.
+ fun hierarchy_poset(mainmodule: MModule, view: ModelView): POSet[MClass] do
+ var mclasses = new HashSet[MClass]
+ mclasses.add self
+ mclasses.add_all collect_ancestors(view)
+ mclasses.add_all collect_descendants(view)
+ return view.mclasses_poset(mainmodule, mclasses)
+ end
+
# Collect all mproperties introduced in 'self' with `visibility >= min_visibility`.
fun collect_intro_mproperties(view: ModelView): Set[MProperty] do
var set = new HashSet[MProperty]
obj["class_name"] = class_name
obj["full_name"] = full_name
obj["mdoc"] = mdoc_or_fallback
+ obj["visibility"] = visibility
+ obj["location"] = location
var modifiers = new JsonArray
for modifier in collect_modifiers do
modifiers.add modifier
redef fun json do
var obj = super
- obj["visibility"] = public_visibility
if ini != null then
obj["ini"] = new JsonObject.from(ini.as(not null).to_map)
end
redef class MGroup
redef fun json do
var obj = super
- obj["visibility"] = public_visibility
obj["is_root"] = is_root
obj["mpackage"] = to_mentity_ref(mpackage)
obj["default_mmodule"] = to_mentity_ref(default_mmodule)
redef class MModule
redef fun json do
var obj = super
- obj["location"] = location
- obj["visibility"] = public_visibility
obj["mpackage"] = to_mentity_ref(mpackage)
obj["mgroup"] = to_mentity_ref(mgroup)
obj["intro_mclasses"] = to_mentity_refs(intro_mclasses)
redef class MClass
redef fun json do
var obj = super
- obj["visibility"] = visibility
var arr = new JsonArray
for mparameter in mparameters do arr.add mparameter
obj["mparameters"] = arr
redef class MClassDef
redef fun json do
var obj = super
- obj["visibility"] = mclass.visibility
- obj["location"] = location
obj["is_intro"] = is_intro
var arr = new JsonArray
for mparameter in mclass.mparameters do arr.add mparameter
redef class MProperty
redef fun json do
var obj = super
- obj["visibility"] = visibility
obj["intro"] = to_mentity_ref(intro)
obj["intro_mclassdef"] = to_mentity_ref(intro_mclassdef)
obj["mpropdefs"] = to_mentity_refs(mpropdefs)
redef class MPropDef
redef fun json do
var obj = super
- obj["visibility"] = mproperty.visibility
- obj["location"] = location
obj["is_intro"] = is_intro
obj["mclassdef"] = to_mentity_ref(mclassdef)
obj["mproperty"] = to_mentity_ref(mproperty)
# See the specific implementation in the subclasses.
fun visit_all(v: ModelVisitor) do end
- private fun accept_visibility(min_visibility: nullable MVisibility): Bool do return true
+ private fun accept_visibility(min_visibility: nullable MVisibility): Bool do
+ if min_visibility == null then return true
+ return visibility >= min_visibility
+ end
end
redef class Model
end
end
-redef class MClass
- redef fun accept_visibility(min_visibility) do
- if min_visibility == null then return true
- return visibility >= min_visibility
- end
-end
-
redef class MClassDef
# Visit all the classes and class definitions of the module.
#
v.enter_visit(x)
end
end
-
- redef fun accept_visibility(min_visibility) do
- if min_visibility == null then return true
- return mclass.visibility >= min_visibility
- end
-end
-
-redef class MProperty
- redef fun accept_visibility(min_visibility) do
- if min_visibility == null then return true
- return visibility >= min_visibility
- end
-end
-
-redef class MPropDef
- redef fun accept_visibility(min_visibility) do
- if min_visibility == null then return true
- return mproperty.visibility >= min_visibility
- end
end
end
"NIT_TESTING".setenv("true")
+"NIT_TESTING_ID".setenv(pid.to_s)
+"SRAND".setenv("0")
var test_dir = toolcontext.test_dir
test_dir.mkdir
import modelize
private import parser_util
import html
+import console
redef class ToolContext
# opt --full
#
# Default: 10 CPU minute
var ulimit_usertime = 600 is writable
+
+ # Show a single-line status to use as a progression.
+ #
+ # Note that the line starts with `'\r'` and is not ended by a `'\n'`.
+ # So it is expected that:
+ # * no other output is printed between two calls
+ # * the last `show_unit_status` is followed by a new-line
+ fun show_unit_status(name: String, tests: SequenceRead[UnitTest], more_message: nullable String)
+ do
+ var esc = 27.code_point.to_s
+ var line = "\r{esc}[K* {name} ["
+ var done = tests.length
+ for t in tests do
+ if not t.is_done then
+ line += " "
+ done -= 1
+ else if t.error == null then
+ line += ".".green.bold
+ else
+ line += "X".red.bold
+ end
+ end
+ line += "] {done}/{tests.length}"
+ if more_message != null then
+ line += " " + more_message
+ end
+ printn "{line}"
+ end
+
end
-# A unit test is an elementary test discovered, run and reported bu nitunit.
+# A unit test is an elementary test discovered, run and reported by nitunit.
#
# This class factorizes `DocUnit` and `TestCase`.
abstract class UnitTest
+ # The name of the unit to show in messages
+ fun full_name: String is abstract
+
+ # The location of the unit test to show in messages.
+ fun location: Location is abstract
- # Error occurred during test-case execution.
+ # Flag that indicates if the unit test was compiled/run.
+ var is_done: Bool = false is writable
+
+ # Error message occurred during test-case execution (or compilation).
+ #
+ # e.g.: `Runtime Error`
var error: nullable String = null is writable
# Was the test case executed at least once?
+ #
+ # This will indicate the status of the test (failture or error)
var was_exec = false is writable
- # Return the `TestCase` in XML format compatible with Jenkins.
+ # The raw output of the execution (or compilation)
#
- # See to_xml
+ # It merges the standard output and error output
+ var raw_output: nullable String = null is writable
+
+ # The location where the error occurred, if it makes sense.
+ var error_location: nullable Location = null is writable
+
+ # A colorful `[OK]` or `[KO]`.
+ fun status_tag: String do
+ if not is_done then
+ return "[ ]"
+ else if error != null then
+ return "[KO]".red.bold
+ else
+ return "[OK]".green.bold
+ end
+ end
+
+ # The full (color) description of the test-case.
+ #
+ # `more message`, if any, is added after the error message.
+ fun to_screen(more_message: nullable String): String do
+ var res
+ var error = self.error
+ if error != null then
+ if more_message != null then error += " " + more_message
+ var loc = error_location or else location
+ res = "{status_tag} {full_name}\n {loc.to_s.yellow}: {error}\n{loc.colored_line("1;31")}"
+ var output = self.raw_output
+ if output != null then
+ res += "\n Output\n\t{output.chomp.replace("\n", "\n\t")}\n"
+ end
+ else
+ res = "{status_tag} {full_name}"
+ if more_message != null then res += more_message
+ end
+ return res
+ end
+
+ # Return a `<testcase>` XML node in format compatible with Jenkins unit tests.
fun to_xml: HTMLTag do
var tc = new HTMLTag("testcase")
tc.attr("classname", xml_classname)
var error = self.error
if error != null then
if was_exec then
- tc.open("error").append("Runtime Error")
+ tc.open("error").append(error)
else
- tc.open("failure").append("Compilation Error")
+ tc.open("failure").append(error)
end
- tc.open("system-err").append(error.trunc(8192).filter_nonprintable)
+ end
+ var output = self.raw_output
+ if output != null then
+ tc.open("system-err").append(output.trunc(8192).filter_nonprintable)
end
return tc
end
# The `classname` attribute of the XML format.
#
# NOTE: jenkins expects a '.' in the classname attr
+ #
+ # See to_xml
fun xml_classname: String is abstract
# The `name` attribute of the XML format.
# The XML node associated to the module
var testsuite: HTMLTag
+ # The name of the suite
+ var name: String
+
# Markdown processor used to parse markdown comments and extract code.
var mdproc = new MarkdownProcessor
# Populate `blocks` from the markdown decorator
mdproc.process(mdoc.content.join("\n"))
-
- toolcontext.check_errors
end
# All extracted docunits
var docunits = new Array[DocUnit]
+ fun show_status(more_message: nullable String)
+ do
+ toolcontext.show_unit_status(name, docunits, more_message)
+ end
+
+ fun mark_done(du: DocUnit)
+ do
+ du.is_done = true
+ show_status(du.full_name + " " + du.status_tag)
+ end
+
# Execute all the docunits
fun run_tests
do
+ if docunits.is_empty then
+ return
+ end
+
var simple_du = new Array[DocUnit]
+ show_status
for du in docunits do
# Skip existing errors
- if du.error != null then continue
+ if du.error != null then
+ mark_done(du)
+ continue
+ end
var ast = toolcontext.parse_something(du.block)
if ast isa AExpr then
test_simple_docunits(simple_du)
+ show_status
+ print ""
+
+ for du in docunits do
+ print du.to_screen
+ end
+
for du in docunits do
testsuite.add du.to_xml
end
i += 1
toolcontext.info("Execute doc-unit {du.full_name} in {file} {i}", 1)
var res2 = toolcontext.safe_exec("{file.to_program_name}.bin {i} >'{file}.out1' 2>&1 </dev/null")
+ du.was_exec = true
var content = "{file}.out1".to_path.read_all
- var msg = content.trunc(8192).filter_nonprintable
+ du.raw_output = content
if res2 != 0 then
- du.error = content
- toolcontext.warning(du.location, "error", "ERROR: {du.full_name} (in {file}): Runtime error\n{msg}")
+ du.error = "Runtime error in {file} with argument {i}"
toolcontext.modelbuilder.failed_entities += 1
end
- toolcontext.check_errors
+ mark_done(du)
end
end
var res2 = 0
if res == 0 then
res2 = toolcontext.safe_exec("{file.to_program_name}.bin >'{file}.out1' 2>&1 </dev/null")
+ du.was_exec = true
end
var content = "{file}.out1".to_path.read_all
- var msg = content.trunc(8192).filter_nonprintable
+ du.raw_output = content
if res != 0 then
- du.error = content
- toolcontext.warning(du.location, "failure", "FAILURE: {du.full_name} (in {file}):\n{msg}")
+ du.error = "Compilation error in {file}"
toolcontext.modelbuilder.failed_entities += 1
else if res2 != 0 then
- toolcontext.warning(du.location, "error", "ERROR: {du.full_name} (in {file}):\n{msg}")
+ du.error = "Runtime error in {file}"
toolcontext.modelbuilder.failed_entities += 1
end
- toolcontext.check_errors
+ mark_done(du)
end
# Create and fill the header of a unit file `file`.
message = "Error: Invalid Nit code."
end
- executor.toolcontext.warning(location, "invalid-block", "{message} To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`).")
- executor.toolcontext.modelbuilder.failed_entities += 1
-
var du = new_docunit
du.block += code
- du.error = "{location}: {message}"
+ du.error_location = location
+ du.error = message
+ executor.toolcontext.modelbuilder.failed_entities += 1
return
end
# The numbering of self in mdoc (starting with 0)
var number: Int
- # The name of the unit to show in messages
- fun full_name: String do
+ redef fun full_name do
var mentity = mdoc.original_mentity
- if mentity != null then return mentity.full_name
- return xml_classname + "." + xml_name
+ if mentity != null then
+ return mentity.full_name
+ else
+ return xml_classname + "." + xml_name
+ end
end
# The text of the code to execute.
#
# If `self` is made of multiple code-blocks, then the location
# starts at the first code-books and finish at the last one, thus includes anything between.
- var location: Location is lazy do
+ redef var location is lazy do
return new Location(mdoc.location.file, lines.first, lines.last+1, columns.first+1, 0)
end
var prefix = toolcontext.test_dir
prefix = prefix.join_path(mmodule.to_s)
- var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts)
+ var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts, "Docunits of module {mmodule.full_name}")
do
total_entities += 1
var prefix = toolcontext.test_dir
prefix = prefix.join_path(mgroup.to_s)
- var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts)
+ var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts, "Docunits of group {mgroup.full_name}")
total_entities += 1
var mdoc = mgroup.mdoc
ts.attr("package", file)
var prefix = toolcontext.test_dir / "file"
- var d2m = new NitUnitExecutor(toolcontext, prefix, null, ts)
+ var d2m = new NitUnitExecutor(toolcontext, prefix, null, ts, "Docunits of file {file}")
total_entities += 1
doc_entities += 1
# Test to be executed after the whole test suite.
var after_module: nullable TestCase = null
+ fun show_status(more_message: nullable String)
+ do
+ toolcontext.show_unit_status("Test-suite of module " + mmodule.full_name, test_cases, more_message)
+ end
+
# Execute the test suite
fun run do
+ show_status
if not toolcontext.test_dir.file_exists then
toolcontext.test_dir.mkdir
end
toolcontext.info("Execute test-suite {mmodule.name}", 1)
var before_module = self.before_module
if not before_module == null then before_module.run
- for case in test_cases do case.run
+ for case in test_cases do
+ case.run
+ show_status(case.full_name + " " + case.status_tag)
+ end
+
+ show_status
+ print ""
+
var after_module = self.after_module
if not after_module == null then after_module.run
+ for case in test_cases do
+ print case.to_screen
+ end
end
# Write the test unit for `self` in a nit compilable file.
# Test method to be compiled and tested.
var test_method: MMethodDef
+ redef fun full_name do return test_method.full_name
+
+ redef fun location do return test_method.location
+
# `ToolContext` to use to display messages and find `nitc` bin.
var toolcontext: ToolContext
var test_file = test_suite.test_file
var res_name = "{test_file}_{method_name.escape_to_c}"
var res = toolcontext.safe_exec("{test_file}.bin {method_name} > '{res_name}.out1' 2>&1 </dev/null")
- var f = new FileReader.open("{res_name}.out1")
- var msg = f.read_all
- f.close
+ self.raw_output = "{res_name}.out1".to_path.read_all
# set test case result
- var loc = test_method.location
if res != 0 then
- error = msg
- toolcontext.warning(loc, "failure",
- "ERROR: {method_name} (in file {test_file}.nit): {msg}")
+ error = "Runtime Error in file {test_file}.nit"
toolcontext.modelbuilder.failed_tests += 1
else
+ # no error, check with res file, if any.
var mmodule = test_method.mclassdef.mmodule
var file = mmodule.filepath
if file != null then
toolcontext.info("Diff output with {sav}", 1)
res = toolcontext.safe_exec("diff -u --label 'expected:{sav}' --label 'got:{res_name}.out1' '{sav}' '{res_name}.out1' > '{res_name}.diff' 2>&1 </dev/null")
if res != 0 then
- msg = "Diff\n" + "{res_name}.diff".to_path.read_all
- error = msg
- toolcontext.warning(loc, "failure",
- "ERROR: {method_name} (in file {test_file}.nit): {msg}")
+ self.raw_output = "Diff\n" + "{res_name}.diff".to_path.read_all
+ error = "Difference with expected output: diff -u {sav} {res_name}.out1"
toolcontext.modelbuilder.failed_tests += 1
end
else
end
end
end
- toolcontext.check_errors
+ is_done = true
end
redef fun xml_classname do
# Option --nit-dir
var opt_nit_dir = new OptionString("Base directory of the Nit installation", "--nit-dir")
+ # Option --share-dir
+ var opt_share_dir = new OptionString("Directory containing tools assets", "--share-dir")
+
# Option --help
var opt_help = new OptionBool("Show Help (This screen)", "-h", "-?", "--help")
# The identified root directory of the Nit package
var nit_dir: String is noinit
+ # Shared files directory.
+ #
+ # Most often `nit/share/`.
+ var share_dir: String is lazy do
+ var sharedir = opt_share_dir.value
+ if sharedir == null then
+ sharedir = nit_dir / "share"
+ if not sharedir.file_exists then
+ fatal_error(null, "Fatal Error: cannot locate shared files directory in {sharedir}. Uses --share-dir to define it's location.")
+ end
+ end
+ return sharedir
+ end
+
private fun compute_nit_dir: String
do
# the option has precedence
test_rubix_cube
test_rubix_visual
test_csv
+repeating_key_xor_solve
test_rubix_visual
test_rubix_cube
test_csv
+repeating_key_xor_solve
--- /dev/null
+../lib/crapto/examples/repeating_key_xor_cipher.txt
-test_nitunit.nit:21,7--22,0: ERROR: test_nitunit$X (in .nitunit/test_nitunit-2.nit):
-Runtime error: Assert failed (.nitunit/test_nitunit-2.nit:5)
+\r\e[K* Docunits of module test_nitunit::test_nitunit [ ] 0/4\r\e[K* Docunits of module test_nitunit::test_nitunit [ \e[1m\e[31mX\e[m\e[m] 1/4 test_nitunit$X$foo1 \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of module test_nitunit::test_nitunit [\e[1m\e[32m.\e[m\e[m \e[1m\e[31mX\e[m\e[m] 2/4 test_nitunit::test_nitunit \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_nitunit::test_nitunit [\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m \e[1m\e[31mX\e[m\e[m] 3/4 test_nitunit$X \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of module test_nitunit::test_nitunit [\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m] 4/4 test_nitunit$X$foo \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of module test_nitunit::test_nitunit [\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m] 4/4
+\e[1m\e[32m[OK]\e[m\e[m test_nitunit::test_nitunit
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit$X
+ \e[33mtest_nitunit.nit:21,7--22,0\e[m: Runtime error in .nitunit/test_nitunit-2.nit
+ # \e[1;31massert false\e[0m
+ ^
+ Output
+ Runtime error: Assert failed (.nitunit/test_nitunit-2.nit:5)
-test_nitunit.nit:24,8--25,0: FAILURE: test_nitunit$X$foo (in .nitunit/test_nitunit-3.nit):
-.nitunit/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit$X$foo
+ \e[33mtest_nitunit.nit:24,8--25,0\e[m: Compilation error in .nitunit/test_nitunit-3.nit
+ # \e[1;31massert undefined_identifier\e[0m
+ ^
+ Output
+ .nitunit/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
-test_test_nitunit.nit:36,2--40,4: ERROR: test_foo1 (in file .nitunit/gen_test_test_nitunit.nit): Runtime error: Assert failed (test_test_nitunit.nit:39)
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit$X$foo1
+ \e[33mtest_nitunit.nit:28,15\e[m: Syntax Error: unexpected operator '!'.
+ # assert \e[1;31m!\e[0m@#$%^&*()
+ ^
+\r\e[K* Test-suite of module test_test_nitunit::test_test_nitunit [ ] 0/3\r\e[K* Test-suite of module test_test_nitunit::test_test_nitunit [\e[1m\e[32m.\e[m\e[m ] 1/3 test_test_nitunit$TestX$test_foo \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Test-suite of module test_test_nitunit::test_test_nitunit [\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m ] 2/3 test_test_nitunit$TestX$test_foo1 \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Test-suite of module test_test_nitunit::test_test_nitunit [\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[32m.\e[m\e[m] 3/3 test_test_nitunit$TestX$test_foo2 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Test-suite of module test_test_nitunit::test_test_nitunit [\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[32m.\e[m\e[m] 3/3
+\e[1m\e[32m[OK]\e[m\e[m test_test_nitunit$TestX$test_foo
+\e[1m\e[31m[KO]\e[m\e[m test_test_nitunit$TestX$test_foo1
+ \e[33mtest_test_nitunit.nit:36,2--40,4\e[m: Runtime Error in file .nitunit/gen_test_test_nitunit.nit
+ \e[1;31m# will fail\e[0m
+ ^
+ Output
+ Runtime error: Assert failed (test_test_nitunit.nit:39)
+\e[1m\e[32m[OK]\e[m\e[m test_test_nitunit$TestX$test_foo2
DocUnits:
-Entities: 27; Documented ones: 3; With nitunits: 3; Failures: 2
+Entities: 27; Documented ones: 4; With nitunits: 4; Failures: 3
TestSuites:
Class suites: 1; Test Cases: 3; Failures: 1
-<testsuites><testsuite package="test_nitunit::test_nitunit"><testcase classname="nitunit.test_nitunit::test_nitunit.<module>" name="<module>"><system-out>assert true
-</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="<class>"><system-out>assert false
-</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="test_nitunit::X::foo"><failure>Compilation Error</failure><system-err>.nitunit/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
+<testsuites><testsuite package="test_nitunit::test_nitunit"><testcase classname="nitunit.test_nitunit::test_nitunit.<module>" name="<module>"><system-err></system-err><system-out>assert true
+</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="<class>"><error>Runtime error in .nitunit/test_nitunit-2.nit</error><system-err>Runtime error: Assert failed (.nitunit/test_nitunit-2.nit:5)
+</system-err><system-out>assert false
+</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="test_nitunit::X::foo"><failure>Compilation error in .nitunit/test_nitunit-3.nit</failure><system-err>.nitunit/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
</system-err><system-out>assert undefined_identifier
-</system-out></testcase></testsuite><testsuite package="test_test_nitunit"><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo"></testcase><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo1"><error>Runtime Error</error><system-err>Runtime error: Assert failed (test_test_nitunit.nit:39)
-</system-err></testcase><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo2"></testcase></testsuite></testsuites>
\ No newline at end of file
+</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="test_nitunit::X::foo1"><failure>Syntax Error: unexpected operator '!'.</failure><system-out>assert !@#$%^&*()
+</system-out></testcase></testsuite><testsuite package="test_test_nitunit"><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo"><system-err></system-err></testcase><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo1"><error>Runtime Error in file .nitunit/gen_test_test_nitunit.nit</error><system-err>Runtime error: Assert failed (test_test_nitunit.nit:39)
+</system-err></testcase><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo2"><system-err></system-err></testcase></testsuite></testsuites>
\ No newline at end of file
+\r\e[K* Docunits of module test_nitunit2::test_nitunit2 [ ] 0/3\r\e[K* Docunits of module test_nitunit2::test_nitunit2 [\e[1m\e[32m.\e[m\e[m ] 1/3 test_nitunit2::test_nitunit2$core::Sys$foo1 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_nitunit2::test_nitunit2 [\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m ] 2/3 test_nitunit2::test_nitunit2$core::Sys$bar2 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_nitunit2::test_nitunit2 [\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m] 3/3 test_nitunit2::test_nitunit2$core::Sys$foo3 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_nitunit2::test_nitunit2 [\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m] 3/3
+\e[1m\e[32m[OK]\e[m\e[m test_nitunit2::test_nitunit2$core::Sys$foo1
+\e[1m\e[32m[OK]\e[m\e[m test_nitunit2::test_nitunit2$core::Sys$bar2
+\e[1m\e[32m[OK]\e[m\e[m test_nitunit2::test_nitunit2$core::Sys$foo3
DocUnits:
DocUnits Success
Entities: 4; Documented ones: 3; With nitunits: 3; Failures: 0
TestSuites:
No test cases found
Class suites: 0; Test Cases: 0; Failures: 0
-<testsuites><testsuite package="test_nitunit2::test_nitunit2"><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::foo1"><system-out>if true then
+<testsuites><testsuite package="test_nitunit2::test_nitunit2"><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::foo1"><system-err></system-err><system-out>if true then
assert true
end
-</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::bar2"><system-out>if true then
+</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::bar2"><system-err></system-err><system-out>if true then
assert true
end
-</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::foo3"><system-out>var a = 1
+</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::foo3"><system-err></system-err><system-out>var a = 1
assert a == 1
assert a == 1
</system-out></testcase></testsuite><testsuite></testsuite></testsuites>
\ No newline at end of file
+\r\e[K* Docunits of module test_doc2::test_doc2 [ ] 0/3\r\e[K* Docunits of module test_doc2::test_doc2 [\e[1m\e[32m.\e[m\e[m ] 1/3 test_doc2::test_doc2$core::Sys$foo1 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_doc2::test_doc2 [\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m ] 2/3 test_doc2::test_doc2$core::Sys$foo2 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_doc2::test_doc2 [\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m] 3/3 test_doc2::test_doc2$core::Sys$foo3 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_doc2::test_doc2 [\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m\e[1m\e[32m.\e[m\e[m] 3/3
+\e[1m\e[32m[OK]\e[m\e[m test_doc2::test_doc2$core::Sys$foo1
+\e[1m\e[32m[OK]\e[m\e[m test_doc2::test_doc2$core::Sys$foo2
+\e[1m\e[32m[OK]\e[m\e[m test_doc2::test_doc2$core::Sys$foo3
DocUnits:
DocUnits Success
Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 0
TestSuites:
No test cases found
Class suites: 0; Test Cases: 0; Failures: 0
-<testsuites><testsuite package="test_doc2::test_doc2"><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo1"><system-out>assert true # tested
-</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo2"><system-out>assert true # tested
-</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo3"><system-out>assert true # tested
+<testsuites><testsuite package="test_doc2::test_doc2"><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo1"><system-err></system-err><system-out>assert true # tested
+</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo2"><system-err></system-err><system-out>assert true # tested
+</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo3"><system-err></system-err><system-out>assert true # tested
</system-out></testcase></testsuite><testsuite></testsuite></testsuites>
\ No newline at end of file
-test_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\]. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`).
-test_nitunit3/README.md:4,2--15,0: ERROR: test_nitunit3> (in .nitunit/test_nitunit3-0.nit): Runtime error
-Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7)
+\r\e[K* Docunits of group test_nitunit3> [ ] 0/2\r\e[K* Docunits of group test_nitunit3> [ \e[1m\e[31mX\e[m\e[m] 1/2 test_nitunit3> \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of group test_nitunit3> [\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m] 2/2 test_nitunit3> \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of group test_nitunit3> [\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m] 2/2
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit3>
+ \e[33mtest_nitunit3/README.md:4,2--15,0\e[m: Runtime error in .nitunit/test_nitunit3-0.nit with argument 1
+ ~\e[1;31m~\e[0m
+ ^
+ Output
+ Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7)
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit3>
+ \e[33mtest_nitunit3/README.md:7,3--5\e[m: Syntax Error: unexpected malformed character '\].
+ ~~\e[1;31m~
+;\e[0m
+ ^
+\r\e[K* Docunits of module test_nitunit3::test_nitunit3 [ ] 0/1\r\e[K* Docunits of module test_nitunit3::test_nitunit3 [\e[1m\e[32m.\e[m\e[m] 1/1 test_nitunit3::test_nitunit3 \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Docunits of module test_nitunit3::test_nitunit3 [\e[1m\e[32m.\e[m\e[m] 1/1
+\e[1m\e[32m[OK]\e[m\e[m test_nitunit3::test_nitunit3
DocUnits:
Entities: 2; Documented ones: 2; With nitunits: 3; Failures: 2
TestSuites:
No test cases found
Class suites: 0; Test Cases: 0; Failures: 0
-<testsuites><testsuite package="test_nitunit3>"><testcase classname="nitunit.test_nitunit3>" name="<group>"><failure>Compilation Error</failure><system-err>Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7)
+<testsuites><testsuite package="test_nitunit3>"><testcase classname="nitunit.test_nitunit3>" name="<group>"><error>Runtime error in .nitunit/test_nitunit3-0.nit with argument 1</error><system-err>Runtime error: Assert failed (.nitunit/test_nitunit3-0.nit:7)
</system-err><system-out>assert false
assert true
-</system-out></testcase><testcase classname="nitunit.test_nitunit3>" name="<group>+1"><failure>Compilation Error</failure><system-err>test_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\].</system-err><system-out>;'\][]
-</system-out></testcase></testsuite><testsuite package="test_nitunit3::test_nitunit3"><testcase classname="nitunit.test_nitunit3::test_nitunit3.<module>" name="<module>"><system-out>assert true
+</system-out></testcase><testcase classname="nitunit.test_nitunit3>" name="<group>+1"><failure>Syntax Error: unexpected malformed character '\].</failure><system-out>;'\][]
+</system-out></testcase></testsuite><testsuite package="test_nitunit3::test_nitunit3"><testcase classname="nitunit.test_nitunit3::test_nitunit3.<module>" name="<module>"><system-err></system-err><system-out>assert true
</system-out></testcase></testsuite><testsuite></testsuite></testsuites>
\ No newline at end of file
-test_nitunit_md.md:4,2--16,0: ERROR: nitunit.<file>.test_nitunit_md.md:1,0--15,0 (in .nitunit/file-0.nit): Runtime error
-Runtime error: Assert failed (.nitunit/file-0.nit:8)
+\r\e[K* Docunits of file test_nitunit_md.md:1,0--15,0 [ ] 0/1\r\e[K* Docunits of file test_nitunit_md.md:1,0--15,0 [\e[1m\e[31mX\e[m\e[m] 1/1 nitunit.<file>.test_nitunit_md.md:1,0--15,0 \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of file test_nitunit_md.md:1,0--15,0 [\e[1m\e[31mX\e[m\e[m] 1/1
+\e[1m\e[31m[KO]\e[m\e[m nitunit.<file>.test_nitunit_md.md:1,0--15,0
+ \e[33mtest_nitunit_md.md:4,2--16,0\e[m: Runtime error in .nitunit/file-0.nit with argument 1
+ ~\e[1;31m~\e[0m
+ ^
+ Output
+ Runtime error: Assert failed (.nitunit/file-0.nit:8)
DocUnits:
Entities: 1; Documented ones: 1; With nitunits: 1; Failures: 1
TestSuites:
No test cases found
Class suites: 0; Test Cases: 0; Failures: 0
-<testsuites><testsuite package="test_nitunit_md.md:1,0--15,0"><testcase classname="nitunit.<file>" name="test_nitunit_md.md:1,0--15,0"><failure>Compilation Error</failure><system-err>Runtime error: Assert failed (.nitunit/file-0.nit:8)
+<testsuites><testsuite package="test_nitunit_md.md:1,0--15,0"><testcase classname="nitunit.<file>" name="test_nitunit_md.md:1,0--15,0"><error>Runtime error in .nitunit/file-0.nit with argument 1</error><system-err>Runtime error: Assert failed (.nitunit/file-0.nit:8)
</system-err><system-out>var a = 1
assert 1 == 1
assert false
-test_doc3.nit:17,9--15: Syntax Error: unexpected identifier 'garbage'. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`).
-test_doc3.nit:23,4--10: Syntax Error: unexpected identifier 'garbage'. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`).
-test_doc3.nit:30,4--10: Syntax Error: unexpected identifier 'garbage'. To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`).
+\r\e[K* Docunits of module test_doc3::test_doc3 [ ] 0/3\r\e[K* Docunits of module test_doc3::test_doc3 [\e[1m\e[31mX\e[m\e[m ] 1/3 test_doc3::test_doc3$core::Sys$foo1 \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of module test_doc3::test_doc3 [\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m ] 2/3 test_doc3::test_doc3$core::Sys$foo2 \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of module test_doc3::test_doc3 [\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m] 3/3 test_doc3::test_doc3$core::Sys$foo3 \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Docunits of module test_doc3::test_doc3 [\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m\e[1m\e[31mX\e[m\e[m] 3/3
+\e[1m\e[31m[KO]\e[m\e[m test_doc3::test_doc3$core::Sys$foo1
+ \e[33mtest_doc3.nit:17,9--15\e[m: Syntax Error: unexpected identifier 'garbage'.
+ # *\e[1;31mgarbage\e[0m*
+ ^
+\e[1m\e[31m[KO]\e[m\e[m test_doc3::test_doc3$core::Sys$foo2
+ \e[33mtest_doc3.nit:23,4--10\e[m: Syntax Error: unexpected identifier 'garbage'.
+ # *\e[1;31mgarbage\e[0m*
+ ^
+\e[1m\e[31m[KO]\e[m\e[m test_doc3::test_doc3$core::Sys$foo3
+ \e[33mtest_doc3.nit:30,4--10\e[m: Syntax Error: unexpected identifier 'garbage'.
+ # *\e[1;31mgarbage\e[0m*
+ ^
DocUnits:
Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 3
TestSuites:
No test cases found
Class suites: 0; Test Cases: 0; Failures: 0
-<testsuites><testsuite package="test_doc3::test_doc3"><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo1"><failure>Compilation Error</failure><system-err>test_doc3.nit:17,9--15: Syntax Error: unexpected identifier 'garbage'.</system-err><system-out> *garbage*
-</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo2"><failure>Compilation Error</failure><system-err>test_doc3.nit:23,4--10: Syntax Error: unexpected identifier 'garbage'.</system-err><system-out>*garbage*
-</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo3"><failure>Compilation Error</failure><system-err>test_doc3.nit:30,4--10: Syntax Error: unexpected identifier 'garbage'.</system-err><system-out>*garbage*
+<testsuites><testsuite package="test_doc3::test_doc3"><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo1"><failure>Syntax Error: unexpected identifier 'garbage'.</failure><system-out> *garbage*
+</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo2"><failure>Syntax Error: unexpected identifier 'garbage'.</failure><system-out>*garbage*
+</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo3"><failure>Syntax Error: unexpected identifier 'garbage'.</failure><system-out>*garbage*
</system-out></testcase></testsuite><testsuite></testsuite></testsuites>
\ No newline at end of file
-test_nitunit4/test_nitunit4.nit:22,2--26,4: ERROR: test_foo (in file .nitunit/gen_test_nitunit4.nit): Before Test
-Tested method
-After Test
-Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31)
+\r\e[K* Test-suite of module test_nitunit4::test_nitunit4 [ ] 0/3\r\e[K* Test-suite of module test_nitunit4::test_nitunit4 [\e[1m\e[31mX\e[m\e[m ] 1/3 test_nitunit4$TestTestSuite$test_foo \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Test-suite of module test_nitunit4::test_nitunit4 [\e[1m\e[31mX\e[m\e[m\e[1m\e[32m.\e[m\e[m ] 2/3 test_nitunit4$TestTestSuite$test_bar \e[1m\e[32m[OK]\e[m\e[m\r\e[K* Test-suite of module test_nitunit4::test_nitunit4 [\e[1m\e[31mX\e[m\e[m\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m] 3/3 test_nitunit4$TestTestSuite$test_baz \e[1m\e[31m[KO]\e[m\e[m\r\e[K* Test-suite of module test_nitunit4::test_nitunit4 [\e[1m\e[31mX\e[m\e[m\e[1m\e[32m.\e[m\e[m\e[1m\e[31mX\e[m\e[m] 3/3
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit4$TestTestSuite$test_foo
+ \e[33mtest_nitunit4/test_nitunit4.nit:22,2--26,4\e[m: Runtime Error in file .nitunit/gen_test_nitunit4.nit
+ \e[1;31mfun test_foo do\e[0m
+ ^
+ Output
+ Before Test
+ Tested method
+ After Test
+ Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31)
-test_nitunit4/test_nitunit4.nit:32,2--34,4: ERROR: test_baz (in file .nitunit/gen_test_nitunit4.nit): Diff
---- expected:test_nitunit4/test_nitunit4.sav/test_baz.res
-+++ got:.nitunit/gen_test_nitunit4_test_baz.out1
-@@ -1 +1,3 @@
--Bad result file
-+Before Test
-+Tested method
-+After Test
+\e[1m\e[32m[OK]\e[m\e[m test_nitunit4$TestTestSuite$test_bar
+\e[1m\e[31m[KO]\e[m\e[m test_nitunit4$TestTestSuite$test_baz
+ \e[33mtest_nitunit4/test_nitunit4.nit:32,2--34,4\e[m: Difference with expected output: diff -u test_nitunit4/test_nitunit4.sav/test_baz.res .nitunit/gen_test_nitunit4_test_baz.out1
+ \e[1;31mfun test_baz do\e[0m
+ ^
+ Output
+ Diff
+ --- expected:test_nitunit4/test_nitunit4.sav/test_baz.res
+ +++ got:.nitunit/gen_test_nitunit4_test_baz.out1
+ @@ -1 +1,3 @@
+ -Bad result file
+ +Before Test
+ +Tested method
+ +After Test
DocUnits:
No doc units found
TestSuites:
Class suites: 1; Test Cases: 3; Failures: 2
-<testsuites><testsuite package="test_nitunit4>"></testsuite><testsuite package="test_nitunit4::nitunit4"></testsuite><testsuite package="test_nitunit4"><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_foo"><error>Runtime Error</error><system-err>Before Test
+<testsuites><testsuite package="test_nitunit4>"></testsuite><testsuite package="test_nitunit4::nitunit4"></testsuite><testsuite package="test_nitunit4"><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_foo"><error>Runtime Error in file .nitunit/gen_test_nitunit4.nit</error><system-err>Before Test
Tested method
After Test
Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31)
-</system-err></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_bar"></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_baz"><error>Runtime Error</error><system-err>Diff
+</system-err></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_bar"><system-err>Before Test
+Tested method
+After Test
+</system-err></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_baz"><error>Difference with expected output: diff -u test_nitunit4/test_nitunit4.sav/test_baz.res .nitunit/gen_test_nitunit4_test_baz.out1</error><system-err>Diff
--- expected:test_nitunit4/test_nitunit4.sav/test_baz.res
+++ got:.nitunit/gen_test_nitunit4_test_baz.out1
@@ -1 +1,3 @@
--- /dev/null
+Usage: repeating_key_xor_solve <cipher_file>
--- /dev/null
+I'm back and I'm ringin' the bell
+A rockin' on the mike while the fly girls yell
+In ecstasy in the back of me
+Well that's my DJ Deshay cuttin' all them Z's
+Hittin' hard and the girlies goin' crazy
+Vanilla's on the mike, man I'm not lazy.
+
+I'm lettin' my drug kick in
+It controls my mouth and I begin
+To just let it flow, let my concepts go
+My posse's to the side yellin', Go Vanilla Go!
+
+Smooth 'cause that's the way I will be
+And if you don't give a damn, then
+Why you starin' at me
+So get off 'cause I control the stage
+There's no dissin' allowed
+I'm in my own phase
+The girlies sa y they love me and that is ok
+And I can dance better than any kid n' play
+
+Stage 2 -- Yea the one ya' wanna listen to
+It's off my head so let the beat play through
+So I can funk it up and make it sound good
+1-2-3 Yo -- Knock on some wood
+For good luck, I like my rhymes atrocious
+Supercalafragilisticexpialidocious
+I'm an effect and that you can bet
+I can take a fly girl and make her wet.
+
+I'm like Samson -- Samson to Delilah
+There's no denyin', You can try to hang
+But you'll keep tryin' to get my style
+Over and over, practice makes perfect
+But not if you're a loafer.
+
+You'll get nowhere, no place, no time, no girls
+Soon -- Oh my God, homebody, you probably eat
+Spaghetti with a spoon! Come on and say it!
+
+VIP. Vanilla Ice yep, yep, I'm comin' hard like a rhino
+Intoxicating so you stagger like a wino
+So punks stop trying and girl stop cryin'
+Vanilla Ice is sellin' and you people are buyin'
+'Cause why the freaks are jockin' like Crazy Glue
+Movin' and groovin' trying to sing along
+All through the ghetto groovin' this here song
+Now you're amazed by the VIP posse.
+
+Steppin' so hard like a German Nazi
+Startled by the bases hittin' ground
+There's no trippin' on mine, I'm just gettin' down
+Sparkamatic, I'm hangin' tight like a fanatic
+You trapped me once and I thought that
+You might have it
+So step down and lend me your ear
+'89 in my time! You, '90 is my year.
+
+You're weakenin' fast, YO! and I can tell it
+Your body's gettin' hot, so, so I can smell it
+So don't be mad and don't be sad
+'Cause the lyrics belong to ICE, You can call me Dad
+You're pitchin' a fit, so step back and endure
+Let the witch doctor, Ice, do the dance to cure
+So come up close and don't be square
+You wanna battle me -- Anytime, anywhere
+
+You thought that I was weak, Boy, you're dead wrong
+So come on, everybody and sing this song
+
+Say -- Play that funky music Say, go white boy, go white boy go
+play that funky music Go white boy, go white boy, go
+Lay down and boogie and play that funky music till you die.
+
+Play that funky music Come on, Come on, let me hear
+Play that funky music white boy you say it, say it
+Play that funky music A little louder now
+Play that funky music, white boy Come on, Come on, Come on
+Play that funky music
+
--- /dev/null
+S&éstrS&éstr
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import core
+#alt1 intrude import core::text::ropes
+#alt2 intrude import core::text::ropes
+
+var ons = new NativeString(9)
+var base_str = "%Dégâštr"
+
+var str: String = base_str
+#alt1 str = new Concat(base_str, base_str)
+#alt2 str = new Concat(base_str, base_str.substring_from(2))
+
+var copy_len = (str.bytelen - 4).min(9)
+str.copy_to_native(ons, copy_len, 4, 0)
+print ons.to_s_with_length(copy_len)
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#alt1 intrude import core::text::ropes
+import core
+
+var src_s = "S&éstr"
+var cpstr: Text = src_s
+#alt1 cpstr = new Concat(src_s, src_s)
+#alt2 cpstr = new FlatBuffer.from(src_s)
+#alt3 cpstr = cpstr.substring(1, 5)
+
+var ns = new NativeString(cpstr.bytelen)
+ns.fill_from(cpstr)
+
+print ns.to_s_with_length(cpstr.bytelen)
redef class Sys
var iface: String is lazy do
- srand
- return "localhost:{10000+20000.rand}"
+ var testid = "NIT_TESTING_ID".environ.to_i
+ return "localhost:{10000+testid}"
end
var fs_path: String = getcwd / "../lib/nitcorn/examples/www/hello_world/dir" is lazy
# assert undefined_identifier
fun foo do end
+ # a 'failure' unit test (does not parse)
+ # assert !@#$%^&*()
fun foo1(a, b: Int) do end
private fun foo2: Bool do return true
export LANG=C
export LC_ALL=C
export NIT_TESTING=true
+# Use the pid as a collision prevention
+export NIT_TESTING_ID=$$
export NIT_SRAND=0
unset NIT_DIR