summaryrefslogtreecommitdiffhomepage
path: root/mrbgems
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems')
-rw-r--r--mrbgems/mruby-bin-mruby/bintest/mruby.rb56
-rw-r--r--mrbgems/mruby-bin-mruby/tools/mruby/mruby.c41
-rw-r--r--mrbgems/mruby-compiler/core/parse.y206
-rw-r--r--mrbgems/mruby-complex/mrbgem.rake10
-rw-r--r--mrbgems/mruby-complex/mrblib/complex.rb140
-rw-r--r--mrbgems/mruby-complex/src/complex.c140
-rw-r--r--mrbgems/mruby-complex/test/complex.rb128
-rw-r--r--mrbgems/mruby-eval/src/eval.c2
-rw-r--r--mrbgems/mruby-eval/test/eval.rb4
-rw-r--r--mrbgems/mruby-io/src/file.c23
-rw-r--r--mrbgems/mruby-io/src/file_test.c19
-rw-r--r--mrbgems/mruby-io/test/file.rb15
-rw-r--r--mrbgems/mruby-io/test/file_test.rb13
-rw-r--r--mrbgems/mruby-io/test/io.rb61
-rw-r--r--mrbgems/mruby-io/test/mruby_io_test.c6
-rw-r--r--mrbgems/mruby-kernel-ext/mrblib/kernel.rb15
-rw-r--r--mrbgems/mruby-kernel-ext/src/kernel.c17
-rw-r--r--mrbgems/mruby-kernel-ext/test/kernel.rb2
-rw-r--r--mrbgems/mruby-metaprog/test/metaprog.rb24
-rw-r--r--mrbgems/mruby-method/test/method.rb2
-rw-r--r--mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb6
-rw-r--r--mrbgems/mruby-object-ext/mrblib/object.rb16
-rw-r--r--mrbgems/mruby-object-ext/src/object.c19
-rw-r--r--mrbgems/mruby-pack/src/pack.c11
-rw-r--r--mrbgems/mruby-rational/mrbgem.rake5
-rw-r--r--mrbgems/mruby-rational/mrblib/rational.rb104
-rw-r--r--mrbgems/mruby-rational/src/rational.c115
-rw-r--r--mrbgems/mruby-rational/test/rational.rb267
-rw-r--r--mrbgems/mruby-socket/src/socket.c7
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb10
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb12
-rw-r--r--mrbgems/mruby-struct/test/struct.rb16
-rw-r--r--mrbgems/mruby-time/src/time.c46
-rw-r--r--mrbgems/mruby-time/test/time.rb126
34 files changed, 1396 insertions, 288 deletions
diff --git a/mrbgems/mruby-bin-mruby/bintest/mruby.rb b/mrbgems/mruby-bin-mruby/bintest/mruby.rb
index e8d1510f7..09350ff49 100644
--- a/mrbgems/mruby-bin-mruby/bintest/mruby.rb
+++ b/mrbgems/mruby-bin-mruby/bintest/mruby.rb
@@ -1,10 +1,16 @@
require 'tempfile'
+require 'open3'
+
+def assert_mruby(exp_out, exp_err, exp_success, args)
+ out, err, stat = Open3.capture3(cmd("mruby"), *args)
+ assert_operator(exp_out, :===, out, "standard output")
+ assert_operator(exp_err, :===, err, "standard error")
+ assert_equal(exp_success, stat.success?, "exit success?")
+end
assert('regression for #1564') do
- o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1`
- assert_include o, "-e:1:2: syntax error"
- o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1`
- assert_include o, "-e:1:3: syntax error"
+ assert_mruby("", /\A-e:1:2: syntax error, .*\n\z/, false, %w[-e <<])
+ assert_mruby("", /\A-e:1:3: syntax error, .*\n\z/, false, %w[-e <<-])
end
assert('regression for #1572') do
@@ -66,6 +72,11 @@ RUBY
assert_equal 0, $?.exitstatus
end
+assert('mruby -c option') do
+ assert_mruby("Syntax OK\n", "", true, ["-c", "-e", "p 1"])
+ assert_mruby("", /\A-e:1:7: syntax error, .*\n\z/, false, ["-c", "-e", "p 1; 1."])
+end
+
assert('mruby -d option') do
o = `#{cmd('mruby')} -e #{shellquote('p $DEBUG')}`
assert_equal "false\n", o
@@ -73,6 +84,14 @@ assert('mruby -d option') do
assert_equal "true\n", o
end
+assert('mruby -e option (no code specified)') do
+ assert_mruby("", /\A.*: No code specified for -e\n\z/, false, %w[-e])
+end
+
+assert('mruby -h option') do
+ assert_mruby(/\AUsage: #{Regexp.escape cmd("mruby")} .*/m, "", true, %w[-h])
+end
+
assert('mruby -r option') do
lib = Tempfile.new('lib.rb')
lib.write <<EOS
@@ -95,3 +114,32 @@ EOS
assert_equal 'hogeClass', `#{cmd('mruby')} -r #{lib.path} -r #{script.path} -e #{shellquote('print Hoge.class')}`
assert_equal 0, $?.exitstatus
end
+
+assert('mruby -r option (no library specified)') do
+ assert_mruby("", /\A.*: No library specified for -r\n\z/, false, %w[-r])
+end
+
+assert('mruby -r option (file not found)') do
+ assert_mruby("", /\A.*: Cannot open library file: .*\n\z/, false, %w[-r _no_exists_])
+end
+
+assert('mruby invalid short option') do
+ assert_mruby("", /\A.*: invalid option -1 .*\n\z/, false, %w[-1])
+end
+
+assert('mruby invalid long option') do
+ assert_mruby("", /\A.*: invalid option --longopt .*\n\z/, false, %w[--longopt])
+end
+
+assert('unhandled exception') do
+ assert_mruby("", /\bEXCEPTION\b.*\n\z/, false, %w[-e raise("EXCEPTION")])
+end
+
+assert('program file not found') do
+ assert_mruby("", /\A.*: Cannot open program file: .*\n\z/, false, %w[_no_exists_])
+end
+
+assert('codegen error') do
+ code = "def f(#{(1..100).map{|n| "a#{n}"} * ","}); end"
+ assert_mruby("", /\Acodegen error:.*\n\z/, false, ["-e", code])
+end
diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
index 498bedef2..29ab4c17c 100644
--- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
+++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
@@ -7,19 +7,6 @@
#include <mruby/dump.h>
#include <mruby/variable.h>
-#ifdef MRB_DISABLE_STDIO
-static void
-p(mrb_state *mrb, mrb_value obj)
-{
- mrb_value val = mrb_inspect(mrb, obj);
-
- fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
- putc('\n', stdout);
-}
-#else
-#define p(mrb,obj) mrb_p(mrb,obj)
-#endif
-
struct _args {
FILE *rfp;
char* cmdline;
@@ -119,14 +106,17 @@ append_cmdline:
}
}
else {
- printf("%s: No code specified for -e\n", *origargv);
- return EXIT_SUCCESS;
+ fprintf(stderr, "%s: No code specified for -e\n", *origargv);
+ return EXIT_FAILURE;
}
break;
+ case 'h':
+ usage(*origargv);
+ exit(EXIT_SUCCESS);
case 'r':
if (!item[0]) {
if (argc <= 1) {
- printf("%s: No library specified for -r\n", *origargv);
+ fprintf(stderr, "%s: No library specified for -r\n", *origargv);
return EXIT_FAILURE;
}
argc--; argv++;
@@ -158,6 +148,7 @@ append_cmdline:
exit(EXIT_SUCCESS);
}
default:
+ fprintf(stderr, "%s: invalid option %s (-h will show valid options)\n", *origargv, *argv);
return EXIT_FAILURE;
}
}
@@ -167,7 +158,7 @@ append_cmdline:
else {
args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
if (args->rfp == NULL) {
- printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
+ fprintf(stderr, "%s: Cannot open program file: %s\n", *origargv, *argv);
return EXIT_FAILURE;
}
args->fname = TRUE;
@@ -212,14 +203,13 @@ main(int argc, char **argv)
mrb_sym zero_sym;
if (mrb == NULL) {
- fputs("Invalid mrb_state, exiting mruby\n", stderr);
+ fprintf(stderr, "%s: Invalid mrb_state, exiting mruby\n", *argv);
return EXIT_FAILURE;
}
n = parse_args(mrb, argc, argv, &args);
if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
cleanup(mrb, &args);
- usage(argv[0]);
return n;
}
else {
@@ -258,7 +248,7 @@ main(int argc, char **argv)
for (i = 0; i < args.libc; i++) {
FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r");
if (lfp == NULL) {
- printf("Cannot open library file: %s\n", args.libv[i]);
+ fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]);
mrbc_context_free(mrb, c);
cleanup(mrb, &args);
return EXIT_FAILURE;
@@ -289,19 +279,16 @@ main(int argc, char **argv)
mrb_gc_arena_restore(mrb, ai);
mrbc_context_free(mrb, c);
if (mrb->exc) {
- if (mrb_undef_p(v)) {
- mrb_p(mrb, mrb_obj_value(mrb->exc));
- }
- else {
+ if (!mrb_undef_p(v)) {
mrb_print_error(mrb);
}
- n = -1;
+ n = EXIT_FAILURE;
}
else if (args.check_syntax) {
- printf("Syntax OK\n");
+ puts("Syntax OK");
}
}
cleanup(mrb, &args);
- return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ return n;
}
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 7838b6dfb..37d4d1bf1 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -10,13 +10,7 @@
# define YYDEBUG 1
#endif
#define YYERROR_VERBOSE 1
-/*
- * Force yacc to use our memory management. This is a little evil because
- * the macros assume that "parser_state *p" is in scope
- */
-#define YYMALLOC(n) mrb_malloc(p->mrb, (n))
-#define YYFREE(o) mrb_free(p->mrb, (o))
-#define YYSTACK_USE_ALLOCA 0
+#define YYSTACK_USE_ALLOCA 1
#include <ctype.h>
#include <errno.h>
@@ -76,6 +70,24 @@ typedef unsigned int stack_type;
#define nint(x) ((node*)(intptr_t)(x))
#define intn(x) ((int)(intptr_t)(x))
+#if defined(MRB_COMPLEX_NUMBERS) || defined(MRB_RATIONAL_NUMBERS)
+ #define MRB_SUFFIX_SUPPORT
+
+ #ifdef MRB_RATIONAL_NUMBERS
+ #define NUM_SUFFIX_R (1<<0)
+ #else
+ #define NUM_SUFFIX_R 0
+ #endif
+
+ #ifdef MRB_COMPLEX_NUMBERS
+ #define NUM_SUFFIX_I (1<<1)
+ #else
+ #define NUM_SUFFIX_I 0
+ #endif
+
+ #define NUM_SUFFIX_ALL (NUM_SUFFIX_R | NUM_SUFFIX_I)
+#endif
+
static inline mrb_sym
intern_cstr_gen(parser_state *p, const char *s)
{
@@ -842,19 +854,57 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
return list4((node*)NODE_OP_ASGN, a, nsym(op), b);
}
+#ifdef MRB_COMPLEX_NUMBERS
+static node*
+new_imaginary(parser_state *p, node *imaginary)
+{
+ return new_call(p, new_const(p, intern_cstr("Kernel")), intern_cstr("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1);
+}
+#endif
+
+#ifdef MRB_RATIONAL_NUMBERS
+static node*
+new_rational(parser_state *p, node *rational)
+{
+ return new_call(p, new_const(p, intern_cstr("Kernel")), intern_cstr("Rational"), list1(list1(rational)), 1);
+}
+#endif
+
/* (:int . i) */
static node*
-new_int(parser_state *p, const char *s, int base)
+new_int(parser_state *p, const char *s, int base, int suffix)
{
- return list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+ node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+#ifdef MRB_RATIONAL_NUMBERS
+ if (suffix & NUM_SUFFIX_R) {
+ result = new_rational(p, result);
+ }
+#endif
+#ifdef MRB_COMPLEX_NUMBERS
+ if (suffix & NUM_SUFFIX_I) {
+ result = new_imaginary(p, result);
+ }
+#endif
+ return result;
}
#ifndef MRB_WITHOUT_FLOAT
/* (:float . i) */
static node*
-new_float(parser_state *p, const char *s)
+new_float(parser_state *p, const char *s, int suffix)
{
- return cons((node*)NODE_FLOAT, (node*)strdup(s));
+ node* result = cons((node*)NODE_FLOAT, (node*)strdup(s));
+#ifdef MRB_RATIONAL_NUMBERS
+ if (suffix & NUM_SUFFIX_R) {
+ result = new_rational(p, result);
+ }
+#endif
+#ifdef MRB_COMPLEX_NUMBERS
+ if (suffix & NUM_SUFFIX_I) {
+ result = new_imaginary(p, result);
+ }
+#endif
+ return result;
}
#endif
@@ -913,40 +963,39 @@ concat_string(parser_state *p, node *a, node *b)
}
}
}
- else if (string_node_p(b)) {
- /* a == NODE_DSTR && b == NODE_STR */
-
- node *c;
+ else {
+ node *c; /* last node of a */
for (c = a; c->cdr != NULL; c = c->cdr) ;
- if (string_node_p(c->car)) {
- /* a->[..., NODE_STR] && b == NODE_STR */
- composite_string_node(p, c->car->cdr, b->cdr);
- cons_free(b);
- return a;
- }
- push(a, b);
- return a;
- }
- else {
- /* a == NODE_DSTR && b == NODE_DSTR */
+ if (string_node_p(b)) {
+ /* a == NODE_DSTR && b == NODE_STR */
+ if (string_node_p(c->car)) {
+ /* a->[..., NODE_STR] && b == NODE_STR */
+ composite_string_node(p, c->car->cdr, b->cdr);
+ cons_free(b);
+ return a;
+ }
- node *c, *d;
- for (c = a; c->cdr != NULL; c = c->cdr) ;
- if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
- /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
- d = b->cdr;
- cons_free(b);
- composite_string_node(p, c->car->cdr, d->car->cdr);
- cons_free(d->car);
- c->cdr = d->cdr;
- cons_free(d);
+ push(a, b);
return a;
}
else {
- c->cdr = b->cdr;
- cons_free(b);
- return a;
+ /* a == NODE_DSTR && b == NODE_DSTR */
+ if (string_node_p(c->car) && string_node_p(b->cdr->car)) {
+ /* a->[..., NODE_STR] && b->[NODE_STR, ...] */
+ node *d = b->cdr;
+ cons_free(b);
+ composite_string_node(p, c->car->cdr, d->car->cdr);
+ cons_free(d->car);
+ c->cdr = d->cdr;
+ cons_free(d);
+ return a;
+ }
+ else {
+ c->cdr = b->cdr;
+ cons_free(b);
+ return a;
+ }
}
}
@@ -3193,7 +3242,7 @@ var_ref : variable
char buf[16];
dump_int(p->lineno, buf);
- $$ = new_int(p, buf, 10);
+ $$ = new_int(p, buf, 10, 0);
}
| keyword__ENCODING__
{
@@ -4521,6 +4570,45 @@ parse_string(parser_state *p)
return tSTRING;
}
+#ifdef MRB_SUFFIX_SUPPORT
+static int
+number_literal_suffix(parser_state *p, int mask)
+{
+ int c, result = 0;
+ node *list = 0;
+ int column = p->column;
+
+ while ((c = nextc(p)) != -1) {
+ list = push(list, (node*)(intptr_t)c);
+
+ if ((mask & NUM_SUFFIX_I) && c == 'i') {
+ result |= (mask & NUM_SUFFIX_I);
+ mask &= ~NUM_SUFFIX_I;
+ /* r after i, rational of complex is disallowed */
+ mask &= ~NUM_SUFFIX_R;
+ continue;
+ }
+ if ((mask & NUM_SUFFIX_R) && c == 'r') {
+ result |= (mask & NUM_SUFFIX_R);
+ mask &= ~NUM_SUFFIX_R;
+ continue;
+ }
+ if (!ISASCII(c) || ISALPHA(c) || c == '_') {
+ p->column = column;
+ if (p->pb) {
+ p->pb = append((node*)list, p->pb);
+ }
+ else {
+ p->pb = list;
+ }
+ return 0;
+ }
+ pushback(p, c);
+ break;
+ }
+ return result;
+}
+#endif
static int
heredoc_identifier(parser_state *p)
@@ -5095,6 +5183,7 @@ parser_yylex(parser_state *p)
case '5': case '6': case '7': case '8': case '9':
{
int is_float, seen_point, seen_e, nondigit;
+ int suffix = 0;
is_float = seen_point = seen_e = nondigit = 0;
p->lstate = EXPR_ENDARG;
@@ -5128,7 +5217,10 @@ parser_yylex(parser_state *p)
no_digits();
}
else if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 16);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 16, suffix);
return tINTEGER;
}
if (c == 'b' || c == 'B') {
@@ -5152,7 +5244,10 @@ parser_yylex(parser_state *p)
no_digits();
}
else if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 2);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 2, suffix);
return tINTEGER;
}
if (c == 'd' || c == 'D') {
@@ -5176,7 +5271,10 @@ parser_yylex(parser_state *p)
no_digits();
}
else if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 10);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 10, suffix);
return tINTEGER;
}
if (c == '_') {
@@ -5209,7 +5307,10 @@ parser_yylex(parser_state *p)
pushback(p, c);
tokfix(p);
if (nondigit) goto trailing_uc;
- pylval.nd = new_int(p, tok(p), 8);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 8, suffix);
return tINTEGER;
}
if (nondigit) {
@@ -5226,7 +5327,10 @@ parser_yylex(parser_state *p)
}
else {
pushback(p, c);
- pylval.nd = new_int(p, "0", 10);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, "0", 10, suffix);
return tINTEGER;
}
}
@@ -5300,7 +5404,7 @@ parser_yylex(parser_state *p)
if (is_float) {
#ifdef MRB_WITHOUT_FLOAT
yywarning(p, "floating point numbers are not supported");
- pylval.nd = new_int(p, "0", 10);
+ pylval.nd = new_int(p, "0", 10, 0);
return tINTEGER;
#else
double d;
@@ -5315,11 +5419,17 @@ parser_yylex(parser_state *p)
yywarning_s(p, "float out of range", tok(p));
errno = 0;
}
- pylval.nd = new_float(p, tok(p));
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_float(p, tok(p), suffix);
return tFLOAT;
#endif
}
- pylval.nd = new_int(p, tok(p), 10);
+ #ifdef MRB_SUFFIX_SUPPORT
+ suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
+ #endif
+ pylval.nd = new_int(p, tok(p), 10, suffix);
return tINTEGER;
}
diff --git a/mrbgems/mruby-complex/mrbgem.rake b/mrbgems/mruby-complex/mrbgem.rake
new file mode 100644
index 000000000..19612e74d
--- /dev/null
+++ b/mrbgems/mruby-complex/mrbgem.rake
@@ -0,0 +1,10 @@
+MRuby::Gem::Specification.new('mruby-complex') do |spec|
+ spec.license = 'MIT'
+ spec.author = 'mruby developers'
+ spec.summary = 'Complex class'
+
+ spec.add_dependency 'mruby-metaprog', core: 'mruby-metaprog'
+ spec.add_dependency 'mruby-object-ext', core: 'mruby-object-ext'
+ spec.add_dependency 'mruby-numeric-ext', core: 'mruby-numeric-ext'
+ spec.add_dependency 'mruby-math', core: 'mruby-math'
+end
diff --git a/mrbgems/mruby-complex/mrblib/complex.rb b/mrbgems/mruby-complex/mrblib/complex.rb
new file mode 100644
index 000000000..4c0c19c70
--- /dev/null
+++ b/mrbgems/mruby-complex/mrblib/complex.rb
@@ -0,0 +1,140 @@
+class Complex < Numeric
+ def initialize(real, imaginary)
+ real = real.to_f unless real.is_a? Numeric
+ imaginary = imaginary.to_f unless imaginary.is_a? Numeric
+ @real = real
+ @imaginary = imaginary
+ end
+
+ def self.polar(abs, arg = 0)
+ Complex(abs * Math.cos(arg), abs * Math.sin(arg))
+ end
+
+ def self.rectangular(real, imaginary = 0)
+ _new(real, imaginary)
+ end
+
+ def inspect
+ "(#{to_s})"
+ end
+
+ def to_s
+ "#{real}#{'+' unless imaginary.negative?}#{imaginary}i"
+ end
+
+ def +@
+ Complex._new(real, imaginary)
+ end
+
+ def -@
+ Complex._new(-real, -imaginary)
+ end
+
+ def +(rhs)
+ if rhs.is_a? Complex
+ Complex._new(real + rhs.real, imaginary + rhs.imaginary)
+ elsif rhs.is_a? Numeric
+ Complex._new(real + rhs, imaginary)
+ end
+ end
+
+ def -(rhs)
+ if rhs.is_a? Complex
+ Complex._new(real - rhs.real, imaginary - rhs.imaginary)
+ elsif rhs.is_a? Numeric
+ Complex._new(real - rhs, imaginary)
+ end
+ end
+
+ def *(rhs)
+ if rhs.is_a? Complex
+ Complex._new(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + rhs.real * imaginary)
+ elsif rhs.is_a? Numeric
+ Complex._new(real * rhs, imaginary * rhs)
+ end
+ end
+
+ def /(rhs)
+ if rhs.is_a? Complex
+ div = rhs.real * rhs.real + rhs.imaginary * rhs.imaginary
+ Complex._new((real * rhs.real + imaginary * rhs.imaginary) / div, (rhs.real * imaginary - real * rhs.imaginary) / div)
+ elsif rhs.is_a? Numeric
+ Complex._new(real / rhs, imaginary / rhs)
+ end
+ end
+ alias_method :quo, :/
+
+ def ==(rhs)
+ if rhs.is_a? Complex
+ real == rhs.real && imaginary == rhs.imaginary
+ elsif rhs.is_a? Numeric
+ imaginary.zero? && real == rhs
+ end
+ end
+
+ def abs
+ Math.sqrt(abs2)
+ end
+ alias_method :magnitude, :abs
+
+ def abs2
+ real * real + imaginary * imaginary
+ end
+
+ def arg
+ Math.atan2 imaginary, real
+ end
+ alias_method :angle, :arg
+ alias_method :phase, :arg
+
+ def conjugate
+ Complex(real, -imaginary)
+ end
+ alias_method :conj, :conjugate
+
+ def fdiv(numeric)
+ Complex(real.to_f / numeric, imaginary.to_f / numeric)
+ end
+
+ def polar
+ [abs, arg]
+ end
+
+ def real?
+ false
+ end
+
+ def rectangular
+ [real, imaginary]
+ end
+ alias_method :rect, :rectangular
+
+ def to_r
+ raise RangeError.new "can't convert #{to_s} into Rational" unless imaginary.zero?
+ Rational(real, 1)
+ end
+
+ alias_method :imag, :imaginary
+end
+
+module Kernel
+ def Complex(real, imaginary = 0)
+ Complex.rectangular(real, imaginary)
+ end
+end
+
+[Fixnum, Float].each do |cls|
+ [:+, :-, :*, :/, :==].each do |op|
+ cls.instance_exec do
+ original_operator_name = "__original_operator_#{op}_complex"
+ alias_method original_operator_name, op
+ define_method op do |rhs|
+ if rhs.is_a? Complex
+ Complex(self).send(op, rhs)
+ else
+ send(original_operator_name, rhs)
+ end
+ end
+ end
+ end
+end
diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c
new file mode 100644
index 000000000..c6fb7a829
--- /dev/null
+++ b/mrbgems/mruby-complex/src/complex.c
@@ -0,0 +1,140 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/numeric.h>
+
+struct mrb_complex {
+ mrb_float real;
+ mrb_float imaginary;
+};
+
+#if defined(MRB_64BIT) || defined(MRB_USE_FLOAT)
+
+#define COMPLEX_USE_ISTRUCT
+/* use TT_ISTRUCT */
+#include <mruby/istruct.h>
+
+#define complex_ptr(mrb, v) (struct mrb_complex*)mrb_istruct_ptr(v)
+
+static mrb_value
+complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary)
+{
+ struct RClass *c = mrb_class_get(mrb, "Complex");
+ struct RIStruct *s = (struct RIStruct*)mrb_obj_alloc(mrb, MRB_TT_ISTRUCT, c);
+ mrb_value comp = mrb_obj_value(s);
+ struct mrb_complex *p = complex_ptr(mrb, comp);
+ p->real = real;
+ p->imaginary = imaginary;
+
+ return comp;
+}
+
+#else
+/* use TT_DATA */
+#include <mruby/data.h>
+
+static const struct mrb_data_type mrb_complex_type = {"Complex", mrb_free};
+
+static mrb_value
+complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary)
+{
+ struct RClass *c = mrb_class_get(mrb, "Complex");
+ struct mrb_complex *p;
+
+ p = (struct mrb_complex*)mrb_malloc(mrb, sizeof(struct mrb_complex));
+ p->real = real;
+ p->imaginary = imaginary;
+
+ return mrb_obj_value(Data_Wrap_Struct(mrb, c, &mrb_complex_type, p));
+}
+
+static struct mrb_complex*
+complex_ptr(mrb_state *mrb, mrb_value v)
+{
+ struct mrb_complex *p;
+
+ p = DATA_GET_PTR(mrb, v, &mrb_complex_type, struct mrb_complex);
+ if (!p) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized complex");
+ }
+ return p;
+}
+#endif
+
+static mrb_value
+complex_real(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_complex *p = complex_ptr(mrb, self);
+ return mrb_float_value(mrb, p->real);
+}
+
+static mrb_value
+complex_imaginary(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_complex *p = complex_ptr(mrb, self);
+ return mrb_float_value(mrb, p->imaginary);
+}
+
+static mrb_value
+complex_s_new(mrb_state *mrb, mrb_value self)
+{
+ mrb_float real, imaginary;
+
+ mrb_get_args(mrb, "ff", &real, &imaginary);
+ return complex_new(mrb, real, imaginary);
+}
+
+#ifndef MRB_WITHOUT_FLOAT
+static mrb_value
+complex_to_f(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_complex *p = complex_ptr(mrb, self);
+
+ if (p->imaginary != 0) {
+ mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self);
+ }
+
+ return mrb_float_value(mrb, p->real);
+}
+#endif
+
+static mrb_value
+complex_to_i(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_complex *p = complex_ptr(mrb, self);
+
+ if (p->imaginary != 0) {
+ mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self);
+ }
+ return mrb_int_value(mrb, p->real);
+}
+
+static mrb_value
+complex_to_c(mrb_state *mrb, mrb_value self)
+{
+ return self;
+}
+
+void mrb_mruby_complex_gem_init(mrb_state *mrb)
+{
+ struct RClass *comp;
+
+#ifdef COMPLEX_USE_ISTRUCT
+ mrb_assert(sizeof(struct mrb_complex) < ISTRUCT_DATA_SIZE);
+#endif
+ comp = mrb_define_class(mrb, "Complex", mrb_class_get(mrb, "Numeric"));
+ //MRB_SET_INSTANCE_TT(comp, MRB_TT_ISTRUCT);
+ mrb_undef_class_method(mrb, comp, "new");
+ mrb_define_class_method(mrb, comp, "_new", complex_s_new, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, comp, "real", complex_real, MRB_ARGS_NONE());
+ mrb_define_method(mrb, comp, "imaginary", complex_imaginary, MRB_ARGS_NONE());
+#ifndef MRB_WITHOUT_FLOAT
+ mrb_define_method(mrb, comp, "to_f", complex_to_f, MRB_ARGS_NONE());
+#endif
+ mrb_define_method(mrb, comp, "to_i", complex_to_i, MRB_ARGS_NONE());
+ mrb_define_method(mrb, comp, "to_c", complex_to_c, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_complex_gem_final(mrb_state* mrb)
+{
+}
diff --git a/mrbgems/mruby-complex/test/complex.rb b/mrbgems/mruby-complex/test/complex.rb
new file mode 100644
index 000000000..e7fcc7322
--- /dev/null
+++ b/mrbgems/mruby-complex/test/complex.rb
@@ -0,0 +1,128 @@
+def assert_complex(real, exp)
+ assert_float real.real, exp.real
+ assert_float real.imaginary, exp.imaginary
+end
+
+assert 'Complex' do
+ c = 123i
+ assert_equal Complex, c.class
+ assert_equal [c.real, c.imaginary], [0, 123]
+ c = 123 + -1.23i
+ assert_equal Complex, c.class
+ assert_equal [c.real, c.imaginary], [123, -1.23]
+end
+
+assert 'Complex::polar' do
+ assert_complex Complex.polar(3, 0), (3 + 0i)
+ assert_complex Complex.polar(3, Math::PI/2), (0 + 3i)
+ assert_complex Complex.polar(3, Math::PI), (-3 + 0i)
+ assert_complex Complex.polar(3, -Math::PI/2), (0 + -3i)
+end
+
+assert 'Complex::rectangular' do
+ assert_complex Complex.rectangular(1, 2), (1 + 2i)
+end
+
+assert 'Complex#*' do
+ assert_complex Complex(2, 3) * Complex(2, 3), (-5 + 12i)
+ assert_complex Complex(900) * Complex(1), (900 + 0i)
+ assert_complex Complex(-2, 9) * Complex(-9, 2), (0 - 85i)
+ assert_complex Complex(9, 8) * 4, (36 + 32i)
+ assert_complex Complex(20, 9) * 9.8, (196.0 + 88.2i)
+end
+
+assert 'Complex#+' do
+ assert_complex Complex(2, 3) + Complex(2, 3) , (4 + 6i)
+ assert_complex Complex(900) + Complex(1) , (901 + 0i)
+ assert_complex Complex(-2, 9) + Complex(-9, 2), (-11 + 11i)
+ assert_complex Complex(9, 8) + 4 , (13 + 8i)
+ assert_complex Complex(20, 9) + 9.8 , (29.8 + 9i)
+end
+
+assert 'Complex#-' do
+ assert_complex Complex(2, 3) - Complex(2, 3) , (0 + 0i)
+ assert_complex Complex(900) - Complex(1) , (899 + 0i)
+ assert_complex Complex(-2, 9) - Complex(-9, 2), (7 + 7i)
+ assert_complex Complex(9, 8) - 4 , (5 + 8i)
+ assert_complex Complex(20, 9) - 9.8 , (10.2 + 9i)
+end
+
+assert 'Complex#-@' do
+ assert_complex -Complex(1, 2), (-1 - 2i)
+end
+
+assert 'Complex#/' do
+ assert_complex Complex(2, 3) / Complex(2, 3) , (1 + 0i)
+ assert_complex Complex(900) / Complex(1) , (900 + 0i)
+ assert_complex Complex(-2, 9) / Complex(-9, 2), ((36 / 85) - (77i / 85))
+ assert_complex Complex(9, 8) / 4 , ((9 / 4) + 2i)
+ assert_complex Complex(20, 9) / 9.8 , (2.0408163265306123 + 0.9183673469387754i)
+end
+
+assert 'Complex#==' do
+ assert_true Complex(2, 3) == Complex(2, 3)
+ assert_true Complex(5) == 5
+ assert_true Complex(0) == 0.0
+end
+
+assert 'Complex#abs' do
+ assert_float Complex(-1).abs, 1
+ assert_float Complex(3.0, -4.0).abs, 5.0
+end
+
+assert 'Complex#abs2' do
+ assert_float Complex(-1).abs2, 1
+ assert_float Complex(3.0, -4.0).abs2, 25.0
+end
+
+assert 'Complex#arg' do
+ assert_float Complex.polar(3, Math::PI/2).arg, 1.5707963267948966
+end
+
+assert 'Complex#conjugate' do
+ assert_complex Complex(1, 2).conjugate, (1 - 2i)
+end
+
+assert 'Complex#fdiv' do
+ assert_complex Complex(11, 22).fdiv(3), (3.6666666666666665 + 7.333333333333333i)
+end
+
+assert 'Complex#imaginary' do
+ assert_float Complex(7).imaginary , 0
+ assert_float Complex(9, -4).imaginary, -4
+end
+
+assert 'Complex#polar' do
+ assert_equal Complex(1, 2).polar, [2.23606797749979, 1.1071487177940904]
+end
+
+assert 'Complex#real' do
+ assert_float Complex(7).real, 7
+ assert_float Complex(9, -4).real, 9
+end
+
+assert 'Complex#real?' do
+ assert_false Complex(1).real?
+end
+
+assert 'Complex::rectangular' do
+ assert_equal Complex(1, 2).rectangular, [1, 2]
+end
+
+assert 'Complex::to_c' do
+ assert_equal Complex(1, 2).to_c, Complex(1, 2)
+end
+
+assert 'Complex::to_f' do
+ assert_float Complex(1, 0).to_f, 1.0
+ assert_raise(RangeError) do
+ Complex(1, 2).to_f
+ end
+end
+
+assert 'Complex::to_i' do
+ assert_equal Complex(1, 0).to_i, 1
+ assert_raise(RangeError) do
+ Complex(1, 2).to_i
+ end
+end
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index fa687d624..a3b211ba2 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -387,7 +387,7 @@ void
mrb_mruby_eval_gem_init(mrb_state* mrb)
{
mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
- mrb_define_method(mrb, mrb->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
+ mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
}
void
diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb
index 4d7dd4606..4930259c1 100644
--- a/mrbgems/mruby-eval/test/eval.rb
+++ b/mrbgems/mruby-eval/test/eval.rb
@@ -80,7 +80,7 @@ assert('Kernel.#eval(string) context') do
assert_equal('class') { obj.const_string }
end
-assert('Object#instance_eval with begin-rescue-ensure execution order') do
+assert('BasicObject#instance_eval with begin-rescue-ensure execution order') do
class HellRaiser
def raise_hell
order = [:enter_raise_hell]
@@ -100,7 +100,7 @@ assert('Object#instance_eval with begin-rescue-ensure execution order') do
assert_equal([:enter_raise_hell, :begin, :rescue, :ensure], hell_raiser.raise_hell)
end
-assert('Kernel#instance_eval() to define singleton methods Issue #3141') do
+assert('BasicObject#instance_eval to define singleton methods Issue #3141') do
foo_class = Class.new do
def bar(x)
instance_eval "def baz; #{x}; end"
diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c
index c00663481..243f634b4 100644
--- a/mrbgems/mruby-io/src/file.c
+++ b/mrbgems/mruby-io/src/file.c
@@ -146,7 +146,7 @@ mrb_file_s_rename(mrb_state *mrb, mrb_value obj)
#endif
mrb_locale_free(src);
mrb_locale_free(dst);
- mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to)));
+ mrb_sys_fail(mrb, RSTRING_PTR(mrb_format(mrb, "(%S, %S)", from, to)));
}
mrb_locale_free(src);
mrb_locale_free(dst);
@@ -159,12 +159,12 @@ mrb_file_dirname(mrb_state *mrb, mrb_value klass)
#if defined(_WIN32) || defined(_WIN64)
char dname[_MAX_DIR], vname[_MAX_DRIVE];
char buffer[_MAX_DRIVE + _MAX_DIR];
+ const char *utf8_path;
char *path;
size_t ridx;
- mrb_value s;
- mrb_get_args(mrb, "S", &s);
- path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, s), -1);
- _splitpath((const char*)path, vname, dname, NULL, NULL);
+ mrb_get_args(mrb, "z", &utf8_path);
+ path = mrb_locale_from_utf8(utf8_path, -1);
+ _splitpath(path, vname, dname, NULL, NULL);
snprintf(buffer, _MAX_DRIVE + _MAX_DIR, "%s%s", vname, dname);
mrb_locale_free(path);
ridx = strlen(buffer);
@@ -248,7 +248,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
s = mrb_str_append(mrb, s, pathname);
pathname = s;
}
- cpath = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, pathname), -1);
+ cpath = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &pathname), -1);
result = mrb_str_buf_new(mrb, PATH_MAX);
if (realpath(cpath, RSTRING_PTR(result)) == NULL) {
mrb_locale_free(cpath);
@@ -300,7 +300,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
mrb_raise(mrb, E_ARGUMENT_ERROR, "non-absolute home");
}
} else {
- const char *cuser = mrb_str_to_cstr(mrb, username);
+ const char *cuser = mrb_string_value_cstr(mrb, &username);
struct passwd *pwd = getpwnam(cuser);
if (pwd == NULL) {
return mrb_nil_value();
@@ -393,9 +393,8 @@ mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
int ai = mrb_gc_arena_save(mrb);
mrb_get_args(mrb, "SS", &from, &to);
- src = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, from), -1);
- dst = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, to), -1);
-
+ src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1);
+ dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1);
if (symlink(src, dst) == -1) {
mrb_locale_free(src);
mrb_locale_free(dst);
@@ -417,16 +416,16 @@ mrb_file_s_chmod(mrb_state *mrb, mrb_value klass) {
mrb_get_args(mrb, "i*", &mode, &filenames, &argc);
for (i = 0; i < argc; i++) {
- const char *utf8_path = mrb_str_to_cstr(mrb, filenames[i]);
+ const char *utf8_path = mrb_string_value_cstr(mrb, &filenames[i]);
char *path = mrb_locale_from_utf8(utf8_path, -1);
if (CHMOD(path, mode) == -1) {
mrb_locale_free(path);
mrb_sys_fail(mrb, utf8_path);
}
mrb_locale_free(path);
+ mrb_gc_arena_restore(mrb, ai);
}
- mrb_gc_arena_restore(mrb, ai);
return mrb_fixnum_value(argc);
}
diff --git a/mrbgems/mruby-io/src/file_test.c b/mrbgems/mruby-io/src/file_test.c
index e429b06b3..5d5ecb93f 100644
--- a/mrbgems/mruby-io/src/file_test.c
+++ b/mrbgems/mruby-io/src/file_test.c
@@ -1,5 +1,5 @@
/*
-** file.c - File class
+** file_test.c - FileTest class
*/
#include "mruby.h"
@@ -42,14 +42,7 @@ extern struct mrb_data_type mrb_io_type;
static int
mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
{
- mrb_value tmp;
- mrb_value io_klass, str_klass;
-
- io_klass = mrb_obj_value(mrb_class_get(mrb, "IO"));
- str_klass = mrb_obj_value(mrb_class_get(mrb, "String"));
-
- tmp = mrb_funcall(mrb, obj, "is_a?", 1, io_klass);
- if (mrb_test(tmp)) {
+ if (mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "IO"))) {
struct mrb_io *fptr;
fptr = (struct mrb_io *)mrb_get_datatype(mrb, obj, &mrb_io_type);
@@ -60,10 +53,8 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
mrb_raise(mrb, E_IO_ERROR, "closed stream");
return -1;
}
-
- tmp = mrb_funcall(mrb, obj, "is_a?", 1, str_klass);
- if (mrb_test(tmp)) {
- char *path = mrb_locale_from_utf8(mrb_str_to_cstr(mrb, obj), -1);
+ else {
+ char *path = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &obj), -1);
int ret;
if (do_lstat) {
ret = LSTAT(path, st);
@@ -73,8 +64,6 @@ mrb_stat0(mrb_state *mrb, mrb_value obj, struct stat *st, int do_lstat)
mrb_locale_free(path);
return ret;
}
-
- return -1;
}
static int
diff --git a/mrbgems/mruby-io/test/file.rb b/mrbgems/mruby-io/test/file.rb
index ba4100492..1535ebb44 100644
--- a/mrbgems/mruby-io/test/file.rb
+++ b/mrbgems/mruby-io/test/file.rb
@@ -1,15 +1,13 @@
##
# File Test
-assert('File TEST SETUP') do
- MRubyIOTestUtil.io_test_setup
-end
+MRubyIOTestUtil.io_test_setup
-assert('File', '15.2.21') do
+assert('File.class', '15.2.21') do
assert_equal Class, File.class
end
-assert('File', '15.2.21.2') do
+assert('File.superclass', '15.2.21.2') do
assert_equal IO, File.superclass
end
@@ -35,6 +33,7 @@ assert('File.basename') do
assert_equal 'a', File.basename('/a/')
assert_equal 'b', File.basename('/a/b')
assert_equal 'b', File.basename('../a/b')
+ assert_raise(ArgumentError) { File.basename("/a/b\0") }
end
assert('File.dirname') do
@@ -108,6 +107,8 @@ assert('File.realpath') do
MRubyIOTestUtil.rmdir dir
end
end
+
+ assert_raise(ArgumentError) { File.realpath("TO\0DO") }
end
assert("File.readlink") do
@@ -204,6 +205,4 @@ assert('File.chmod') do
end
end
-assert('File TEST CLEANUP') do
- assert_nil MRubyIOTestUtil.io_test_cleanup
-end
+MRubyIOTestUtil.io_test_cleanup
diff --git a/mrbgems/mruby-io/test/file_test.rb b/mrbgems/mruby-io/test/file_test.rb
index 04e10e0c8..2134c6a75 100644
--- a/mrbgems/mruby-io/test/file_test.rb
+++ b/mrbgems/mruby-io/test/file_test.rb
@@ -1,9 +1,7 @@
##
# FileTest
-assert('FileTest TEST SETUP') do
- MRubyIOTestUtil.io_test_setup
-end
+MRubyIOTestUtil.io_test_setup
assert("FileTest.directory?") do
dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
@@ -22,9 +20,8 @@ assert("FileTest.exist?") do
assert_equal true, FileTest.exist?(io), "io obj - exist"
io.close
assert_equal true, io.closed?
- assert_raise IOError do
- FileTest.exist?(io)
- end
+ assert_raise(IOError) { FileTest.exist?(io) }
+ assert_raise(TypeError) { File.exist?($mrbtest_io_rfname.to_sym) }
end
assert("FileTest.file?") do
@@ -112,6 +109,4 @@ assert("FileTest.zero?") do
assert_true fp2.closed?
end
-assert('FileTest TEST CLEANUP') do
- assert_nil MRubyIOTestUtil.io_test_cleanup
-end
+MRubyIOTestUtil.io_test_cleanup
diff --git a/mrbgems/mruby-io/test/io.rb b/mrbgems/mruby-io/test/io.rb
index 44eaca6be..5004d0042 100644
--- a/mrbgems/mruby-io/test/io.rb
+++ b/mrbgems/mruby-io/test/io.rb
@@ -1,35 +1,44 @@
##
# IO Test
-assert('IO TEST SETUP') do
- MRubyIOTestUtil.io_test_setup
- $cr, $crlf, $cmd = MRubyIOTestUtil.win? ? [1, "\r\n", "cmd /c "] : [0, "\n", ""]
+MRubyIOTestUtil.io_test_setup
+$cr, $crlf, $cmd = MRubyIOTestUtil.win? ? [1, "\r\n", "cmd /c "] : [0, "\n", ""]
+
+assert_io_open = ->(meth) do
+ fd = IO.sysopen($mrbtest_io_rfname)
+ assert_equal Fixnum, fd.class
+ io1 = IO.__send__(meth, fd)
+ begin
+ assert_equal IO, io1.class
+ assert_equal $mrbtest_io_msg, io1.read
+ ensure
+ io1.close
+ end
+
+ io2 = IO.__send__(meth, IO.sysopen($mrbtest_io_rfname))do |io|
+ if meth == :open
+ assert_equal $mrbtest_io_msg, io.read
+ else
+ flunk "IO.#{meth} does not take block"
+ end
+ end
+ io2.close unless meth == :open
end
-assert('IO', '15.2.20') do
+assert('IO.class', '15.2.20') do
assert_equal(Class, IO.class)
end
-assert('IO', '15.2.20.2') do
+assert('IO.superclass', '15.2.20.2') do
assert_equal(Object, IO.superclass)
end
-assert('IO', '15.2.20.3') do
+assert('IO.ancestors', '15.2.20.3') do
assert_include(IO.ancestors, Enumerable)
end
assert('IO.open', '15.2.20.4.1') do
- fd = IO.sysopen $mrbtest_io_rfname
- assert_equal Fixnum, fd.class
- io = IO.open fd
- assert_equal IO, io.class
- assert_equal $mrbtest_io_msg, io.read
- io.close
-
- fd = IO.sysopen $mrbtest_io_rfname
- IO.open(fd) do |io|
- assert_equal $mrbtest_io_msg, io.read
- end
+ assert_io_open.(:open)
end
assert('IO#close', '15.2.20.5.1') do
@@ -84,7 +93,7 @@ end
assert('IO#getc', '15.2.20.5.8') do
io = IO.new(IO.sysopen($mrbtest_io_rfname))
- $mrbtest_io_msg.each_char { |ch|
+ $mrbtest_io_msg.split("").each { |ch|
assert_equal ch, io.getc
}
assert_equal nil, io.getc
@@ -127,7 +136,7 @@ end
assert('IO#readchar', '15.2.20.5.15') do
# almost same as IO#getc
IO.open(IO.sysopen($mrbtest_io_rfname)) do |io|
- $mrbtest_io_msg.each_char { |ch|
+ $mrbtest_io_msg.split("").each { |ch|
assert_equal ch, io.readchar
}
assert_raise(EOFError) do
@@ -215,19 +224,15 @@ assert('IO#dup for writable') do
end
assert('IO.for_fd') do
- fd = IO.sysopen($mrbtest_io_rfname)
- io = IO.for_fd(fd)
- assert_equal $mrbtest_io_msg, io.read
- io.close
+ assert_io_open.(:for_fd)
end
assert('IO.new') do
- io = IO.new(0)
- io.close
+ assert_io_open.(:new)
end
assert('IO gc check') do
- 100.times { IO.new(0) }
+ assert_nothing_raised { 100.times { IO.new(0) } }
end
assert('IO.sysopen("./nonexistent")') do
@@ -604,6 +609,4 @@ assert('`cmd`') do
end
end
-assert('IO TEST CLEANUP') do
- assert_nil MRubyIOTestUtil.io_test_cleanup
-end
+MRubyIOTestUtil.io_test_cleanup
diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c
index 71239a827..3312d6c7e 100644
--- a/mrbgems/mruby-io/test/mruby_io_test.c
+++ b/mrbgems/mruby-io/test/mruby_io_test.c
@@ -215,11 +215,9 @@ mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass)
static mrb_value
mrb_io_test_rmdir(mrb_state *mrb, mrb_value klass)
{
- mrb_value str;
- char *cp;
+ const char *cp;
- mrb_get_args(mrb, "S", &str);
- cp = mrb_str_to_cstr(mrb, str);
+ mrb_get_args(mrb, "z", &cp);
if (rmdir(cp) == -1) {
mrb_sys_fail(mrb, "rmdir");
}
diff --git a/mrbgems/mruby-kernel-ext/mrblib/kernel.rb b/mrbgems/mruby-kernel-ext/mrblib/kernel.rb
deleted file mode 100644
index bf739ed1a..000000000
--- a/mrbgems/mruby-kernel-ext/mrblib/kernel.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Kernel
- # call-seq:
- # obj.yield_self {|_obj|...} -> an_object
- # obj.then {|_obj|...} -> an_object
- #
- # Yields <i>obj</i> and returns the result.
- #
- # 'my string'.yield_self {|s|s.upcase} #=> "MY STRING"
- #
- def yield_self(&block)
- return to_enum :yield_self unless block
- block.call(self)
- end
- alias then yield_self
-end
diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c
index 99affbfa4..9288b0e6f 100644
--- a/mrbgems/mruby-kernel-ext/src/kernel.c
+++ b/mrbgems/mruby-kernel-ext/src/kernel.c
@@ -206,22 +206,6 @@ mrb_f_hash(mrb_state *mrb, mrb_value self)
return mrb_ensure_hash_type(mrb, arg);
}
-/*
- * call-seq:
- * obj.itself -> an_object
- *
- * Returns <i>obj</i>.
- *
- * string = 'my string' #=> "my string"
- * string.itself.object_id == string.object_id #=> true
- *
- */
-static mrb_value
-mrb_f_itself(mrb_state *mrb, mrb_value self)
-{
- return self;
-}
-
void
mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
{
@@ -237,7 +221,6 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "Hash", mrb_f_hash, MRB_ARGS_REQ(1));
- mrb_define_module_function(mrb, krn, "itself", mrb_f_itself, MRB_ARGS_NONE());
}
void
diff --git a/mrbgems/mruby-kernel-ext/test/kernel.rb b/mrbgems/mruby-kernel-ext/test/kernel.rb
index 28f089007..ad9177165 100644
--- a/mrbgems/mruby-kernel-ext/test/kernel.rb
+++ b/mrbgems/mruby-kernel-ext/test/kernel.rb
@@ -65,6 +65,8 @@ assert('Kernel#Float') do
assert_equal(123.456, Float(123.456))
assert_equal(123.456, Float("123.456"))
assert_raise(TypeError) { Float(nil) }
+ assert_raise(ArgumentError) { Float("1.5a") }
+ assert_raise(ArgumentError) { Float("1.5\0") }
end
assert('Kernel#String') do
diff --git a/mrbgems/mruby-metaprog/test/metaprog.rb b/mrbgems/mruby-metaprog/test/metaprog.rb
index 1262c9945..3aa1d8732 100644
--- a/mrbgems/mruby-metaprog/test/metaprog.rb
+++ b/mrbgems/mruby-metaprog/test/metaprog.rb
@@ -122,6 +122,22 @@ assert('Kernel#define_singleton_method') do
assert_equal :singleton_method_ok, o.test_method
end
+assert('Kernel#singleton_class') do
+ o1 = Object.new
+ assert_same(o1.singleton_class, class << o1; self end)
+
+ o2 = Object.new
+ sc2 = class << o2; self end
+ assert_same(o2.singleton_class, sc2)
+
+ o3 = Object.new
+ sc3 = o3.singleton_class
+ o3.freeze
+ assert_predicate(sc3, :frozen?)
+
+ assert_predicate(Object.new.freeze.singleton_class, :frozen?)
+end
+
def labeled_module(name, &block)
Module.new do
(class <<self; self end).class_eval do
@@ -171,7 +187,6 @@ assert('Module#class_variable_set', '15.2.2.4.18') do
@@foo
end
end
-
assert_equal 99, Test4ClassVariableSet.class_variable_set(:@@cv, 99)
assert_equal 101, Test4ClassVariableSet.class_variable_set(:@@foo, 101)
assert_true Test4ClassVariableSet.class_variables.include? :@@cv
@@ -180,6 +195,13 @@ assert('Module#class_variable_set', '15.2.2.4.18') do
%w[@@ @@1 @@x= @x @ x 1].each do |n|
assert_raise(NameError) { Test4ClassVariableSet.class_variable_set(n, 1) }
end
+
+ m = Module.new.freeze
+ assert_raise(FrozenError) { m.class_variable_set(:@@cv, 1) }
+
+ parent = Class.new{ class_variable_set(:@@a, nil) }.freeze
+ child = Class.new(parent)
+ assert_raise(FrozenError) { child.class_variable_set(:@@a, 1) }
end
assert('Module#class_variables', '15.2.2.4.19') do
diff --git a/mrbgems/mruby-method/test/method.rb b/mrbgems/mruby-method/test/method.rb
index dfddde9cc..0b67d3e61 100644
--- a/mrbgems/mruby-method/test/method.rb
+++ b/mrbgems/mruby-method/test/method.rb
@@ -21,7 +21,7 @@ class Interpreter
}
def interpret(string)
@ret = ""
- string.each_char {|b| Dispatcher[b].bind(self).call }
+ string.split("").each {|b| Dispatcher[b].bind(self).call }
end
end
diff --git a/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb b/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb
index f250538fe..576605cb1 100644
--- a/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb
+++ b/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb
@@ -1,8 +1,4 @@
-module Integral
- def div(other)
- self.divmod(other)[0]
- end
-
+class Numeric
def zero?
self == 0
end
diff --git a/mrbgems/mruby-object-ext/mrblib/object.rb b/mrbgems/mruby-object-ext/mrblib/object.rb
index 581156cb0..f014df469 100644
--- a/mrbgems/mruby-object-ext/mrblib/object.rb
+++ b/mrbgems/mruby-object-ext/mrblib/object.rb
@@ -1,4 +1,18 @@
-class Object
+module Kernel
+ # call-seq:
+ # obj.yield_self {|_obj|...} -> an_object
+ # obj.then {|_obj|...} -> an_object
+ #
+ # Yields <i>obj</i> and returns the result.
+ #
+ # 'my string'.yield_self {|s|s.upcase} #=> "MY STRING"
+ #
+ def yield_self(&block)
+ return to_enum :yield_self unless block
+ block.call(self)
+ end
+ alias then yield_self
+
##
# call-seq:
# obj.tap{|x|...} -> obj
diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c
index b076b3ec0..d3e7a9c50 100644
--- a/mrbgems/mruby-object-ext/src/object.c
+++ b/mrbgems/mruby-object-ext/src/object.c
@@ -46,6 +46,22 @@ nil_to_i(mrb_state *mrb, mrb_value obj)
/*
* call-seq:
+ * obj.itself -> an_object
+ *
+ * Returns <i>obj</i>.
+ *
+ * string = 'my string' #=> "my string"
+ * string.itself.object_id == string.object_id #=> true
+ *
+ */
+static mrb_value
+mrb_f_itself(mrb_state *mrb, mrb_value self)
+{
+ return self;
+}
+
+/*
+ * call-seq:
* obj.instance_exec(arg...) {|var...| block } -> obj
*
* Executes the given block within the context of the receiver
@@ -102,8 +118,9 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, n, "to_f", nil_to_f, MRB_ARGS_NONE());
#endif
mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE());
+ mrb_define_module_function(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE());
- mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
+ mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
}
void
diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c
index ac29fdbf3..75a447d6c 100644
--- a/mrbgems/mruby-pack/src/pack.c
+++ b/mrbgems/mruby-pack/src/pack.c
@@ -118,9 +118,9 @@ make_base64_dec_tab(void)
base64_dec_tab['a' + i] = i + 26;
for (i = 0; i < 10; i++)
base64_dec_tab['0' + i] = i + 52;
- base64_dec_tab['+'] = 62;
- base64_dec_tab['/'] = 63;
- base64_dec_tab['='] = PACK_BASE64_PADDING;
+ base64_dec_tab['+'+0] = 62;
+ base64_dec_tab['/'+0] = 63;
+ base64_dec_tab['='+0] = PACK_BASE64_PADDING;
}
static mrb_value
@@ -1075,10 +1075,11 @@ alias:
if (ISDIGIT(ch)) {
count = ch - '0';
while (tmpl->idx < tlen && ISDIGIT(tptr[tmpl->idx])) {
- count = count * 10 + (tptr[tmpl->idx++] - '0');
- if (count < 0) {
+ int ch = tptr[tmpl->idx++] - '0';
+ if (count+ch > INT_MAX/10) {
mrb_raise(mrb, E_RUNTIME_ERROR, "too big template length");
}
+ count = count * 10 + ch;
}
continue; /* special case */
} else if (ch == '*') {
diff --git a/mrbgems/mruby-rational/mrbgem.rake b/mrbgems/mruby-rational/mrbgem.rake
new file mode 100644
index 000000000..4b540dec4
--- /dev/null
+++ b/mrbgems/mruby-rational/mrbgem.rake
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-rational') do |spec|
+ spec.license = 'MIT'
+ spec.author = 'mruby developers'
+ spec.summary = 'Rational class'
+end
diff --git a/mrbgems/mruby-rational/mrblib/rational.rb b/mrbgems/mruby-rational/mrblib/rational.rb
new file mode 100644
index 000000000..c8614ecea
--- /dev/null
+++ b/mrbgems/mruby-rational/mrblib/rational.rb
@@ -0,0 +1,104 @@
+class Rational < Numeric
+ def inspect
+ "(#{to_s})"
+ end
+
+ def to_s
+ "#{numerator}/#{denominator}"
+ end
+
+ def *(rhs)
+ if rhs.is_a? Rational
+ Rational(numerator * rhs.numerator, denominator * rhs.denominator)
+ elsif rhs.is_a? Integer
+ Rational(numerator * rhs, denominator)
+ elsif rhs.is_a? Numeric
+ numerator * rhs / denominator
+ end
+ end
+
+ def +(rhs)
+ if rhs.is_a? Rational
+ Rational(numerator * rhs.denominator + rhs.numerator * denominator, denominator * rhs.denominator)
+ elsif rhs.is_a? Integer
+ Rational(numerator + rhs * denominator, denominator)
+ elsif rhs.is_a? Numeric
+ (numerator + rhs * denominator) / denominator
+ end
+ end
+
+ def -(rhs)
+ if rhs.is_a? Rational
+ Rational(numerator * rhs.denominator - rhs.numerator * denominator, denominator * rhs.denominator)
+ elsif rhs.is_a? Integer
+ Rational(numerator - rhs * denominator, denominator)
+ elsif rhs.is_a? Numeric
+ (numerator - rhs * denominator) / denominator
+ end
+ end
+
+ def /(rhs)
+ if rhs.is_a? Rational
+ Rational(numerator * rhs.denominator, denominator * rhs.numerator)
+ elsif rhs.is_a? Integer
+ Rational(numerator, denominator * rhs)
+ elsif rhs.is_a? Numeric
+ numerator / rhs / denominator
+ end
+ end
+
+ def <=>(rhs)
+ if rhs.is_a?(Integral)
+ return numerator <=> rhs if denominator == 1
+ rhs = Rational(rhs)
+ end
+
+ case rhs
+ when Rational
+ (numerator * rhs.denominator - denominator * rhs.numerator) <=> 0
+ when Numeric
+ (rhs <=> self)&.-@
+ else
+ nil
+ end
+ end
+end
+
+class Numeric
+ def to_r
+ Rational(self, 1)
+ end
+end
+
+module Kernel
+ def Rational(numerator = 0, denominator = 1)
+ a = numerator
+ b = denominator
+ a, b = b, a % b until b == 0
+ Rational._new(numerator.div(a), denominator.div(a))
+ end
+end
+
+[:+, :-, :*, :/, :<=>, :==, :<, :<=, :>, :>=].each do |op|
+ Fixnum.instance_eval do
+ original_operator_name = "__original_operator_#{op}_rational"
+ alias_method original_operator_name, op
+ define_method op do |rhs|
+ if rhs.is_a? Rational
+ Rational(self).__send__(op, rhs)
+ else
+ __send__(original_operator_name, rhs)
+ end
+ end
+ end
+ Float.instance_eval do
+ original_operator_name = "__original_operator_#{op}_rational"
+ alias_method original_operator_name, op
+ define_method op do |rhs|
+ if rhs.is_a? Rational
+ rhs = rhs.to_f
+ end
+ __send__(original_operator_name, rhs)
+ end
+ end if Object.const_defined?(:Float)
+end
diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c
new file mode 100644
index 000000000..2a3f6df09
--- /dev/null
+++ b/mrbgems/mruby-rational/src/rational.c
@@ -0,0 +1,115 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/istruct.h>
+
+struct mrb_rational {
+ mrb_int numerator;
+ mrb_int denominator;
+};
+
+static struct mrb_rational*
+rational_ptr(mrb_value v)
+{
+ return (struct mrb_rational*)mrb_istruct_ptr(v);
+}
+
+static mrb_value
+rational_numerator(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ return mrb_fixnum_value(p->numerator);
+}
+
+static mrb_value
+rational_denominator(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ return mrb_fixnum_value(p->denominator);
+}
+
+static mrb_value
+rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
+{
+ struct RClass *c = mrb_class_get(mrb, "Rational");
+ struct RIStruct *s = (struct RIStruct*)mrb_obj_alloc(mrb, MRB_TT_ISTRUCT, c);
+ mrb_value rat = mrb_obj_value(s);
+ struct mrb_rational *p = rational_ptr(rat);
+ p->numerator = numerator;
+ p->denominator = denominator;
+ return rat;
+}
+
+static mrb_value
+rational_s_new(mrb_state *mrb, mrb_value self)
+{
+ mrb_int numerator, denominator;
+
+ mrb_get_args(mrb, "ii", &numerator, &denominator);
+ return rational_new(mrb, numerator, denominator);
+}
+
+#ifndef MRB_WITHOUT_FLOAT
+static mrb_value
+rational_to_f(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ mrb_float f = (mrb_float)p->numerator / (mrb_float)p->denominator;
+
+ return mrb_float_value(mrb, f);
+}
+#endif
+
+static mrb_value
+rational_to_i(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ return mrb_fixnum_value(p->numerator / p->denominator);
+}
+
+static mrb_value
+rational_to_r(mrb_state *mrb, mrb_value self)
+{
+ return self;
+}
+
+static mrb_value
+rational_negative_p(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ if (p->numerator < 0) {
+ return mrb_true_value();
+ }
+ return mrb_false_value();
+}
+
+static mrb_value
+fix_to_r(mrb_state *mrb, mrb_value self)
+{
+ return rational_new(mrb, mrb_fixnum(self), 1);
+}
+
+void mrb_mruby_rational_gem_init(mrb_state *mrb)
+{
+ struct RClass *rat;
+
+ mrb_assert(sizeof(struct mrb_rational) < ISTRUCT_DATA_SIZE);
+ rat = mrb_define_class(mrb, "Rational", mrb_class_get(mrb, "Numeric"));
+ MRB_SET_INSTANCE_TT(rat, MRB_TT_ISTRUCT);
+ mrb_undef_class_method(mrb, rat, "new");
+ mrb_define_class_method(mrb, rat, "_new", rational_s_new, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "denominator", rational_denominator, MRB_ARGS_NONE());
+#ifndef MRB_WITHOUT_FLOAT
+ mrb_define_method(mrb, rat, "to_f", rational_to_f, MRB_ARGS_NONE());
+#endif
+ mrb_define_method(mrb, rat, "to_i", rational_to_i, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "to_r", rational_to_r, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "negative?", rational_negative_p, MRB_ARGS_NONE());
+ mrb_define_method(mrb, mrb->fixnum_class, "to_r", fix_to_r, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_rational_gem_final(mrb_state* mrb)
+{
+}
diff --git a/mrbgems/mruby-rational/test/rational.rb b/mrbgems/mruby-rational/test/rational.rb
new file mode 100644
index 000000000..ea55880fe
--- /dev/null
+++ b/mrbgems/mruby-rational/test/rational.rb
@@ -0,0 +1,267 @@
+def assert_rational(exp, real)
+ assert_float exp.numerator, real.numerator
+ assert_float exp.denominator, real.denominator
+end
+
+def assert_equal_rational(exp, o1, o2)
+ if exp
+ assert_operator(o1, :==, o2)
+ assert_not_operator(o1, :!=, o2)
+ else
+ assert_not_operator(o1, :==, o2)
+ assert_operator(o1, :!=, o2)
+ end
+end
+
+def assert_cmp(exp, o1, o2)
+ if exp == (o1 <=> o2)
+ pass
+ else
+ flunk "", " Expected #{o1.inspect} <=> #{o2.inspect} to be #{exp}"
+ end
+end
+
+assert 'Rational' do
+ r = 5r
+ assert_equal(Rational, r.class)
+ assert_equal([5, 1], [r.numerator, r.denominator])
+end
+
+assert 'Rational#to_f' do
+ assert_float(2.0, Rational(2).to_f)
+ assert_float(2.25, Rational(9, 4).to_f)
+ assert_float(-0.75, Rational(-3, 4).to_f)
+ assert_float(6.666666666666667, Rational(20, 3).to_f)
+end
+
+assert 'Rational#to_i' do
+ assert_equal(0, Rational(2, 3).to_i)
+ assert_equal(3, Rational(3).to_i)
+ assert_equal(300, Rational(300.6).to_i)
+ assert_equal(1, Rational(98, 71).to_i)
+ assert_equal(-15, Rational(-30, 2).to_i)
+end
+
+assert 'Rational#*' do
+ assert_rational(Rational(4, 9), Rational(2, 3) * Rational(2, 3))
+ assert_rational(Rational(900, 1), Rational(900) * Rational(1))
+ assert_rational(Rational(1, 1), Rational(-2, 9) * Rational(-9, 2))
+ assert_rational(Rational(9, 2), Rational(9, 8) * 4)
+ assert_float( 21.77777777777778, Rational(20, 9) * 9.8)
+end
+
+assert 'Rational#+' do
+ assert_rational(Rational(4, 3), Rational(2, 3) + Rational(2, 3))
+ assert_rational(Rational(901, 1), Rational(900) + Rational(1))
+ assert_rational(Rational(-85, 18), Rational(-2, 9) + Rational(-9, 2))
+ assert_rational(Rational(41, 8), Rational(9, 8) + 4)
+ assert_float( 12.022222222222222, Rational(20, 9) + 9.8)
+end
+
+assert 'Rational#-' do
+ assert_rational(Rational(0, 1), Rational(2, 3) - Rational(2, 3))
+ assert_rational(Rational(899, 1), Rational(900) - Rational(1))
+ assert_rational(Rational(77, 18), Rational(-2, 9) - Rational(-9, 2))
+ assert_rational(Rational(-23, 8), Rational(9, 8) - 4)
+ assert_float( -7.577777777777778, Rational(20, 9) - 9.8)
+end
+
+assert 'Rational#/' do
+ assert_rational(Rational(1, 1), Rational(2, 3) / Rational(2, 3))
+ assert_rational(Rational(900, 1), Rational(900) / Rational(1))
+ assert_rational(Rational(4, 81), Rational(-2, 9) / Rational(-9, 2))
+ assert_rational(Rational(9, 32), Rational(9, 8) / 4)
+ assert_float( 0.22675736961451246, Rational(20, 9) / 9.8)
+end
+
+assert 'Rational#==, Rational#!=' do
+ assert_equal_rational(true, Rational(1,1), Rational(1))
+ assert_equal_rational(true, Rational(-1,1), -1r)
+ assert_equal_rational(true, Rational(13,4), 3.25)
+ assert_equal_rational(true, Rational(13,3.25), Rational(4,1))
+ assert_equal_rational(true, Rational(-3,-4), Rational(3,4))
+ assert_equal_rational(true, Rational(-4,5), Rational(4,-5))
+ assert_equal_rational(true, Rational(4,2), 2)
+ assert_equal_rational(true, Rational(-4,2), -2)
+ assert_equal_rational(true, Rational(4,-2), -2)
+ assert_equal_rational(true, Rational(4,2), 2.0)
+ assert_equal_rational(true, Rational(-4,2), -2.0)
+ assert_equal_rational(true, Rational(4,-2), -2.0)
+ assert_equal_rational(true, Rational(8,6), Rational(4,3))
+ assert_equal_rational(false, Rational(13,4), 3)
+ assert_equal_rational(false, Rational(13,4), 3.3)
+ assert_equal_rational(false, Rational(2,1), 1r)
+ assert_equal_rational(false, Rational(1), nil)
+ assert_equal_rational(false, Rational(1), '')
+end
+
+assert 'Fixnum#==(Rational), Fixnum#!=(Rational)' do
+ assert_equal_rational(true, 2, Rational(4,2))
+ assert_equal_rational(true, -2, Rational(-4,2))
+ assert_equal_rational(true, -2, Rational(4,-2))
+ assert_equal_rational(false, 3, Rational(13,4))
+end
+
+assert 'Float#==(Rational), Float#!=(Rational)' do
+ assert_equal_rational(true, 2.0, Rational(4,2))
+ assert_equal_rational(true, -2.0, Rational(-4,2))
+ assert_equal_rational(true, -2.0, Rational(4,-2))
+ assert_equal_rational(false, 3.3, Rational(13,4))
+end
+
+assert 'Rational#<=>' do
+ num = Class.new(Numeric) do
+ def initialize(n)
+ @n = n
+ end
+
+ def <=>(rhs)
+ rhs = rhs.to_i
+ rhs < 0 ? nil : @n <=> rhs
+ end
+
+ def inspect
+ "num(#{@n})"
+ end
+ end
+
+ assert_cmp(-1, Rational(-1), Rational(0))
+ assert_cmp(0, Rational(0), Rational(0))
+ assert_cmp(1, Rational(1), Rational(0))
+ assert_cmp(-1, Rational(-1), 0)
+ assert_cmp(0, Rational(0), 0)
+ assert_cmp(1, Rational(1), 0)
+ assert_cmp(-1, Rational(-1), 0.0)
+ assert_cmp(0, Rational(0), 0.0)
+ assert_cmp(1, Rational(1), 0.0)
+ assert_cmp(-1, Rational(1,2), Rational(2,3))
+ assert_cmp(0, Rational(2,3), Rational(2,3))
+ assert_cmp(1, Rational(2,3), Rational(1,2))
+ assert_cmp(1, Rational(2,3), Rational(1,2))
+ assert_cmp(1, Rational(0), Rational(-1))
+ assert_cmp(-1, Rational(0), Rational(1))
+ assert_cmp(1, Rational(2,3), Rational(1,2))
+ assert_cmp(0, Rational(2,3), Rational(2,3))
+ assert_cmp(-1, Rational(1,2), Rational(2,3))
+ assert_cmp(-1, Rational(1,2), Rational(2,3))
+ assert_cmp(nil, 3r, "3")
+ assert_cmp(1, 3r, num.new(2))
+ assert_cmp(0, 3r, num.new(3))
+ assert_cmp(-1, 3r, num.new(4))
+ assert_cmp(nil, Rational(-3), num.new(5))
+end
+
+assert 'Fixnum#<=>(Rational)' do
+ assert_cmp(-1, -2, Rational(-9,5))
+ assert_cmp(0, 5, 5r)
+ assert_cmp(1, 3, Rational(8,3))
+end
+
+assert 'Float#<=>(Rational)' do
+ assert_cmp(-1, -2.1, Rational(-9,5))
+ assert_cmp(0, 5.0, 5r)
+ assert_cmp(1, 2.7, Rational(8,3))
+end
+
+assert 'Rational#<' do
+ assert_operator(Rational(1,2), :<, Rational(2,3))
+ assert_not_operator(Rational(2,3), :<, Rational(2,3))
+ assert_operator(Rational(2,3), :<, 1)
+ assert_not_operator(2r, :<, 2)
+ assert_not_operator(Rational(2,3), :<, -3)
+ assert_operator(Rational(-4,3), :<, -0.3)
+ assert_not_operator(Rational(13,4), :<, 3.25)
+ assert_not_operator(Rational(2,3), :<, 0.6)
+ assert_raise(ArgumentError) { 1r < "2" }
+end
+
+assert 'Fixnum#<(Rational)' do
+ assert_not_operator(1, :<, Rational(2,3))
+ assert_not_operator(2, :<, 2r)
+ assert_operator(-3, :<, Rational(2,3))
+end
+
+assert 'Float#<(Rational)' do
+ assert_not_operator(-0.3, :<, Rational(-4,3))
+ assert_not_operator(3.25, :<, Rational(13,4))
+ assert_operator(0.6, :<, Rational(2,3))
+end
+
+assert 'Rational#<=' do
+ assert_operator(Rational(1,2), :<=, Rational(2,3))
+ assert_operator(Rational(2,3), :<=, Rational(2,3))
+ assert_operator(Rational(2,3), :<=, 1)
+ assert_operator(2r, :<=, 2)
+ assert_not_operator(Rational(2,3), :<=, -3)
+ assert_operator(Rational(-4,3), :<=, -0.3)
+ assert_operator(Rational(13,4), :<=, 3.25)
+ assert_not_operator(Rational(2,3), :<=, 0.6)
+ assert_raise(ArgumentError) { 1r <= "2" }
+end
+
+assert 'Fixnum#<=(Rational)' do
+ assert_not_operator(1, :<=, Rational(2,3))
+ assert_operator(2, :<=, 2r)
+ assert_operator(-3, :<=, Rational(2,3))
+end
+
+assert 'Float#<=(Rational)' do
+ assert_not_operator(-0.3, :<=, Rational(-4,3))
+ assert_operator(3.25, :<=, Rational(13,4))
+ assert_operator(0.6, :<=, Rational(2,3))
+end
+
+assert 'Rational#>' do
+ assert_not_operator(Rational(1,2), :>, Rational(2,3))
+ assert_not_operator(Rational(2,3), :>, Rational(2,3))
+ assert_not_operator(Rational(2,3), :>, 1)
+ assert_not_operator(2r, :>, 2)
+ assert_operator(Rational(2,3), :>, -3)
+ assert_not_operator(Rational(-4,3), :>, -0.3)
+ assert_not_operator(Rational(13,4), :>, 3.25)
+ assert_operator(Rational(2,3), :>, 0.6)
+ assert_raise(ArgumentError) { 1r > "2" }
+end
+
+assert 'Fixnum#>(Rational)' do
+ assert_operator(1, :>, Rational(2,3))
+ assert_not_operator(2, :>, 2r)
+ assert_not_operator(-3, :>, Rational(2,3))
+end
+
+assert 'Float#>(Rational)' do
+ assert_operator(-0.3, :>, Rational(-4,3))
+ assert_not_operator(3.25, :>, Rational(13,4))
+ assert_not_operator(0.6, :>, Rational(2,3))
+end
+
+assert 'Rational#>=' do
+ assert_not_operator(Rational(1,2), :>=, Rational(2,3))
+ assert_operator(Rational(2,3), :>=, Rational(2,3))
+ assert_not_operator(Rational(2,3), :>=, 1)
+ assert_operator(2r, :>=, 2)
+ assert_operator(Rational(2,3), :>=, -3)
+ assert_not_operator(Rational(-4,3), :>=, -0.3)
+ assert_operator(Rational(13,4), :>=, 3.25)
+ assert_operator(Rational(2,3), :>=, 0.6)
+ assert_raise(ArgumentError) { 1r >= "2" }
+end
+
+assert 'Fixnum#>=(Rational)' do
+ assert_operator(1, :>=, Rational(2,3))
+ assert_operator(2, :>=, 2r)
+ assert_not_operator(-3, :>=, Rational(2,3))
+end
+
+assert 'Float#>=(Rational)' do
+ assert_operator(-0.3, :>=, Rational(-4,3))
+ assert_operator(3.25, :>=, Rational(13,4))
+ assert_not_operator(0.6, :>=, Rational(2,3))
+end
+
+assert 'Rational#negative?' do
+ assert_predicate(Rational(-2,3), :negative?)
+ assert_predicate(Rational(2,-3), :negative?)
+ assert_not_predicate(Rational(2,3), :negative?)
+ assert_not_predicate(Rational(0), :negative?)
+end
diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c
index dff176778..8515a6057 100644
--- a/mrbgems/mruby-socket/src/socket.c
+++ b/mrbgems/mruby-socket/src/socket.c
@@ -38,6 +38,7 @@
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/data.h"
+#include "mruby/numeric.h"
#include "mruby/string.h"
#include "mruby/variable.h"
#include "error.h"
@@ -130,7 +131,7 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
mrb_get_args(mrb, "oo|oooi", &nodename, &service, &family, &socktype, &protocol, &flags);
if (mrb_string_p(nodename)) {
- hostname = mrb_str_to_cstr(mrb, nodename);
+ hostname = mrb_string_value_cstr(mrb, &nodename);
} else if (mrb_nil_p(nodename)) {
hostname = NULL;
} else {
@@ -138,9 +139,9 @@ mrb_addrinfo_getaddrinfo(mrb_state *mrb, mrb_value klass)
}
if (mrb_string_p(service)) {
- servname = mrb_str_to_cstr(mrb, service);
+ servname = mrb_string_value_cstr(mrb, &service);
} else if (mrb_fixnum_p(service)) {
- servname = mrb_str_to_cstr(mrb, mrb_funcall(mrb, service, "to_s", 0));
+ servname = RSTRING_PTR(mrb_fixnum_to_str(mrb, service, 10));
} else if (mrb_nil_p(service)) {
servname = NULL;
} else {
diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb
index 311803ea2..fdaf2f960 100644
--- a/mrbgems/mruby-string-ext/mrblib/string.rb
+++ b/mrbgems/mruby-string-ext/mrblib/string.rb
@@ -310,11 +310,15 @@ class String
end
end
+ ##
+ # Call the given block for each character of
+ # +self+.
def each_char(&block)
return to_enum :each_char unless block
-
- split('').each do |i|
- block.call(i)
+ pos = 0
+ while pos < self.size
+ block.call(self[pos])
+ pos += 1
end
self
end
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index 44ca1fde2..02777e594 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -657,19 +657,19 @@ assert('String#chars(UTF-8)') do
end if UTF8STRING
assert('String#each_char') do
- s = ""
+ chars = []
"hello!".each_char do |x|
- s += x
+ chars << x
end
- assert_equal "hello!", s
+ assert_equal ["h", "e", "l", "l", "o", "!"], chars
end
assert('String#each_char(UTF-8)') do
- s = ""
+ chars = []
"こんにちは世界!".each_char do |x|
- s += x
+ chars << x
end
- assert_equal "こんにちは世界!", s
+ assert_equal ["こ", "ん", "に", "ち", "は", "世", "界", "!"], chars
end if UTF8STRING
assert('String#codepoints') do
diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb
index c298fef9f..91e8cecc6 100644
--- a/mrbgems/mruby-struct/test/struct.rb
+++ b/mrbgems/mruby-struct/test/struct.rb
@@ -152,14 +152,14 @@ assert("Struct#dig") do
assert_equal 1, a.dig(1, 0)
end
-assert("Struct.new removes existing constant") do
- skip "redefining Struct with same name cause warnings"
- begin
- assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
- ensure
- Struct.remove_const :Test
- end
-end
+# TODO: suppress redefining Struct warning during test
+# assert("Struct.new removes existing constant") do
+# begin
+# assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
+# ensure
+# Struct.remove_const :Test
+# end
+# end
assert("Struct#initialize_copy requires struct to be the same type") do
begin
diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c
index 7f6c3004d..34376c286 100644
--- a/mrbgems/mruby-time/src/time.c
+++ b/mrbgems/mruby-time/src/time.c
@@ -18,6 +18,7 @@
#endif
#define NDIV(x,y) (-(-((x)+1)/(y))-1)
+#define TO_S_FMT "%Y-%m-%d %H:%M:%S "
#if defined(_MSC_VER) && _MSC_VER < 1800
double round(double x) {
@@ -204,17 +205,18 @@ static struct mrb_time*
time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc)
{
struct tm *aid;
+ time_t t = self->sec;
if (self->timezone == MRB_TIMEZONE_UTC) {
- aid = gmtime_r(&self->sec, &self->datetime);
+ aid = gmtime_r(&t, &self->datetime);
}
else {
- aid = localtime_r(&self->sec, &self->datetime);
+ aid = localtime_r(&t, &self->datetime);
}
if (!aid) {
- mrb_float sec = (mrb_float)self->sec;
+ mrb_float sec = (mrb_float)t;
- mrb_free(mrb, self);
+ if (dealloc) mrb_free(mrb, self);
mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec));
/* not reached */
return NULL;
@@ -291,24 +293,24 @@ mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mr
static struct mrb_time*
current_mrb_time(mrb_state *mrb)
{
+ struct mrb_time tmzero = {0};
struct mrb_time *tm;
+ time_t sec, usec;
- tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
#if defined(TIME_UTC) && !defined(__ANDROID__)
{
struct timespec ts;
if (timespec_get(&ts, TIME_UTC) == 0) {
- mrb_free(mrb, tm);
mrb_raise(mrb, E_RUNTIME_ERROR, "timespec_get() failed for unknown reasons");
}
- tm->sec = ts.tv_sec;
- tm->usec = ts.tv_nsec / 1000;
+ sec = ts.tv_sec;
+ usec = ts.tv_nsec / 1000;
}
#elif defined(NO_GETTIMEOFDAY)
{
static time_t last_sec = 0, last_usec = 0;
- tm->sec = time(NULL);
+ sec = time(NULL);
if (tm->sec != last_sec) {
last_sec = tm->sec;
last_usec = 0;
@@ -317,17 +319,20 @@ current_mrb_time(mrb_state *mrb)
/* add 1 usec to differentiate two times */
last_usec += 1;
}
- tm->usec = last_usec;
+ usec = last_usec;
}
#else
{
struct timeval tv;
gettimeofday(&tv, NULL);
- tm->sec = tv.tv_sec;
- tm->usec = tv.tv_usec;
+ sec = tv.tv_sec;
+ usec = tv.tv_usec;
}
#endif
+ tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
+ *tm = tmzero;
+ tm->sec = sec; tm->usec = usec;
tm->timezone = MRB_TIMEZONE_LOCAL;
time_update_datetime(mrb, tm, TRUE);
@@ -576,10 +581,9 @@ mrb_time_asctime(mrb_state *mrb, mrb_value self)
#else
char buf[256];
- len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d",
+ len = snprintf(buf, sizeof(buf), "%s %s %2d %02d:%02d:%02d %.4d",
wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
d->tm_hour, d->tm_min, d->tm_sec,
- tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",
d->tm_year + 1900);
#endif
return mrb_str_new(mrb, buf, len);
@@ -761,7 +765,6 @@ mrb_time_sec(mrb_state *mrb, mrb_value self)
return mrb_fixnum_value(tm->datetime.tm_sec);
}
-
/* 15.2.19.7.24 */
/* Returns a Float with the time since the epoch in seconds. */
static mrb_value
@@ -825,6 +828,15 @@ mrb_time_utc_p(mrb_state *mrb, mrb_value self)
return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC);
}
+static mrb_value
+mrb_time_to_s(mrb_state *mrb, mrb_value self)
+{
+ char buf[64];
+ struct mrb_time *tm = time_get_ptr(mrb, self);
+ const char *fmt = tm->timezone == MRB_TIMEZONE_UTC ? TO_S_FMT "UTC" : TO_S_FMT "%z";
+ size_t len = strftime(buf, sizeof(buf), fmt, &tm->datetime);
+ return mrb_str_new(mrb, buf, len);
+}
void
mrb_mruby_time_gem_init(mrb_state* mrb)
@@ -845,8 +857,8 @@ mrb_mruby_time_gem_init(mrb_state* mrb)
mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */
mrb_define_method(mrb, tc, "+" , mrb_time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */
mrb_define_method(mrb, tc, "-" , mrb_time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */
- mrb_define_method(mrb, tc, "to_s" , mrb_time_asctime, MRB_ARGS_NONE());
- mrb_define_method(mrb, tc, "inspect", mrb_time_asctime, MRB_ARGS_NONE());
+ mrb_define_method(mrb, tc, "to_s" , mrb_time_to_s , MRB_ARGS_NONE());
+ mrb_define_method(mrb, tc, "inspect", mrb_time_to_s , MRB_ARGS_NONE());
mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */
mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */
mrb_define_method(mrb, tc, "day" , mrb_time_day , MRB_ARGS_NONE()); /* 15.2.19.7.6 */
diff --git a/mrbgems/mruby-time/test/time.rb b/mrbgems/mruby-time/test/time.rb
index 54c446ca3..ce7b39928 100644
--- a/mrbgems/mruby-time/test/time.rb
+++ b/mrbgems/mruby-time/test/time.rb
@@ -2,11 +2,11 @@
# Time ISO Test
assert('Time.new', '15.2.3.3.3') do
- Time.new.class == Time
+ assert_equal(Time, Time.new.class)
end
assert('Time', '15.2.19') do
- Time.class == Class
+ assert_equal(Class, Time.class)
end
assert('Time.at', '15.2.19.6.1') do
@@ -21,30 +21,58 @@ assert('Time.at', '15.2.19.6.1') do
end
assert('Time.gm', '15.2.19.6.2') do
- Time.gm(2012, 12, 23)
+ t = Time.gm(2012, 9, 23)
+ assert_operator(2012, :eql?, t.year)
+ assert_operator( 9, :eql?, t.month)
+ assert_operator( 23, :eql?, t.day)
+ assert_operator( 0, :eql?, t.hour)
+ assert_operator( 0, :eql?, t.min)
+ assert_operator( 0, :eql?, t.sec)
+ assert_operator( 0, :eql?, t.usec)
end
assert('Time.local', '15.2.19.6.3') do
- Time.local(2012, 12, 23)
+ t = Time.local(2014, 12, 27, 18)
+ assert_operator(2014, :eql?, t.year)
+ assert_operator( 12, :eql?, t.month)
+ assert_operator( 27, :eql?, t.day)
+ assert_operator( 18, :eql?, t.hour)
+ assert_operator( 0, :eql?, t.min)
+ assert_operator( 0, :eql?, t.sec)
+ assert_operator( 0, :eql?, t.usec)
end
assert('Time.mktime', '15.2.19.6.4') do
- Time.mktime(2012, 12, 23)
+ t = Time.mktime(2013, 10, 4, 6, 15, 58, 3485)
+ assert_operator(2013, :eql?, t.year)
+ assert_operator( 10, :eql?, t.month)
+ assert_operator( 4, :eql?, t.day)
+ assert_operator( 6, :eql?, t.hour)
+ assert_operator( 15, :eql?, t.min)
+ assert_operator( 58, :eql?, t.sec)
+ assert_operator(3485, :eql?, t.usec)
end
assert('Time.now', '15.2.19.6.5') do
- Time.now.class == Time
+ assert_equal(Time, Time.now.class)
end
assert('Time.utc', '15.2.19.6.6') do
- Time.utc(2012, 12, 23)
+ t = Time.utc(2034)
+ assert_operator(2034, :eql?, t.year)
+ assert_operator( 1, :eql?, t.month)
+ assert_operator( 1, :eql?, t.day)
+ assert_operator( 0, :eql?, t.hour)
+ assert_operator( 0, :eql?, t.min)
+ assert_operator( 0, :eql?, t.sec)
+ assert_operator( 0, :eql?, t.usec)
end
assert('Time#+', '15.2.19.7.1') do
t1 = Time.at(1300000000.0)
t2 = t1.+(60)
- assert_equal(t2.utc.asctime, "Sun Mar 13 07:07:40 UTC 2011")
+ assert_equal(t2.utc.asctime, "Sun Mar 13 07:07:40 2011")
assert_raise(FloatDomainError) { Time.at(0) + Float::NAN }
assert_raise(FloatDomainError) { Time.at(0) + Float::INFINITY }
@@ -55,7 +83,7 @@ assert('Time#-', '15.2.19.7.2') do
t1 = Time.at(1300000000.0)
t2 = t1.-(60)
- assert_equal(t2.utc.asctime, "Sun Mar 13 07:05:40 UTC 2011")
+ assert_equal(t2.utc.asctime, "Sun Mar 13 07:05:40 2011")
assert_raise(FloatDomainError) { Time.at(0) - Float::NAN }
assert_raise(FloatDomainError) { Time.at(0) - Float::INFINITY }
@@ -67,30 +95,30 @@ assert('Time#<=>', '15.2.19.7.3') do
t2 = Time.at(1400000000.0)
t3 = Time.at(1500000000.0)
- t2.<=>(t1) == 1 and
- t2.<=>(t2) == 0 and
- t2.<=>(t3) == -1 and
- t2.<=>(nil) == nil
+ assert_equal(1, t2 <=> t1)
+ assert_equal(0, t2 <=> t2)
+ assert_equal(-1, t2 <=> t3)
+ assert_nil(t2 <=> nil)
end
assert('Time#asctime', '15.2.19.7.4') do
- Time.at(1300000000.0).utc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+ assert_equal("Thu Mar 4 05:06:07 1982", Time.gm(1982,3,4,5,6,7).asctime)
end
assert('Time#ctime', '15.2.19.7.5') do
- Time.at(1300000000.0).utc.ctime == "Sun Mar 13 07:06:40 UTC 2011"
+ assert_equal("Thu Oct 24 15:26:47 2013", Time.gm(2013,10,24,15,26,47).ctime)
end
assert('Time#day', '15.2.19.7.6') do
- Time.gm(2012, 12, 23).day == 23
+ assert_equal(23, Time.gm(2012, 12, 23).day)
end
assert('Time#dst?', '15.2.19.7.7') do
- not Time.gm(2012, 12, 23).utc.dst?
+ assert_not_predicate(Time.gm(2012, 12, 23).utc, :dst?)
end
assert('Time#getgm', '15.2.19.7.8') do
- Time.at(1300000000.0).getgm.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+ assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getgm.asctime)
end
assert('Time#getlocal', '15.2.19.7.9') do
@@ -98,114 +126,120 @@ assert('Time#getlocal', '15.2.19.7.9') do
t2 = Time.at(1300000000.0)
t3 = t1.getlocal
- t1 == t3 and t3 == t2.getlocal
+ assert_equal(t1, t3)
+ assert_equal(t3, t2.getlocal)
end
assert('Time#getutc', '15.2.19.7.10') do
- Time.at(1300000000.0).getutc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+ assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getutc.asctime)
end
assert('Time#gmt?', '15.2.19.7.11') do
- Time.at(1300000000.0).utc.gmt?
+ assert_predicate(Time.at(1300000000.0).utc, :gmt?)
end
# ATM not implemented
# assert('Time#gmt_offset', '15.2.19.7.12') do
assert('Time#gmtime', '15.2.19.7.13') do
- Time.at(1300000000.0).gmtime
+ t = Time.now
+ assert_predicate(t.gmtime, :gmt?)
+ assert_predicate(t, :gmt?)
end
# ATM not implemented
# assert('Time#gmtoff', '15.2.19.7.14') do
assert('Time#hour', '15.2.19.7.15') do
- Time.gm(2012, 12, 23, 7, 6).hour == 7
+ assert_equal(7, Time.gm(2012, 12, 23, 7, 6).hour)
end
# ATM doesn't really work
# assert('Time#initialize', '15.2.19.7.16') do
assert('Time#initialize_copy', '15.2.19.7.17') do
- time_tmp_2 = Time.at(7.0e6)
- time_tmp_2.clone == time_tmp_2
+ t = Time.at(7.0e6)
+ assert_equal(t, t.clone)
end
assert('Time#localtime', '15.2.19.7.18') do
- t1 = Time.at(1300000000.0)
- t2 = Time.at(1300000000.0)
+ t1 = Time.utc(2014, 5 ,6)
+ t2 = Time.utc(2014, 5 ,6)
+ t3 = t2.getlocal
- t1.localtime
- t1 == t2.getlocal
+ assert_equal(t3, t1.localtime)
+ assert_equal(t3, t1)
end
assert('Time#mday', '15.2.19.7.19') do
- Time.gm(2012, 12, 23).mday == 23
+ assert_equal(23, Time.gm(2012, 12, 23).mday)
end
assert('Time#min', '15.2.19.7.20') do
- Time.gm(2012, 12, 23, 7, 6).min == 6
+ assert_equal(6, Time.gm(2012, 12, 23, 7, 6).min)
end
assert('Time#mon', '15.2.19.7.21') do
- Time.gm(2012, 12, 23).mon == 12
+ assert_equal(12, Time.gm(2012, 12, 23).mon)
end
assert('Time#month', '15.2.19.7.22') do
- Time.gm(2012, 12, 23).month == 12
+ assert_equal(12, Time.gm(2012, 12, 23).month)
end
assert('Times#sec', '15.2.19.7.23') do
- Time.gm(2012, 12, 23, 7, 6, 40).sec == 40
+ assert_equal(40, Time.gm(2012, 12, 23, 7, 6, 40).sec)
end
assert('Time#to_f', '15.2.19.7.24') do
- Time.at(1300000000.0).to_f == 1300000000.0
+ assert_operator(2.0, :eql?, Time.at(2).to_f)
end
assert('Time#to_i', '15.2.19.7.25') do
- Time.at(1300000000.0).to_i == 1300000000
+ assert_operator(2, :eql?, Time.at(2.0).to_i)
end
assert('Time#usec', '15.2.19.7.26') do
- Time.at(1300000000.0).usec == 0
+ assert_equal(0, Time.at(1300000000.0).usec)
end
assert('Time#utc', '15.2.19.7.27') do
- Time.at(1300000000.0).utc
+ t = Time.now
+ assert_predicate(t.utc, :gmt?)
+ assert_predicate(t, :gmt?)
end
assert('Time#utc?', '15.2.19.7.28') do
- Time.at(1300000000.0).utc.utc?
+ assert_predicate(Time.at(1300000000.0).utc, :utc?)
end
# ATM not implemented
# assert('Time#utc_offset', '15.2.19.7.29') do
assert('Time#wday', '15.2.19.7.30') do
- Time.gm(2012, 12, 23).wday == 0
+ assert_equal(0, Time.gm(2012, 12, 23).wday)
end
assert('Time#yday', '15.2.19.7.31') do
- Time.gm(2012, 12, 23).yday == 358
+ assert_equal(358, Time.gm(2012, 12, 23).yday)
end
assert('Time#year', '15.2.19.7.32') do
- Time.gm(2012, 12, 23).year == 2012
+ assert_equal(2012, Time.gm(2012, 12, 23).year)
end
assert('Time#zone', '15.2.19.7.33') do
- Time.at(1300000000.0).utc.zone == 'UTC'
+ assert_equal('UTC', Time.at(1300000000.0).utc.zone)
end
# Not ISO specified
assert('Time#to_s') do
- Time.at(1300000000.0).utc.to_s == "Sun Mar 13 07:06:40 UTC 2011"
+ assert_equal("2003-04-05 06:07:08 UTC", Time.gm(2003,4,5,6,7,8,9).to_s)
end
assert('Time#inspect') do
- Time.at(1300000000.0).utc.inspect == "Sun Mar 13 07:06:40 UTC 2011"
+ assert_match("2013-10-28 16:27:48 [^U]*", Time.local(2013,10,28,16,27,48).inspect)
end
assert('day of week methods') do
@@ -224,7 +258,7 @@ assert('2000 times 500us make a second') do
2000.times do
t += 0.0005
end
- t.usec == 0
+ assert_equal(0, t.usec)
end
assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do