json/src/test/java/net/java/html/json/ModelProcessorTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Wed, 09 Dec 2015 21:39:13 +0100
changeset 1023 4f906bde3a2e
parent 1011 267ca1bfeb6f
permissions -rw-r--r--
#257039: @Model.instance() to allow storage of private (and non-JSON like) state in a model
jtulach@3
     1
/**
jaroslav@358
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jtulach@3
     3
 *
jaroslav@551
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jtulach@3
     5
 *
jaroslav@358
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jaroslav@358
     7
 * Other names may be trademarks of their respective owners.
jtulach@3
     8
 *
jaroslav@358
     9
 * The contents of this file are subject to the terms of either the GNU
jaroslav@358
    10
 * General Public License Version 2 only ("GPL") or the Common
jaroslav@358
    11
 * Development and Distribution License("CDDL") (collectively, the
jaroslav@358
    12
 * "License"). You may not use this file except in compliance with the
jaroslav@358
    13
 * License. You can obtain a copy of the License at
jaroslav@358
    14
 * http://www.netbeans.org/cddl-gplv2.html
jaroslav@358
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jaroslav@358
    16
 * specific language governing permissions and limitations under the
jaroslav@358
    17
 * License.  When distributing the software, include this License Header
jaroslav@358
    18
 * Notice in each file and include the License file at
jaroslav@358
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jaroslav@358
    20
 * particular file as subject to the "Classpath" exception as provided
jaroslav@358
    21
 * by Oracle in the GPL Version 2 section of the License file that
jaroslav@358
    22
 * accompanied this code. If applicable, add the following below the
jaroslav@358
    23
 * License Header, with the fields enclosed by brackets [] replaced by
jaroslav@358
    24
 * your own identifying information:
jaroslav@358
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
jaroslav@358
    26
 *
jaroslav@358
    27
 * Contributor(s):
jaroslav@358
    28
 *
jaroslav@358
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
jaroslav@551
    30
 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jaroslav@358
    31
 *
jaroslav@358
    32
 * If you wish your version of this file to be governed by only the CDDL
jaroslav@358
    33
 * or only the GPL Version 2, indicate your decision by adding
jaroslav@358
    34
 * "[Contributor] elects to include this software in this distribution
jaroslav@358
    35
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jaroslav@358
    36
 * single choice of license, a recipient has the option to distribute
jaroslav@358
    37
 * your version of this file under either the CDDL, the GPL Version 2 or
jaroslav@358
    38
 * to extend the choice of license to its licensees as provided above.
jaroslav@358
    39
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jaroslav@358
    40
 * Version 2 license, then the option applies only if the new code is
jaroslav@358
    41
 * made subject to such option by the copyright holder.
jtulach@3
    42
 */
jtulach@3
    43
package net.java.html.json;
jtulach@3
    44
jtulach@3
    45
import java.io.IOException;
jtulach@3
    46
import java.util.Locale;
jtulach@3
    47
import javax.tools.Diagnostic;
jtulach@3
    48
import javax.tools.JavaFileObject;
jtulach@3
    49
import static org.testng.Assert.*;
jtulach@3
    50
import org.testng.annotations.Test;
jtulach@3
    51
jtulach@3
    52
/** Verify errors emitted by the processor.
jtulach@3
    53
 *
jtulach@790
    54
 * @author Jaroslav Tulach
jtulach@3
    55
 */
jtulach@3
    56
public class ModelProcessorTest {
jtulach@3
    57
    @Test public void verifyWrongType() throws IOException {
jtulach@3
    58
        String html = "<html><body>"
jtulach@3
    59
            + "</body></html>";
jtulach@3
    60
        String code = "package x.y.z;\n"
jtulach@3
    61
            + "import net.java.html.json.Model;\n"
jtulach@3
    62
            + "import net.java.html.json.Property;\n"
jtulach@3
    63
            + "@Model(className=\"XModel\", properties={\n"
jtulach@3
    64
            + "  @Property(name=\"prop\", type=Runnable.class)\n"
jtulach@3
    65
            + "})\n"
jtulach@3
    66
            + "class X {\n"
jtulach@3
    67
            + "}\n";
jtulach@940
    68
jtulach@3
    69
        Compile c = Compile.create(html, code);
jtulach@3
    70
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@3
    71
        boolean ok = false;
jtulach@3
    72
        StringBuilder msgs = new StringBuilder();
jtulach@3
    73
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jtulach@3
    74
            String msg = e.getMessage(Locale.ENGLISH);
jaroslav@68
    75
            if (msg.contains("Runnable")) {
jtulach@3
    76
                ok = true;
jtulach@3
    77
            }
jtulach@3
    78
            msgs.append("\n").append(msg);
jtulach@3
    79
        }
jtulach@3
    80
        if (!ok) {
jtulach@3
    81
            fail("Should contain warning about Runnable:" + msgs);
jtulach@3
    82
        }
jtulach@3
    83
    }
jtulach@940
    84
jtulach@926
    85
    @Test public void verifyWrongTypeInInnerClass() throws IOException {
jtulach@926
    86
        String html = "<html><body>"
jtulach@926
    87
            + "</body></html>";
jtulach@926
    88
        String code = "package x.y.z;\n"
jtulach@926
    89
            + "import net.java.html.json.Model;\n"
jtulach@926
    90
            + "import net.java.html.json.Property;\n"
jtulach@926
    91
            + "class X {\n"
jtulach@926
    92
            + "  @Model(className=\"XModel\", properties={\n"
jtulach@926
    93
            + "    @Property(name=\"prop\", type=Runnable.class)\n"
jtulach@926
    94
            + "  })\n"
jtulach@926
    95
            + "  static class Inner {\n"
jtulach@926
    96
            + "  }\n"
jtulach@926
    97
            + "}\n";
jtulach@940
    98
jtulach@926
    99
        Compile c = Compile.create(html, code);
jtulach@926
   100
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@926
   101
        boolean ok = false;
jtulach@926
   102
        StringBuilder msgs = new StringBuilder();
jtulach@926
   103
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jtulach@926
   104
            String msg = e.getMessage(Locale.ENGLISH);
jtulach@926
   105
            if (msg.contains("Runnable")) {
jtulach@926
   106
                ok = true;
jtulach@926
   107
            }
jtulach@926
   108
            msgs.append("\n").append(msg);
jtulach@926
   109
        }
jtulach@926
   110
        if (!ok) {
jtulach@926
   111
            fail("Should contain warning about Runnable:" + msgs);
jtulach@926
   112
        }
jtulach@926
   113
    }
jtulach@940
   114
jaroslav@227
   115
    @Test public void warnOnNonStatic() throws IOException {
jaroslav@227
   116
        String html = "<html><body>"
jaroslav@227
   117
            + "</body></html>";
jaroslav@227
   118
        String code = "package x.y.z;\n"
jaroslav@227
   119
            + "import net.java.html.json.Model;\n"
jaroslav@227
   120
            + "import net.java.html.json.Property;\n"
jaroslav@227
   121
            + "import net.java.html.json.ComputedProperty;\n"
jaroslav@227
   122
            + "@Model(className=\"XModel\", properties={\n"
jaroslav@227
   123
            + "  @Property(name=\"prop\", type=int.class)\n"
jaroslav@227
   124
            + "})\n"
jaroslav@227
   125
            + "class X {\n"
jaroslav@227
   126
            + "    @ComputedProperty int y(int prop) {\n"
jaroslav@227
   127
            + "        return prop;\n"
jaroslav@227
   128
            + "    }\n"
jaroslav@227
   129
            + "}\n";
jtulach@940
   130
jaroslav@227
   131
        Compile c = Compile.create(html, code);
jaroslav@227
   132
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jaroslav@227
   133
        boolean ok = false;
jaroslav@227
   134
        StringBuilder msgs = new StringBuilder();
jaroslav@227
   135
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jaroslav@227
   136
            String msg = e.getMessage(Locale.ENGLISH);
jaroslav@227
   137
            if (msg.contains("y has to be static")) {
jaroslav@227
   138
                ok = true;
jaroslav@227
   139
            }
jaroslav@227
   140
            msgs.append("\n").append(msg);
jaroslav@227
   141
        }
jaroslav@227
   142
        if (!ok) {
jaroslav@227
   143
            fail("Should contain warning about non-static method:" + msgs);
jaroslav@227
   144
        }
jaroslav@227
   145
    }
jtulach@940
   146
jtulach@1011
   147
    @Test public void tooManyProperties() throws IOException {
jtulach@1011
   148
        manyProperties(255, false, 0);
jtulach@1011
   149
    }
jtulach@1011
   150
jtulach@1011
   151
    @Test public void tooManyArrayPropertiesIsOK() throws IOException {
jtulach@1011
   152
        manyProperties(0, true, 300);
jtulach@1011
   153
    }
jtulach@1011
   154
jtulach@1011
   155
    @Test public void justEnoughProperties() throws IOException {
jtulach@1011
   156
        manyProperties(254, true, 0);
jtulach@1011
   157
    }
jtulach@1011
   158
jtulach@1011
   159
    @Test public void justEnoughPropertiesWithArrayOne() throws IOException {
jtulach@1011
   160
        manyProperties(253, true, 300);
jtulach@1011
   161
    }
jtulach@1011
   162
jtulach@1011
   163
    @Test public void justEnoughPropertiesButOneArrayOne() throws IOException {
jtulach@1011
   164
        manyProperties(254, false, 300);
jtulach@1011
   165
    }
jtulach@1011
   166
jtulach@1011
   167
    private void manyProperties(
jtulach@1011
   168
        int cnt, boolean constructorWithParams, int arrayCnt
jtulach@1011
   169
    ) throws IOException {
jtulach@1011
   170
        String html = "<html><body>"
jtulach@1011
   171
            + "</body></html>";
jtulach@1011
   172
        StringBuilder code = new StringBuilder();
jtulach@1011
   173
        code.append("package x.y.z;\n"
jtulach@1011
   174
            + "import net.java.html.json.Model;\n"
jtulach@1011
   175
            + "import net.java.html.json.Property;\n"
jtulach@1011
   176
            + "@Model(className=\"XModel\", properties={\n"
jtulach@1011
   177
        );
jtulach@1011
   178
        for (int i = 1; i <= cnt; i++) {
jtulach@1011
   179
            code.append("  @Property(name=\"prop").append(i).append("\", ");
jtulach@1011
   180
            code.append("type=int.class),\n");
jtulach@1011
   181
        }
jtulach@1011
   182
        for (int i = 1; i <= arrayCnt; i++) {
jtulach@1011
   183
            code.append("  @Property(name=\"array").append(i).append("\", ");
jtulach@1011
   184
            code.append("array=true, ");
jtulach@1011
   185
            code.append("type=int.class),\n");
jtulach@1011
   186
        }
jtulach@1011
   187
        code.append(""
jtulach@1011
   188
            + "})\n"
jtulach@1011
   189
            + "class X {\n"
jtulach@1011
   190
            + "    static {\n"
jtulach@1011
   191
            + "      new XModel();\n"
jtulach@1011
   192
            + "      new XModel("
jtulach@1011
   193
        );
jtulach@1011
   194
        if (constructorWithParams) {
jtulach@1011
   195
            code.append("0");
jtulach@1011
   196
            for (int i = 1; i < cnt; i++) {
jtulach@1011
   197
                code.append(",\n").append(i);
jtulach@1011
   198
            }
jtulach@1011
   199
        }
jtulach@1011
   200
        code.append(");\n"
jtulach@1011
   201
            + "    }\n"
jtulach@1011
   202
            + "}\n"
jtulach@1011
   203
        );
jtulach@1011
   204
jtulach@1011
   205
        Compile c = Compile.create(html, code.toString());
jtulach@1011
   206
        assertTrue(c.getErrors().isEmpty(), "Compiles OK: " + c.getErrors());
jtulach@1011
   207
    }
jtulach@1011
   208
jtulach@951
   209
    @Test public void writeableComputedPropertyMissingWrite() throws IOException {
jtulach@951
   210
        String html = "<html><body>"
jtulach@951
   211
            + "</body></html>";
jtulach@951
   212
        String code = "package x.y.z;\n"
jtulach@951
   213
            + "import net.java.html.json.Model;\n"
jtulach@951
   214
            + "import net.java.html.json.Property;\n"
jtulach@951
   215
            + "import net.java.html.json.ComputedProperty;\n"
jtulach@951
   216
            + "@Model(className=\"XModel\", properties={\n"
jtulach@951
   217
            + "  @Property(name=\"prop\", type=int.class)\n"
jtulach@951
   218
            + "})\n"
jtulach@951
   219
            + "class X {\n"
jtulach@951
   220
            + "    static @ComputedProperty(write=\"setY\") int y(int prop) {\n"
jtulach@951
   221
            + "        return prop;\n"
jtulach@951
   222
            + "    }\n"
jtulach@951
   223
            + "}\n";
jtulach@951
   224
jtulach@951
   225
        Compile c = Compile.create(html, code);
jtulach@951
   226
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@951
   227
        boolean ok = false;
jtulach@951
   228
        StringBuilder msgs = new StringBuilder();
jtulach@951
   229
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jtulach@951
   230
            String msg = e.getMessage(Locale.ENGLISH);
jtulach@951
   231
            if (msg.contains("Cannot find setY")) {
jtulach@951
   232
                ok = true;
jtulach@951
   233
            }
jtulach@951
   234
            msgs.append("\n").append(msg);
jtulach@951
   235
        }
jtulach@951
   236
        if (!ok) {
jtulach@951
   237
            fail("Should contain warning about non-static method:" + msgs);
jtulach@951
   238
        }
jtulach@951
   239
    }
jtulach@951
   240
jtulach@951
   241
    @Test public void writeableComputedPropertyWrongWriteType() throws IOException {
jtulach@951
   242
        String html = "<html><body>"
jtulach@951
   243
            + "</body></html>";
jtulach@951
   244
        String code = "package x.y.z;\n"
jtulach@951
   245
            + "import net.java.html.json.Model;\n"
jtulach@951
   246
            + "import net.java.html.json.Property;\n"
jtulach@951
   247
            + "import net.java.html.json.ComputedProperty;\n"
jtulach@951
   248
            + "@Model(className=\"XModel\", properties={\n"
jtulach@951
   249
            + "  @Property(name=\"prop\", type=int.class)\n"
jtulach@951
   250
            + "})\n"
jtulach@951
   251
            + "class X {\n"
jtulach@951
   252
            + "    static @ComputedProperty(write=\"setY\") int y(int prop) {\n"
jtulach@951
   253
            + "        return prop;\n"
jtulach@951
   254
            + "    }\n"
jtulach@954
   255
            + "    static void setY(XModel model, String prop) {\n"
jtulach@951
   256
            + "    }\n"
jtulach@951
   257
            + "}\n";
jtulach@951
   258
jtulach@951
   259
        Compile c = Compile.create(html, code);
jtulach@951
   260
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@951
   261
        boolean ok = false;
jtulach@951
   262
        StringBuilder msgs = new StringBuilder();
jtulach@951
   263
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jtulach@951
   264
            String msg = e.getMessage(Locale.ENGLISH);
jtulach@951
   265
            if (msg.contains("Write method first argument needs to be XModel and second int or Object")) {
jtulach@951
   266
                ok = true;
jtulach@951
   267
            }
jtulach@951
   268
            msgs.append("\n").append(msg);
jtulach@951
   269
        }
jtulach@951
   270
        if (!ok) {
jtulach@951
   271
            fail("Should contain warning about non-static method:" + msgs);
jtulach@951
   272
        }
jtulach@951
   273
    }
jtulach@951
   274
jtulach@955
   275
    @Test public void writeableComputedPropertyReturnsVoid() throws IOException {
jtulach@955
   276
        String html = "<html><body>"
jtulach@955
   277
            + "</body></html>";
jtulach@955
   278
        String code = "package x.y.z;\n"
jtulach@955
   279
            + "import net.java.html.json.Model;\n"
jtulach@955
   280
            + "import net.java.html.json.Property;\n"
jtulach@955
   281
            + "import net.java.html.json.ComputedProperty;\n"
jtulach@955
   282
            + "@Model(className=\"XModel\", properties={\n"
jtulach@955
   283
            + "  @Property(name=\"prop\", type=int.class)\n"
jtulach@955
   284
            + "})\n"
jtulach@955
   285
            + "class X {\n"
jtulach@955
   286
            + "    static @ComputedProperty(write=\"setY\") int y(int prop) {\n"
jtulach@955
   287
            + "        return prop;\n"
jtulach@955
   288
            + "    }\n"
jtulach@955
   289
            + "    static Number setY(XModel model, int prop) {\n"
jtulach@955
   290
            + "    }\n"
jtulach@955
   291
            + "}\n";
jtulach@955
   292
jtulach@955
   293
        Compile c = Compile.create(html, code);
jtulach@955
   294
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@955
   295
        boolean ok = false;
jtulach@955
   296
        StringBuilder msgs = new StringBuilder();
jtulach@955
   297
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jtulach@955
   298
            String msg = e.getMessage(Locale.ENGLISH);
jtulach@955
   299
            if (msg.contains("Write method has to return void")) {
jtulach@955
   300
                ok = true;
jtulach@955
   301
            }
jtulach@955
   302
            msgs.append("\n").append(msg);
jtulach@955
   303
        }
jtulach@955
   304
        if (!ok) {
jtulach@955
   305
            fail("Should contain warning about non-static method:" + msgs);
jtulach@955
   306
        }
jtulach@955
   307
    }
jtulach@955
   308
jaroslav@235
   309
    @Test public void computedCantReturnVoid() throws IOException {
jaroslav@235
   310
        String html = "<html><body>"
jaroslav@235
   311
            + "</body></html>";
jaroslav@235
   312
        String code = "package x.y.z;\n"
jaroslav@235
   313
            + "import net.java.html.json.Model;\n"
jaroslav@235
   314
            + "import net.java.html.json.Property;\n"
jaroslav@235
   315
            + "import net.java.html.json.ComputedProperty;\n"
jaroslav@235
   316
            + "@Model(className=\"XModel\", properties={\n"
jaroslav@235
   317
            + "  @Property(name=\"prop\", type=int.class)\n"
jaroslav@235
   318
            + "})\n"
jaroslav@235
   319
            + "class X {\n"
jaroslav@235
   320
            + "    @ComputedProperty static void y(int prop) {\n"
jaroslav@235
   321
            + "    }\n"
jaroslav@235
   322
            + "}\n";
jtulach@940
   323
jaroslav@235
   324
        Compile c = Compile.create(html, code);
jaroslav@235
   325
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jaroslav@235
   326
        boolean ok = false;
jaroslav@235
   327
        StringBuilder msgs = new StringBuilder();
jaroslav@235
   328
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jaroslav@235
   329
            String msg = e.getMessage(Locale.ENGLISH);
jaroslav@235
   330
            if (msg.contains("y cannot return void")) {
jaroslav@235
   331
                ok = true;
jaroslav@235
   332
            }
jaroslav@235
   333
            msgs.append("\n").append(msg);
jaroslav@235
   334
        }
jaroslav@235
   335
        if (!ok) {
jaroslav@235
   336
            fail("Should contain warning about non-static method:" + msgs);
jaroslav@235
   337
        }
jaroslav@235
   338
    }
jtulach@940
   339
jaroslav@235
   340
    @Test public void computedCantReturnRunnable() throws IOException {
jaroslav@235
   341
        String html = "<html><body>"
jaroslav@235
   342
            + "</body></html>";
jaroslav@235
   343
        String code = "package x.y.z;\n"
jaroslav@235
   344
            + "import net.java.html.json.Model;\n"
jaroslav@235
   345
            + "import net.java.html.json.Property;\n"
jaroslav@235
   346
            + "import net.java.html.json.ComputedProperty;\n"
jaroslav@235
   347
            + "@Model(className=\"XModel\", properties={\n"
jaroslav@235
   348
            + "  @Property(name=\"prop\", type=int.class)\n"
jaroslav@235
   349
            + "})\n"
jaroslav@235
   350
            + "class X {\n"
jaroslav@235
   351
            + "    @ComputedProperty static Runnable y(int prop) {\n"
jaroslav@235
   352
            + "       return null;\n"
jaroslav@235
   353
            + "    }\n"
jaroslav@235
   354
            + "}\n";
jtulach@940
   355
jaroslav@235
   356
        Compile c = Compile.create(html, code);
jaroslav@235
   357
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jaroslav@235
   358
        boolean ok = false;
jaroslav@235
   359
        StringBuilder msgs = new StringBuilder();
jaroslav@235
   360
        for (Diagnostic<? extends JavaFileObject> e : c.getErrors()) {
jaroslav@235
   361
            String msg = e.getMessage(Locale.ENGLISH);
jaroslav@235
   362
            if (msg.contains("y cannot return java.lang.Runnable")) {
jaroslav@235
   363
                ok = true;
jaroslav@235
   364
            }
jaroslav@235
   365
            msgs.append("\n").append(msg);
jaroslav@235
   366
        }
jaroslav@235
   367
        if (!ok) {
jaroslav@235
   368
            fail("Should contain warning about non-static method:" + msgs);
jaroslav@235
   369
        }
jaroslav@235
   370
    }
jtulach@940
   371
jaroslav@68
   372
    @Test public void canWeCompileWithJDK1_5SourceLevel() throws IOException {
jaroslav@68
   373
        String html = "<html><body>"
jaroslav@68
   374
            + "</body></html>";
jaroslav@68
   375
        String code = "package x.y.z;\n"
jaroslav@68
   376
            + "import net.java.html.json.Model;\n"
jaroslav@68
   377
            + "import net.java.html.json.Property;\n"
jaroslav@68
   378
            + "import net.java.html.json.ComputedProperty;\n"
jaroslav@68
   379
            + "@Model(className=\"XModel\", properties={\n"
jaroslav@68
   380
            + "  @Property(name=\"prop\", type=long.class)\n"
jaroslav@68
   381
            + "})\n"
jaroslav@68
   382
            + "class X {\n"
jaroslav@68
   383
            + "  @ComputedProperty static double derived(long prop) { return prop; }"
jaroslav@68
   384
            + "}\n";
jtulach@940
   385
jaroslav@68
   386
        Compile c = Compile.create(html, code, "1.5");
jaroslav@68
   387
        assertTrue(c.getErrors().isEmpty(), "No errors: " + c.getErrors());
jaroslav@68
   388
    }
jtulach@1023
   389
    
jtulach@1023
   390
    @Test public void instanceNeedsDefaultConstructor() throws IOException {
jtulach@1023
   391
        String html = "<html><body>"
jtulach@1023
   392
            + "</body></html>";
jtulach@1023
   393
        String code = "package x.y.z;\n"
jtulach@1023
   394
            + "import net.java.html.json.Model;\n"
jtulach@1023
   395
            + "import net.java.html.json.Property;\n"
jtulach@1023
   396
            + "import net.java.html.json.ComputedProperty;\n"
jtulach@1023
   397
            + "@Model(className=\"XModel\", instance=true, properties={\n"
jtulach@1023
   398
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@1023
   399
            + "})\n"
jtulach@1023
   400
            + "class X {\n"
jtulach@1023
   401
            + "  X(int x) {}\n"
jtulach@1023
   402
            + "}\n";
jtulach@1023
   403
jtulach@1023
   404
        Compile c = Compile.create(html, code);
jtulach@1023
   405
        c.assertError("Needs non-private default constructor when instance=true");
jtulach@1023
   406
    }
jtulach@1023
   407
    
jtulach@1023
   408
    @Test public void instanceNeedsNonPrivateConstructor() throws IOException {
jtulach@1023
   409
        String html = "<html><body>"
jtulach@1023
   410
            + "</body></html>";
jtulach@1023
   411
        String code = "package x.y.z;\n"
jtulach@1023
   412
            + "import net.java.html.json.Model;\n"
jtulach@1023
   413
            + "import net.java.html.json.Property;\n"
jtulach@1023
   414
            + "import net.java.html.json.ComputedProperty;\n"
jtulach@1023
   415
            + "@Model(className=\"XModel\", instance=true, properties={\n"
jtulach@1023
   416
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@1023
   417
            + "})\n"
jtulach@1023
   418
            + "class X {\n"
jtulach@1023
   419
            + "  private X() {}\n"
jtulach@1023
   420
            + "}\n";
jtulach@1023
   421
jtulach@1023
   422
        Compile c = Compile.create(html, code);
jtulach@1023
   423
        c.assertError("Needs non-private default constructor when instance=true");
jtulach@1023
   424
    }
jtulach@1023
   425
jtulach@1023
   426
    @Test public void instanceNoConstructorIsOK() throws IOException {
jtulach@1023
   427
        String html = "<html><body>"
jtulach@1023
   428
            + "</body></html>";
jtulach@1023
   429
        String code = "package x.y.z;\n"
jtulach@1023
   430
            + "import net.java.html.json.Model;\n"
jtulach@1023
   431
            + "import net.java.html.json.Property;\n"
jtulach@1023
   432
            + "import net.java.html.json.ComputedProperty;\n"
jtulach@1023
   433
            + "@Model(className=\"XModel\", instance=true, properties={\n"
jtulach@1023
   434
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@1023
   435
            + "})\n"
jtulach@1023
   436
            + "class X {\n"
jtulach@1023
   437
            + "}\n";
jtulach@1023
   438
jtulach@1023
   439
        Compile c = Compile.create(html, code);
jtulach@1023
   440
        c.assertNoErrors();
jtulach@1023
   441
    }
jtulach@940
   442
jaroslav@70
   443
    @Test public void putNeedsDataArgument() throws Exception {
jaroslav@70
   444
        needsAnArg("PUT");
jaroslav@70
   445
    }
jaroslav@70
   446
jaroslav@70
   447
    @Test public void postNeedsDataArgument() throws Exception {
jaroslav@70
   448
        needsAnArg("POST");
jaroslav@70
   449
    }
jtulach@940
   450
jaroslav@70
   451
    private void needsAnArg(String method) throws Exception {
jaroslav@70
   452
        String html = "<html><body>"
jaroslav@70
   453
            + "</body></html>";
jaroslav@70
   454
        String code = "package x.y.z;\n"
jaroslav@70
   455
            + "import net.java.html.json.Model;\n"
jaroslav@70
   456
            + "import net.java.html.json.Property;\n"
jaroslav@70
   457
            + "import net.java.html.json.OnReceive;\n"
jaroslav@70
   458
            + "@Model(className=\"XModel\", properties={\n"
jaroslav@70
   459
            + "  @Property(name=\"prop\", type=long.class)\n"
jaroslav@70
   460
            + "})\n"
jaroslav@70
   461
            + "class X {\n"
jaroslav@70
   462
            + "  @Model(className=\"PQ\", properties={})\n"
jaroslav@70
   463
            + "  class PImpl {\n"
jaroslav@70
   464
            + "  }\n"
jaroslav@70
   465
            + "  @OnReceive(method=\"" + method + "\", url=\"whereever\")\n"
jaroslav@70
   466
            + "  static void obtained(XModel m, PQ p) { }\n"
jaroslav@70
   467
            + "}\n";
jtulach@940
   468
jaroslav@70
   469
        Compile c = Compile.create(html, code);
jaroslav@70
   470
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jaroslav@70
   471
        for (Diagnostic<? extends JavaFileObject> diagnostic : c.getErrors()) {
jaroslav@70
   472
            String msg = diagnostic.getMessage(Locale.ENGLISH);
jaroslav@70
   473
            if (msg.contains("specify a data()")) {
jaroslav@70
   474
                return;
jaroslav@70
   475
            }
jaroslav@70
   476
        }
jaroslav@70
   477
        fail("Needs an error message about missing data():\n" + c.getErrors());
jtulach@940
   478
jaroslav@70
   479
    }
jtulach@940
   480
jtulach@940
   481
jaroslav@73
   482
    @Test public void jsonNeedsToUseGet () throws Exception {
jaroslav@73
   483
        String html = "<html><body>"
jaroslav@73
   484
            + "</body></html>";
jaroslav@73
   485
        String code = "package x.y.z;\n"
jaroslav@73
   486
            + "import net.java.html.json.Model;\n"
jaroslav@73
   487
            + "import net.java.html.json.Property;\n"
jaroslav@73
   488
            + "import net.java.html.json.OnReceive;\n"
jaroslav@73
   489
            + "@Model(className=\"XModel\", properties={\n"
jaroslav@73
   490
            + "  @Property(name=\"prop\", type=long.class)\n"
jaroslav@73
   491
            + "})\n"
jaroslav@73
   492
            + "class X {\n"
jaroslav@73
   493
            + "  @Model(className=\"PQ\", properties={})\n"
jaroslav@73
   494
            + "  class PImpl {\n"
jaroslav@73
   495
            + "  }\n"
jaroslav@73
   496
            + "  @OnReceive(method=\"POST\", jsonp=\"callback\", url=\"whereever\")\n"
jaroslav@73
   497
            + "  static void obtained(XModel m, PQ p) { }\n"
jaroslav@73
   498
            + "}\n";
jtulach@940
   499
jaroslav@73
   500
        Compile c = Compile.create(html, code);
jaroslav@73
   501
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jaroslav@73
   502
        for (Diagnostic<? extends JavaFileObject> diagnostic : c.getErrors()) {
jaroslav@73
   503
            String msg = diagnostic.getMessage(Locale.ENGLISH);
jaroslav@73
   504
            if (msg.contains("JSONP works only with GET")) {
jaroslav@73
   505
                return;
jaroslav@73
   506
            }
jaroslav@73
   507
        }
jaroslav@73
   508
        fail("Needs an error message about wrong method:\n" + c.getErrors());
jtulach@940
   509
jaroslav@73
   510
    }
jtulach@940
   511
jtulach@940
   512
    @Test public void noHeadersForWebSockets() throws Exception {
jtulach@940
   513
        String html = "<html><body>"
jtulach@940
   514
            + "</body></html>";
jtulach@940
   515
        String code = "package x.y.z;\n"
jtulach@940
   516
            + "import net.java.html.json.Model;\n"
jtulach@940
   517
            + "import net.java.html.json.Property;\n"
jtulach@940
   518
            + "import net.java.html.json.OnReceive;\n"
jtulach@940
   519
            + "@Model(className=\"XModel\", properties={\n"
jtulach@940
   520
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@940
   521
            + "})\n"
jtulach@940
   522
            + "class X {\n"
jtulach@940
   523
            + "  @Model(className=\"PQ\", properties={})\n"
jtulach@940
   524
            + "  class PImpl {\n"
jtulach@940
   525
            + "  }\n"
jtulach@940
   526
            + "  @OnReceive(method=\"WebSocket\", data = PQ.class, headers=\"SomeHeader: {some}\", url=\"whereever\")\n"
jtulach@940
   527
            + "  static void obtained(XModel m, PQ p) { }\n"
jtulach@940
   528
            + "}\n";
jtulach@940
   529
jtulach@940
   530
        Compile c = Compile.create(html, code);
jtulach@940
   531
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@940
   532
        for (Diagnostic<? extends JavaFileObject> diagnostic : c.getErrors()) {
jtulach@940
   533
            String msg = diagnostic.getMessage(Locale.ENGLISH);
jtulach@940
   534
            if (msg.contains("WebSocket spec does not support headers")) {
jtulach@940
   535
                return;
jtulach@940
   536
            }
jtulach@940
   537
        }
jtulach@940
   538
        fail("Needs an error message about headers:\n" + c.getErrors());
jtulach@940
   539
jtulach@940
   540
    }
jtulach@940
   541
jtulach@948
   542
    @Test public void webSocketsWithoutDataIsError() throws Exception {
jtulach@948
   543
        String html = "<html><body>"
jtulach@948
   544
            + "</body></html>";
jtulach@948
   545
        String code = "package x.y.z;\n"
jtulach@948
   546
            + "import net.java.html.json.Model;\n"
jtulach@948
   547
            + "import net.java.html.json.Property;\n"
jtulach@948
   548
            + "import net.java.html.json.OnReceive;\n"
jtulach@948
   549
            + "@Model(className=\"XModel\", properties={\n"
jtulach@948
   550
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@948
   551
            + "})\n"
jtulach@948
   552
            + "class X {\n"
jtulach@948
   553
            + "  @Model(className=\"PQ\", properties={})\n"
jtulach@948
   554
            + "  class PImpl {\n"
jtulach@948
   555
            + "  }\n"
jtulach@948
   556
            + "  @OnReceive(method=\"WebSocket\", url=\"whereever\")\n"
jtulach@948
   557
            + "  static void obtained(XModel m, PQ p) { }\n"
jtulach@948
   558
            + "}\n";
jtulach@948
   559
jtulach@948
   560
        Compile c = Compile.create(html, code);
jtulach@948
   561
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@948
   562
        for (Diagnostic<? extends JavaFileObject> diagnostic : c.getErrors()) {
jtulach@948
   563
            String msg = diagnostic.getMessage(Locale.ENGLISH);
jtulach@948
   564
            if (msg.contains("eeds to specify a data()")) {
jtulach@948
   565
                return;
jtulach@948
   566
            }
jtulach@948
   567
        }
jtulach@948
   568
        fail("Needs data attribute :\n" + c.getErrors());
jtulach@948
   569
    }
jtulach@948
   570
jtulach@940
   571
    @Test public void noNewLinesInHeaderLines() throws Exception {
jtulach@940
   572
        String html = "<html><body>"
jtulach@940
   573
            + "</body></html>";
jtulach@940
   574
        String code = "package x.y.z;\n"
jtulach@940
   575
            + "import net.java.html.json.Model;\n"
jtulach@940
   576
            + "import net.java.html.json.Property;\n"
jtulach@940
   577
            + "import net.java.html.json.OnReceive;\n"
jtulach@940
   578
            + "@Model(className=\"XModel\", properties={\n"
jtulach@940
   579
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@940
   580
            + "})\n"
jtulach@940
   581
            + "class X {\n"
jtulach@940
   582
            + "  @Model(className=\"PQ\", properties={})\n"
jtulach@940
   583
            + "  class PImpl {\n"
jtulach@940
   584
            + "  }\n"
jtulach@940
   585
            + "  @OnReceive(headers=\"SomeHeader\\n: {some}\", url=\"whereever\")\n"
jtulach@940
   586
            + "  static void obtained(XModel m, PQ p) { }\n"
jtulach@940
   587
            + "}\n";
jtulach@940
   588
jtulach@940
   589
        Compile c = Compile.create(html, code);
jtulach@940
   590
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@940
   591
        for (Diagnostic<? extends JavaFileObject> diagnostic : c.getErrors()) {
jtulach@940
   592
            String msg = diagnostic.getMessage(Locale.ENGLISH);
jtulach@940
   593
            if (msg.contains("Header line cannot contain line separator")) {
jtulach@940
   594
                return;
jtulach@940
   595
            }
jtulach@940
   596
        }
jtulach@940
   597
        fail("Needs an error message about headers:\n" + c.getErrors());
jtulach@940
   598
jtulach@940
   599
    }
jtulach@940
   600
jtulach@940
   601
    @Test public void noReturnInHeaderLines() throws Exception {
jtulach@940
   602
        String html = "<html><body>"
jtulach@940
   603
            + "</body></html>";
jtulach@940
   604
        String code = "package x.y.z;\n"
jtulach@940
   605
            + "import net.java.html.json.Model;\n"
jtulach@940
   606
            + "import net.java.html.json.Property;\n"
jtulach@940
   607
            + "import net.java.html.json.OnReceive;\n"
jtulach@940
   608
            + "@Model(className=\"XModel\", properties={\n"
jtulach@940
   609
            + "  @Property(name=\"prop\", type=long.class)\n"
jtulach@940
   610
            + "})\n"
jtulach@940
   611
            + "class X {\n"
jtulach@940
   612
            + "  @Model(className=\"PQ\", properties={})\n"
jtulach@940
   613
            + "  class PImpl {\n"
jtulach@940
   614
            + "  }\n"
jtulach@940
   615
            + "  @OnReceive(headers=\"Some\\rHeader: {some}\", url=\"whereever\")\n"
jtulach@940
   616
            + "  static void obtained(XModel m, PQ p) { }\n"
jtulach@940
   617
            + "}\n";
jtulach@940
   618
jtulach@940
   619
        Compile c = Compile.create(html, code);
jtulach@940
   620
        assertFalse(c.getErrors().isEmpty(), "One error: " + c.getErrors());
jtulach@940
   621
        for (Diagnostic<? extends JavaFileObject> diagnostic : c.getErrors()) {
jtulach@940
   622
            String msg = diagnostic.getMessage(Locale.ENGLISH);
jtulach@940
   623
            if (msg.contains("Header line cannot contain line separator")) {
jtulach@940
   624
                return;
jtulach@940
   625
            }
jtulach@940
   626
        }
jtulach@940
   627
        fail("Needs an error message about headers:\n" + c.getErrors());
jtulach@940
   628
jtulach@940
   629
    }
jtulach@940
   630
jaroslav@245
   631
    @Test public void onErrorHasToExist() throws IOException {
jaroslav@245
   632
        Compile res = Compile.create("", "package x;\n"
jaroslav@245
   633
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jaroslav@245
   634
            + "  @net.java.html.json.Property(name=\"x\", type=String.class)\n"
jaroslav@245
   635
            + "})\n"
jaroslav@245
   636
            + "class UseOnReceive {\n"
jaroslav@245
   637
            + "  @net.java.html.json.OnReceive(url=\"http://nowhere.com\", onError=\"doesNotExist\")\n"
jaroslav@245
   638
            + "  static void onMessage(MyModel model, String value) {\n"
jaroslav@245
   639
            + "  }\n"
jaroslav@245
   640
            + "}\n"
jaroslav@245
   641
        );
jaroslav@245
   642
        res.assertErrors();
jaroslav@245
   643
        res.assertError("not find doesNotExist");
jaroslav@245
   644
    }
jtulach@940
   645
jtulach@647
   646
    @Test public void usingListIsOK() throws IOException {
jtulach@647
   647
        Compile res = Compile.create("", "package x;\n"
jtulach@647
   648
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jtulach@647
   649
            + "  @net.java.html.json.Property(name=\"x\", type=String.class)\n"
jtulach@647
   650
            + "})\n"
jtulach@647
   651
            + "class UseOnReceive {\n"
jtulach@647
   652
            + "  @net.java.html.json.OnReceive(url=\"http://nowhere.com\")\n"
jtulach@647
   653
            + "  static void onMessage(MyModel model, java.util.List<MyData> value) {\n"
jtulach@647
   654
            + "  }\n"
jtulach@647
   655
            + "\n"
jtulach@647
   656
            + "  @net.java.html.json.Model(className=\"MyData\", properties={\n"
jtulach@647
   657
            + "  })\n"
jtulach@647
   658
            + "  static class MyDataModel {\n"
jtulach@647
   659
            + "  }\n"
jtulach@647
   660
            + "}\n"
jtulach@647
   661
        );
jtulach@647
   662
        res.assertNoErrors();
jtulach@647
   663
    }
jaroslav@245
   664
jtulach@648
   665
    @Test public void functionAndPropertyCollide() throws IOException {
jtulach@648
   666
        Compile res = Compile.create("", "package x;\n"
jtulach@648
   667
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jtulach@648
   668
            + "  @net.java.html.json.Property(name=\"x\", type=String.class)\n"
jtulach@648
   669
            + "})\n"
jtulach@648
   670
            + "class Collision {\n"
jtulach@648
   671
            + "  @net.java.html.json.Function\n"
jtulach@648
   672
            + "  static void x(MyModel model, String value) {\n"
jtulach@648
   673
            + "  }\n"
jtulach@648
   674
            + "}\n"
jtulach@648
   675
        );
jtulach@648
   676
        res.assertErrors();
jtulach@648
   677
        res.assertError("cannot have the name");
jtulach@648
   678
    }
jtulach@648
   679
jtulach@648
   680
    @Test public void twoPropertiesCollide() throws IOException {
jtulach@648
   681
        Compile res = Compile.create("", "package x;\n"
jtulach@648
   682
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jtulach@648
   683
            + "  @net.java.html.json.Property(name=\"x\", type=String.class),\n"
jtulach@648
   684
            + "  @net.java.html.json.Property(name=\"x\", type=int.class)\n"
jtulach@648
   685
            + "})\n"
jtulach@648
   686
            + "class Collision {\n"
jtulach@648
   687
            + "}\n"
jtulach@648
   688
        );
jtulach@648
   689
        res.assertErrors();
jtulach@648
   690
        res.assertError("Cannot have the name");
jtulach@648
   691
    }
jtulach@648
   692
jtulach@648
   693
    @Test public void propertyAndComputedOneCollide() throws IOException {
jtulach@648
   694
        Compile res = Compile.create("", "package x;\n"
jtulach@648
   695
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jtulach@648
   696
            + "  @net.java.html.json.Property(name=\"x\", type=String.class),\n"
jtulach@648
   697
            + "})\n"
jtulach@648
   698
            + "class Collision {\n"
jtulach@648
   699
            + "  @net.java.html.json.ComputedProperty static int x(String x) {\n"
jtulach@648
   700
            + "    return x.length();\n"
jtulach@648
   701
            + "  }\n"
jtulach@648
   702
            + "}\n"
jtulach@648
   703
        );
jtulach@648
   704
        res.assertErrors();
jtulach@648
   705
        res.assertError("Cannot have the name");
jtulach@648
   706
    }
jtulach@940
   707
jtulach@650
   708
    @Test public void onWebSocketJustTwoArgs() throws IOException {
jtulach@650
   709
        Compile res = Compile.create("", "package x;\n"
jtulach@650
   710
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jtulach@650
   711
            + "  @net.java.html.json.Property(name=\"x\", type=String.class)\n"
jtulach@650
   712
            + "})\n"
jtulach@650
   713
            + "class UseOnReceive {\n"
jtulach@948
   714
            + "  @net.java.html.json.OnReceive(url=\"http://nowhere.com\", method=\"WebSocket\", data=String.class)\n"
jtulach@650
   715
            + "  static void onMessage(MyModel model, String value, int arg) {\n"
jtulach@650
   716
            + "  }\n"
jtulach@650
   717
            + "}\n"
jtulach@650
   718
        );
jtulach@650
   719
        res.assertErrors();
jtulach@650
   720
        res.assertError("only have two arg");
jtulach@650
   721
    }
jtulach@940
   722
jaroslav@245
   723
    @Test public void onErrorWouldHaveToBeStatic() throws IOException {
jaroslav@245
   724
        Compile res = Compile.create("", "package x;\n"
jaroslav@245
   725
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jaroslav@245
   726
            + "  @net.java.html.json.Property(name=\"x\", type=String.class)\n"
jaroslav@245
   727
            + "})\n"
jaroslav@245
   728
            + "class UseOnReceive {\n"
jaroslav@245
   729
            + "  @net.java.html.json.OnReceive(url=\"http://nowhere.com\", onError=\"notStatic\")\n"
jaroslav@245
   730
            + "  static void onMessage(MyModel model, String value) {\n"
jaroslav@245
   731
            + "  }\n"
jaroslav@245
   732
            + "  void notStatic(Exception e) {}\n"
jaroslav@245
   733
            + "}\n"
jaroslav@245
   734
        );
jaroslav@245
   735
        res.assertErrors();
jaroslav@245
   736
        res.assertError("have to be static");
jaroslav@245
   737
    }
jaroslav@245
   738
jaroslav@245
   739
    @Test public void onErrorMustAcceptExceptionArgument() throws IOException {
jaroslav@245
   740
        Compile res = Compile.create("", "package x;\n"
jaroslav@245
   741
            + "@net.java.html.json.Model(className=\"MyModel\", properties= {\n"
jaroslav@245
   742
            + "  @net.java.html.json.Property(name=\"x\", type=String.class)\n"
jaroslav@245
   743
            + "})\n"
jaroslav@245
   744
            + "class UseOnReceive {\n"
jaroslav@245
   745
            + "  @net.java.html.json.OnReceive(url=\"http://nowhere.com\", onError=\"subclass\")\n"
jaroslav@245
   746
            + "  static void onMessage(MyModel model, String value) {\n"
jaroslav@245
   747
            + "  }\n"
jaroslav@245
   748
            + "  static void subclass(java.io.IOException e) {}\n"
jaroslav@245
   749
            + "}\n"
jaroslav@245
   750
        );
jaroslav@245
   751
        res.assertErrors();
jaroslav@245
   752
        res.assertError("Error method first argument needs to be MyModel and second Exception");
jaroslav@245
   753
    }
jtulach@3
   754
}